mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
fix(javascript): ignore bare CommonJS exports rebinding
Assigning a new value to the exports alias does not replace module.exports. Stop inventing a default export link and definite return-shape changes for that assignment. Validation: 22 semantic structure source tests and 49 compiled CLI/MCP acceptance tests passed. The new regression checks Node require returns an empty export object for both versions and both adapters report missing defaults without definite changes.
This commit is contained in:
1 parent
c57e759ae6
commit
8b2f8514c5
2 files changed
+26
-1
No files matched your search
@@ -641,7 +641,7 @@ const commonJsExportName = (
|
||||
node: t.Node,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): string | undefined => {
|
||||
if (isUnshadowedGlobal(node, state, "exports")) return "default";
|
||||
// Rebinding the CommonJS `exports` alias does not replace `module.exports`.
|
||||
if (!t.isMemberExpression(node) && !t.isOptionalMemberExpression(node))
|
||||
return undefined;
|
||||
const key = semanticStaticPropertyKey(node.property, node.computed);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { mkdir, writeFile } from "node:fs/promises";
|
||||
import { createRequire } from "node:module";
|
||||
import { join, resolve } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
@@ -13,6 +14,7 @@ import { javaScriptExportShapeComparisonResultSchema } from "../../../src/domain
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
const execute = promisify(execFile);
|
||||
const requireFixture = createRequire(import.meta.url);
|
||||
const comparisonEnvelope = z.object({
|
||||
normalized_result: javaScriptExportShapeComparisonResultSchema,
|
||||
});
|
||||
@@ -111,6 +113,28 @@ describe("exported function binding resolution through the CLI", () => {
|
||||
expectUncertainComparison(cli);
|
||||
expect(await compareThroughMcp(fixture.input)).toEqual(cli);
|
||||
});
|
||||
|
||||
it("does not treat rebinding the CommonJS exports alias as a default export", async () => {
|
||||
const fixture = await analyzeVersions(
|
||||
(count) =>
|
||||
`exports = function parse() { return { kind: "result", count: ${String(count)} }; };`,
|
||||
"default",
|
||||
"app.cjs",
|
||||
);
|
||||
|
||||
// This is a test-owned fixture, so Node's actual CommonJS loader is the
|
||||
// oracle for what the application exports.
|
||||
expect(requireFixture(fixture.leftPath)).toEqual({});
|
||||
expect(requireFixture(fixture.rightPath)).toEqual({});
|
||||
|
||||
const cli = await compareThroughCli(fixture);
|
||||
expect(cli).toMatchObject({
|
||||
left: { status: "missing" },
|
||||
right: { status: "missing" },
|
||||
summary: { added: 0, removed: 0, changed: 0 },
|
||||
});
|
||||
expect(await compareThroughMcp(fixture.input)).toEqual(cli);
|
||||
});
|
||||
});
|
||||
|
||||
describe("stable exported function bindings through the CLI", () => {
|
||||
@@ -588,6 +612,7 @@ const compareThroughMcp = async (input: Record<string, unknown>) => {
|
||||
arguments: input,
|
||||
});
|
||||
expect(response.isError).not.toBe(true);
|
||||
await client.ping();
|
||||
return comparisonEnvelope.parse(response.structuredContent)
|
||||
.normalized_result;
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user