fix(web): preserve exact module imports and capture coverage (#9940)

This commit is contained in:
morluto authored and GitHub committed 2026-11-11 02:22:30 -05:00
1 parent 19f7eef513
commit a2aea3f4c6
4 files changed
+60 -7

No files matched your search

+26
View File
@@ -2123,6 +2123,32 @@ it("keeps known capture omissions in compact route summaries and queryable gap f
expect(row).toMatchObject({ source_id: null, provenance: null });
});
it.each(
(["scripts", "script_sources"] as const).flatMap((section) =>
[0, 1, null].map((count) => ({ section, count })),
),
)(
"preserves actual capture omission coverage for $section count $count",
({ section, count }) => {
const captured = inspection("export {};");
captured.completeness.excluded.push({
section,
reason: "resource_budget_exhausted",
count,
});
const result = analyzeWebBundleFixture(captured);
expect(result.completeness.status).toBe(
count === 0 ? "complete" : "partial",
);
expect(result.unknowns).toHaveLength(count === 0 ? 0 : 1);
expect(
result.route_inventory?.unknowns.filter(
({ kind }) => kind === "capture-omission",
),
).toHaveLength(count === 0 ? 0 : 1);
},
);
it("retains captured Next script identity while deriving decoded route patterns", () => {
const url = `${origin}/base/_next/static/chunks/app/%28shop%29/blog/%5Bid%5D/page-abc.js`;
const captured = createWebPageInspection([
+2 -1
View File
@@ -385,7 +385,8 @@ const captureBudgetOmission = (
const exclusions = inspection.completeness.excluded.filter(
(exclusion) =>
exclusion.section === section &&
exclusion.reason === "resource_budget_exhausted",
exclusion.reason === "resource_budget_exhausted" &&
exclusion.count !== 0,
);
if (exclusions.length === 0) return undefined;
if (exclusions.some(({ count }) => count === null)) return null;
+28
View File
@@ -63,6 +63,34 @@ describe("native module syntax observations", () => {
column: 7,
});
});
it.each([
['"./dep.js" as const', "./dep.js"],
['"./dep.js" satisfies string', "./dep.js"],
['"./dep.js"!', "./dep.js"],
["`./dep.js` as const", "./dep.js"],
["`./${name}.js` as const", null],
] as const)(
"retains exact import identity through erased syntax: %s",
(expression, specifier) => {
const source = `import(${expression});`;
const result = collectWebModuleImports(source, "main.ts");
expect(result.state).toBe("parsed");
expect(result.diagnostics).toEqual([]);
expect(result.imports).toEqual([
{
kind: "dynamic-import",
specifier,
expression,
start: { offset: 7, line: 1, column: 7 },
end: {
offset: 7 + expression.length,
line: 1,
column: 7 + expression.length,
},
},
]);
},
);
it("reports unparseable input without asserting an empty complete graph", () => {
const result = collectWebModuleImports(
'import "./ok.js"; function {',
+4 -6
View File
@@ -1,5 +1,5 @@
import { isStringLiteral, isTemplateLiteral } from "@babel/types";
import type { Node } from "@babel/types";
import { readExactJavaScriptLiteral } from "./javascript/javascriptAstValues.js";
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
import { parseJavaScriptSource } from "./javascript/javascriptSourceParser.js";
import type { WebModuleImport } from "./webModuleTrace.js";
@@ -36,11 +36,9 @@ export const collectWebModuleImports = (
expression.loc === undefined
)
return;
const specifier = isStringLiteral(expression)
? expression.value
: isTemplateLiteral(expression) && expression.expressions.length === 0
? (expression.quasis[0]?.value.cooked ?? null)
: null;
const literal = readExactJavaScriptLiteral(expression);
const specifier =
literal.found && typeof literal.value === "string" ? literal.value : null;
imports.push({
kind,
specifier,