mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
fix(javascript): keep TypeScript substitution out of runtime paths
This commit is contained in:
@@ -231,6 +231,11 @@ unknown instead of silently treating them as absent or verified.
|
||||
Plain `.ts` artifact sources use TypeScript syntax without JSX, including
|
||||
angle-bracket type assertions. `.tsx` and `.jsx` retain JSX parsing.
|
||||
|
||||
Relative TypeScript imports can name their emitted `.js`, `.mjs`, or `.cjs`
|
||||
counterparts while resolving to inventoried source files. This substitution
|
||||
requires import or require semantics. Literal Electron preload, renderer, and
|
||||
utility-process runtime paths retain the runtime filename selected by the caller.
|
||||
|
||||
Selected bounded text is then parsed as inert data to recover:
|
||||
|
||||
- `package.json` metadata and declared main or renderer entrypoints;
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface ResolveArtifactPathInput {
|
||||
readonly context: ArtifactPathResolutionContext;
|
||||
readonly files: ReadonlyMap<string, JavaScriptArtifactFile>;
|
||||
readonly htmlBaseHref?: string | null;
|
||||
/** Import/require semantics; runtime resource paths omit this provenance. */
|
||||
readonly moduleKind?: "import" | "require";
|
||||
}
|
||||
|
||||
@@ -149,6 +150,7 @@ const resolvePath = (input: ResolveArtifactPathInput): CandidateResolution => {
|
||||
confined,
|
||||
new Set(),
|
||||
input.context === "module-specifier" &&
|
||||
input.moduleKind !== undefined &&
|
||||
(input.declaredPath.startsWith(".") || input.declaredPath.startsWith("/"))
|
||||
? typescriptEmittedSourceCandidates(input.sourcePath, confined)
|
||||
: [],
|
||||
|
||||
@@ -11,6 +11,78 @@ import {
|
||||
writeFixtureFiles,
|
||||
} from "../../support/javascriptApplicationFixture.js";
|
||||
|
||||
cliTest(
|
||||
"resolves emitted module imports without substituting Electron runtime paths",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-typescript-runtime-paths-");
|
||||
await writeFixtureFiles(root, {
|
||||
"package.json": JSON.stringify({ main: "main.ts" }),
|
||||
"main.ts": `import { BrowserWindow, utilityProcess } from "electron";
|
||||
import "./worker.js";
|
||||
import "./config.mjs";
|
||||
import "./legacy.cjs";
|
||||
import "./view.js";
|
||||
import "./runtime.js";
|
||||
const win = new BrowserWindow({webPreferences:{preload:"./worker.js"}});
|
||||
win.loadURL("./renderer.js");
|
||||
utilityProcess.fork("./worker.js");
|
||||
utilityProcess.fork("./runtime.js");
|
||||
throw new Error("source must stay inert");`,
|
||||
"worker.ts": "export const worker = 1;",
|
||||
"config.mts": "export const config = 1;",
|
||||
"legacy.cts": "export const legacy = 1;",
|
||||
"view.tsx": "export const view = <div />;",
|
||||
"renderer.ts": "export const renderer = 1;",
|
||||
"runtime.ts": "export const source = 1;",
|
||||
"runtime.js": "throw new Error('runtime must stay inert');",
|
||||
});
|
||||
const output = await cli.run({
|
||||
arguments: ["analyze-javascript-application", root, "--json"],
|
||||
});
|
||||
expect(output.exitCode, output.stderr).toBe(0);
|
||||
const result = javascriptApplicationAnalysisResultSchema.parse(
|
||||
parseEvidence(output.json).normalized_result,
|
||||
);
|
||||
const { graph } = result;
|
||||
const source = findSourceModule(graph, "main.ts");
|
||||
for (const [specifier, target] of [
|
||||
["./worker.js", "worker.ts"],
|
||||
["./config.mjs", "config.mts"],
|
||||
["./legacy.cjs", "legacy.cts"],
|
||||
["./view.js", "view.tsx"],
|
||||
["./runtime.js", "runtime.js"],
|
||||
] as const)
|
||||
expect(
|
||||
findGraphEdge(graph, source, findSourceModule(graph, target), "imports")
|
||||
?.properties,
|
||||
).toMatchObject({ specifier, resolved_path: target });
|
||||
expect(result.summary).toMatchObject({
|
||||
utility_processes: 2,
|
||||
resolved_utility_entrypoints: 1,
|
||||
});
|
||||
expect(
|
||||
graph.edges.find(
|
||||
(edge) =>
|
||||
edge.evidence.extractor.operation ===
|
||||
"associate-browser-window-preload",
|
||||
)?.properties,
|
||||
).toMatchObject({
|
||||
declared_path: "./worker.js",
|
||||
resolved_path: null,
|
||||
resolution_status: "not-found",
|
||||
});
|
||||
expect(
|
||||
graph.edges
|
||||
.filter(
|
||||
(edge) =>
|
||||
edge.properties.declared_path === "./worker.js" ||
|
||||
edge.properties.declared_path === "./renderer.js",
|
||||
)
|
||||
.some((edge) => edge.properties.resolved_path != null),
|
||||
).toBe(false);
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"returns literal self-import evidence while preserving sibling imports and self-re-exports",
|
||||
async ({ cli }) => {
|
||||
|
||||
Reference in New Issue
Block a user