mirror of
https://github.com/morluto/rea
synced 2026-10-27 14:42:18 -04:00
06739aeaf2
* fix(javascript): ignore erased TypeScript names in native-addon requests Skip import type / export type declarations and per-binding type specifiers when collecting .node addon members so only runtime value imports request native exports (fixes #2667). Co-authored-by: Cursor <cursoragent@cursor.com> * test(javascript): cover erased TypeScript re-export forms * test(javascript): allow Inspector observation events to arrive * test(inspector): emit events before enable responses --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
|
|
|
|
describe("native addon type-only TypeScript imports", () => {
|
|
it("ignores declaration-wide import type and export type from .node modules", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
import type { NativeThing } from "./addon.node";
|
|
export type { Extra } from "./addon.node";
|
|
`);
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.native_addon_bindings).toEqual([]);
|
|
});
|
|
|
|
it("keeps only value members from mixed type/value native imports", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
import { type OtherThing, load } from "./addon.node";
|
|
load();
|
|
`);
|
|
expect(analysis.electron.native_addon_bindings).toEqual([
|
|
expect.objectContaining({
|
|
specifier: "./addon.node",
|
|
binding_kind: "import",
|
|
members: ["load"],
|
|
}),
|
|
]);
|
|
});
|
|
|
|
it("retains ordinary value imports of native addons", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
import { load } from "./addon.node";
|
|
load();
|
|
`);
|
|
expect(analysis.electron.native_addon_bindings).toEqual([
|
|
expect.objectContaining({
|
|
specifier: "./addon.node",
|
|
binding_kind: "import",
|
|
members: ["load"],
|
|
}),
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("native addon type-only re-exports", () => {
|
|
it.each([
|
|
['export { type Extra, load } from "./addon.node";', ["load"]],
|
|
['export { type Extra } from "./addon.node";', []],
|
|
['export type * from "./addon.node";', []],
|
|
] as const)("retains only runtime members from %s", (source, members) => {
|
|
const analysis = analyzeJavaScriptStaticSource(source);
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.native_addon_bindings).toEqual(
|
|
members.length === 0
|
|
? []
|
|
: [
|
|
expect.objectContaining({
|
|
specifier: "./addon.node",
|
|
binding_kind: "re-export",
|
|
members: [...members],
|
|
}),
|
|
],
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("native addon loader provenance", () => {
|
|
it("distinguishes CommonJS and ESM re-exports", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const required = require("./addon.node#literal.node");
|
|
module.exports = require("./addon.node#literal.node");
|
|
import imported from "./addon.node#literal.node";
|
|
export { default } from "./addon.node#literal.node";
|
|
`);
|
|
expect(analysis.electron.native_addon_bindings).toHaveLength(4);
|
|
expect(analysis.electron.native_addon_bindings).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
binding_kind: "require",
|
|
module_kind: "require",
|
|
}),
|
|
expect.objectContaining({
|
|
binding_kind: "import",
|
|
module_kind: "import",
|
|
}),
|
|
expect.objectContaining({
|
|
binding_kind: "re-export",
|
|
module_kind: "require",
|
|
}),
|
|
expect.objectContaining({
|
|
binding_kind: "re-export",
|
|
module_kind: "import",
|
|
}),
|
|
]),
|
|
);
|
|
});
|
|
|
|
it.each(["#", "?"])(
|
|
"classifies require filenames literally for %s",
|
|
(punctuation) => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const script = require("./addon.node${punctuation}helper.js");
|
|
import native from "./addon.node${punctuation}helper.js";
|
|
`);
|
|
expect(analysis.electron.native_addon_bindings).toEqual([
|
|
expect.objectContaining({
|
|
binding_kind: "import",
|
|
module_kind: "import",
|
|
}),
|
|
]);
|
|
},
|
|
);
|
|
});
|