diff --git a/src/domain/referenceSourceImportParsing.ts b/src/domain/referenceSourceImportParsing.ts index f2c7f2692a..ac7d90c622 100644 --- a/src/domain/referenceSourceImportParsing.ts +++ b/src/domain/referenceSourceImportParsing.ts @@ -72,6 +72,16 @@ const safeModuleName = (node: Node | null | undefined): string | undefined => { return undefined; }; +const exactStringModuleName = ( + node: Node | null | undefined, +): string | undefined => { + if (node === null || node === undefined) return undefined; + const literal = readExactJavaScriptLiteral(node); + return literal.found && typeof literal.value === "string" + ? literal.value + : undefined; +}; + const resolveSpecifier = ( specifier: string, ): ReferenceSourceImportResolution => { @@ -248,7 +258,7 @@ const extractRequireAndDynamicImports = ( for (const call of expressions) { if (isImportExpression(call)) { - const specifier = safeModuleName(call.source); + const specifier = exactStringModuleName(call.source); appendRelationship(relationships, limitations, { fromPath: from_path, to: specifier ?? "", diff --git a/tests/boundary/filesystem/referenceSourceDynamicImports.test.ts b/tests/boundary/filesystem/referenceSourceDynamicImports.test.ts index b826e1dbae..4ed88bb911 100644 --- a/tests/boundary/filesystem/referenceSourceDynamicImports.test.ts +++ b/tests/boundary/filesystem/referenceSourceDynamicImports.test.ts @@ -15,6 +15,8 @@ it("resolves dynamic source imports while retaining computed targets as unknown" 'import "./static";', 'require("./common");', 'const lazy = import("./lazy");', + "const templated = import(`./template-lazy.mjs`);", + 'const wrapped = import("./wrapped-lazy.mjs" as const);', 'async function load() { return await import("./data.json", { with: { type: "json" } }); }', 'const name = "./not-guessed.js"; import(name);', "import(`./${name}.js`);", @@ -24,6 +26,9 @@ it("resolves dynamic source imports while retaining computed targets as unknown" ...["static.ts", "common.js", "lazy.ts"].map((path) => writeFile(join(root, path), "export {};\n"), ), + ...["template-lazy.mjs", "wrapped-lazy.mjs"].map((path) => + writeFile(join(root, path), "export {};\n"), + ), writeFile(join(root, "data.json"), '{"value":1}\n'), ]); @@ -34,11 +39,13 @@ it("resolves dynamic source imports while retaining computed targets as unknown" }); if (!result.ok) throw result.error; expect(result.value.parse_failures).toEqual([]); - expect(result.value.relationships).toHaveLength(6); + expect(result.value.relationships).toHaveLength(8); for (const [to, kind] of [ ["static.ts", "imports"], ["common.js", "requires"], ["lazy.ts", "imports"], + ["template-lazy.mjs", "imports"], + ["wrapped-lazy.mjs", "imports"], ["data.json", "imports"], ]) expect(result.value.relationships).toContainEqual({