fix(codegen): validate sourcemap options (#25860)

## Summary
- require a string sourceText when sourcemaps are enabled
- reject non-string supplied sourceFilename values before map generation
- cover invalid and valid source-map option combinations
This commit is contained in:
camc314 committed 2026-08-18 13:57:46 +00:00
1 parent 345f9818c5
commit 0fbcf6420b
3 files changed
+51 -2

No files matched your search

+9 -1
View File
@@ -70,7 +70,15 @@ export function printSync(node: ESTree.Node, options?: Options): CodegenResult {
options = EMPTY_OPTIONS;
} else {
if (options.ts === true) index = 1;
if (options.sourcemap === true) index |= 2;
if (options.sourcemap === true) {
if (typeof options.sourceText !== "string") {
throw new TypeError("`sourceText` must be a string when `sourcemap` is true");
}
if (options.sourceFilename !== undefined && typeof options.sourceFilename !== "string") {
throw new TypeError("`sourceFilename` must be a string when supplied");
}
index |= 2;
}
}
let print = printers[index];
+1 -1
View File
@@ -49,7 +49,7 @@ export interface Options {
sourcemap?: boolean;
/**
* Original source text. Required for source-map mappings.
* Original source text. Required when `sourcemap` is `true`.
*/
sourceText?: string;
+41
View File
@@ -201,6 +201,47 @@ describe("Rust conformance", () => {
});
});
describe("source map options", () => {
const code = "const value = 1;";
const program = parseProgram("options.js", code);
test.each([
["missing", undefined],
["null", null],
["number", 1],
])("rejects %s sourceText", (_name, sourceText) => {
expect(() =>
printSync(program, { sourcemap: true, sourceText: sourceText as unknown as string }),
).toThrowError(new TypeError("`sourceText` must be a string when `sourcemap` is true"));
});
test.each([
["null", null],
["number", 1],
])("rejects %s sourceFilename", (_name, sourceFilename) => {
expect(() =>
printSync(program, {
sourcemap: true,
sourceText: code,
sourceFilename: sourceFilename as unknown as string,
}),
).toThrowError(new TypeError("`sourceFilename` must be a string when supplied"));
});
test("accepts valid source map options", () => {
expect(
printSync(program, {
sourcemap: true,
sourceText: code,
sourceFilename: "options.js",
}).map,
).toMatchObject({
sources: ["options.js"],
sourcesContent: [code],
});
});
});
interface Fixture {
name: string;
/** Source text, or `null` if the fixture is a cached file which has not been downloaded */