feat(studio): recover matching Nitro sources and persist import phases
CI / check (push) Successful in 2m5s
CI / deploy (push) Successful in 1m8s
CI / publish-container (push) Successful in 1m4s

This commit is contained in:
Simo committed 2026-09-11 10:22:06 +02:00
1 parent 00e33623f7
commit 13bd3695cb
45 files changed
+903 -28

No files matched your search

+12 -6
View File
@@ -238,7 +238,10 @@ export function createNitroBundle(
// ── .nitro Bundle Parser ──────────────────────────────────────────
export function parseNitroBundle(buffer: Buffer): {
export function parseNitroBundle(
buffer: Buffer,
options?: { maxOutputLength?: number },
): {
json: Record<string, unknown>;
jsonFileName: string;
png: Buffer;
@@ -267,7 +270,7 @@ export function parseNitroBundle(buffer: Buffer): {
offset += 4;
const jsonCompressed = buffer.subarray(offset, offset + jsonCompressedLen);
offset += jsonCompressedLen;
const jsonStr = inflateJsonOrGzip(jsonCompressed).toString("utf-8");
const jsonStr = inflateJsonOrGzip(jsonCompressed, options).toString("utf-8");
const json = JSON.parse(jsonStr);
// File 2: PNG
@@ -279,7 +282,7 @@ export function parseNitroBundle(buffer: Buffer): {
offset += 4;
const pngCompressed = buffer.subarray(offset, offset + pngCompressedLen);
offset += pngCompressedLen;
const png = inflateJsonOrGzip(pngCompressed);
const png = inflateJsonOrGzip(pngCompressed, options);
return { json, jsonFileName, png, pngFileName };
}
@@ -289,10 +292,13 @@ export function parseNitroBundle(buffer: Buffer): {
* gzip their contents instead of raw-deflate. Try inflate first, then fall
* back to gunzip so both formats parse.
*/
function inflateJsonOrGzip(input: Buffer): Buffer {
function inflateJsonOrGzip(
input: Buffer,
options?: { maxOutputLength?: number },
): Buffer {
try {
return inflateSync(input);
return inflateSync(input, options);
} catch {
return gunzipSync(input);
return gunzipSync(input, options);
}
}
@@ -0,0 +1,12 @@
import { expect, it } from "vitest";
import { createNitroBundle, parseNitroBundle } from "./nitro-builder";
it("honors an explicit decompression limit for imported bundles", () => {
const bundle = createNitroBundle(
{ name: "chair", value: "a".repeat(4096) },
Buffer.from("png"),
"chair",
);
expect(() => parseNitroBundle(bundle, { maxOutputLength: 1024 })).toThrow();
expect(parseNitroBundle(bundle).json.name).toBe("chair");
});