@navita/extraction 3.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +157 -0
- package/_virtual/_rolldown/runtime.cjs +23 -0
- package/_virtual/_rolldown/runtime.mjs +8 -0
- package/ast.cjs +164 -0
- package/ast.mjs +159 -0
- package/extraction.cjs +23 -0
- package/extraction.mjs +25 -0
- package/index.cjs +3 -0
- package/index.d.ts +24 -0
- package/index.mjs +5 -0
- package/loadOxc.cjs +19 -0
- package/loadOxc.mjs +21 -0
- package/package.json +32 -0
- package/rewrite.cjs +185 -0
- package/rewrite.mjs +185 -0
- package/stripTypes.cjs +12 -0
- package/stripTypes.mjs +14 -0
- package/toAmd.cjs +190 -0
- package/toAmd.mjs +192 -0
package/toAmd.mjs
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { importedName, patternNames } from "./ast.mjs";
|
|
5
|
+
import { getParser } from "./loadOxc.mjs";
|
|
6
|
+
//#region src/toAmd.ts
|
|
7
|
+
/**
|
|
8
|
+
* Convert an ES module (already TypeScript-stripped) into a single AMD
|
|
9
|
+
* `define([...deps], function (require, exports, ...modules) { ... })` call
|
|
10
|
+
* expression — the shape `@navita/core`'s evaluator expects.
|
|
11
|
+
*/
|
|
12
|
+
function esmToAmd(code, { dropUnusedImports }) {
|
|
13
|
+
const { program } = getParser().parseSync("module.js", code, {
|
|
14
|
+
lang: "js",
|
|
15
|
+
sourceType: "module"
|
|
16
|
+
});
|
|
17
|
+
const body = program.body;
|
|
18
|
+
const sources = [];
|
|
19
|
+
const sourceIndex = /* @__PURE__ */ new Map();
|
|
20
|
+
const sideEffectSources = [];
|
|
21
|
+
const sourceInfoFor = (source) => {
|
|
22
|
+
let info = sourceIndex.get(source);
|
|
23
|
+
if (!info) {
|
|
24
|
+
info = {
|
|
25
|
+
source,
|
|
26
|
+
specs: [],
|
|
27
|
+
param: ""
|
|
28
|
+
};
|
|
29
|
+
sourceIndex.set(source, info);
|
|
30
|
+
sources.push(info);
|
|
31
|
+
}
|
|
32
|
+
return info;
|
|
33
|
+
};
|
|
34
|
+
for (const stmt of body) {
|
|
35
|
+
if (stmt.type !== "ImportDeclaration") continue;
|
|
36
|
+
const source = stmt.source.value;
|
|
37
|
+
const specifiers = stmt.specifiers || [];
|
|
38
|
+
if (specifiers.length === 0) {
|
|
39
|
+
sideEffectSources.push(source);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const info = sourceInfoFor(source);
|
|
43
|
+
for (const spec of specifiers) if (spec.type === "ImportDefaultSpecifier") info.specs.push({
|
|
44
|
+
kind: "default",
|
|
45
|
+
local: spec.local.name
|
|
46
|
+
});
|
|
47
|
+
else if (spec.type === "ImportNamespaceSpecifier") info.specs.push({
|
|
48
|
+
kind: "namespace",
|
|
49
|
+
local: spec.local.name
|
|
50
|
+
});
|
|
51
|
+
else info.specs.push({
|
|
52
|
+
kind: "named",
|
|
53
|
+
imported: importedName(spec),
|
|
54
|
+
local: spec.local.name
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
58
|
+
if (dropUnusedImports) for (const stmt of body) {
|
|
59
|
+
if (stmt.type === "ImportDeclaration") continue;
|
|
60
|
+
collectIdentifierNames(stmt, referenced);
|
|
61
|
+
}
|
|
62
|
+
const keptSources = [];
|
|
63
|
+
for (const info of sources) {
|
|
64
|
+
const specs = dropUnusedImports ? info.specs.filter((s) => referenced.has(s.local)) : info.specs;
|
|
65
|
+
if (specs.length === 0) continue;
|
|
66
|
+
info.specs = specs;
|
|
67
|
+
keptSources.push(info);
|
|
68
|
+
}
|
|
69
|
+
const keptSideEffects = dropUnusedImports ? [] : sideEffectSources;
|
|
70
|
+
keptSources.forEach((info, i) => {
|
|
71
|
+
info.param = `_navita_import_${i}`;
|
|
72
|
+
});
|
|
73
|
+
const sideEffectParams = keptSideEffects.map((_, i) => `_navita_side_${i}`);
|
|
74
|
+
const deps = [
|
|
75
|
+
"\"require\"",
|
|
76
|
+
"\"exports\"",
|
|
77
|
+
...keptSources.map((info) => JSON.stringify(info.source)),
|
|
78
|
+
...keptSideEffects.map((source) => JSON.stringify(source))
|
|
79
|
+
];
|
|
80
|
+
const params = [
|
|
81
|
+
"require",
|
|
82
|
+
"exports",
|
|
83
|
+
...keptSources.map((info) => info.param),
|
|
84
|
+
...sideEffectParams
|
|
85
|
+
];
|
|
86
|
+
const lines = [];
|
|
87
|
+
let reexportCounter = 0;
|
|
88
|
+
const nextReexportNs = () => `_navita_reexport_${reexportCounter++}`;
|
|
89
|
+
for (const info of keptSources) lines.push(...destructure(info));
|
|
90
|
+
for (const stmt of body) {
|
|
91
|
+
if (stmt.type === "ImportDeclaration") continue;
|
|
92
|
+
emitStatement(stmt, code, lines, nextReexportNs);
|
|
93
|
+
}
|
|
94
|
+
const bodyText = lines.join("\n");
|
|
95
|
+
return `define([${deps.join(", ")}], function (${params.join(", ")}) {\n${bodyText}\n})`;
|
|
96
|
+
}
|
|
97
|
+
function destructure(info) {
|
|
98
|
+
const lines = [];
|
|
99
|
+
const named = [];
|
|
100
|
+
for (const spec of info.specs) if (spec.kind === "named") named.push(spec.imported === spec.local ? spec.local : `${spec.imported}: ${spec.local}`);
|
|
101
|
+
else if (spec.kind === "namespace") lines.push(`const ${spec.local} = ${info.param};`);
|
|
102
|
+
else lines.push(`const ${spec.local} = ${info.param} && ${info.param}.__esModule ? ${info.param}.default : (${info.param}.default !== undefined ? ${info.param}.default : ${info.param});`);
|
|
103
|
+
if (named.length > 0) lines.push(`const { ${named.join(", ")} } = ${info.param};`);
|
|
104
|
+
return lines;
|
|
105
|
+
}
|
|
106
|
+
function emitStatement(stmt, code, lines, nextReexportNs) {
|
|
107
|
+
switch (stmt.type) {
|
|
108
|
+
case "ExportNamedDeclaration":
|
|
109
|
+
if (stmt.declaration) {
|
|
110
|
+
const decl = stmt.declaration;
|
|
111
|
+
lines.push(code.slice(decl.start, decl.end));
|
|
112
|
+
for (const name of declaredNames(decl)) lines.push(`exports.${name} = ${name};`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (stmt.source) {
|
|
116
|
+
const ns = nextReexportNs();
|
|
117
|
+
lines.push(`const ${ns} = require(${JSON.stringify(stmt.source.value)});`);
|
|
118
|
+
for (const spec of stmt.specifiers || []) lines.push(`exports.${spec.exported.name} = ${ns}.${spec.local.name};`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
for (const spec of stmt.specifiers || []) lines.push(`exports.${spec.exported.name} = ${spec.local.name};`);
|
|
122
|
+
return;
|
|
123
|
+
case "ExportDefaultDeclaration": {
|
|
124
|
+
const decl = stmt.declaration;
|
|
125
|
+
if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") if (decl.id) {
|
|
126
|
+
lines.push(code.slice(decl.start, decl.end));
|
|
127
|
+
lines.push(`exports.default = ${decl.id.name};`);
|
|
128
|
+
} else lines.push(`exports.default = ${code.slice(decl.start, decl.end)};`);
|
|
129
|
+
else lines.push(`exports.default = ${code.slice(decl.start, decl.end)};`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
case "ExportAllDeclaration": {
|
|
133
|
+
const ns = nextReexportNs();
|
|
134
|
+
lines.push(`const ${ns} = require(${JSON.stringify(stmt.source.value)});`);
|
|
135
|
+
if (stmt.exported) lines.push(`exports.${stmt.exported.name} = ${ns};`);
|
|
136
|
+
else lines.push(`for (const _k in ${ns}) { if (_k !== "default") exports[_k] = ${ns}[_k]; }`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
default: lines.push(code.slice(stmt.start, stmt.end));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function declaredNames(decl) {
|
|
143
|
+
if (decl.type === "VariableDeclaration") {
|
|
144
|
+
const names = [];
|
|
145
|
+
for (const d of decl.declarations) patternNames(d.id, names);
|
|
146
|
+
return names;
|
|
147
|
+
}
|
|
148
|
+
if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") return decl.id ? [decl.id.name] : [];
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
const SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
152
|
+
"type",
|
|
153
|
+
"start",
|
|
154
|
+
"end",
|
|
155
|
+
"range",
|
|
156
|
+
"loc",
|
|
157
|
+
"parent"
|
|
158
|
+
]);
|
|
159
|
+
/** Collect identifier names referenced in a subtree (skip static member/key). */
|
|
160
|
+
function collectIdentifierNames(node, out) {
|
|
161
|
+
if (!node || typeof node !== "object") return;
|
|
162
|
+
if (Array.isArray(node)) {
|
|
163
|
+
for (const child of node) collectIdentifierNames(child, out);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const n = node;
|
|
167
|
+
switch (n.type) {
|
|
168
|
+
case "Identifier":
|
|
169
|
+
case "IdentifierReference":
|
|
170
|
+
out.add(n.name);
|
|
171
|
+
return;
|
|
172
|
+
case "MemberExpression":
|
|
173
|
+
case "StaticMemberExpression":
|
|
174
|
+
case "ComputedMemberExpression":
|
|
175
|
+
if (n.computed) collectIdentifierNames(n.property, out);
|
|
176
|
+
collectIdentifierNames(n.object, out);
|
|
177
|
+
return;
|
|
178
|
+
case "Property":
|
|
179
|
+
case "ObjectProperty":
|
|
180
|
+
if (n.computed) collectIdentifierNames(n.key, out);
|
|
181
|
+
collectIdentifierNames(n.value, out);
|
|
182
|
+
return;
|
|
183
|
+
default: break;
|
|
184
|
+
}
|
|
185
|
+
for (const key in n) {
|
|
186
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
187
|
+
const value = n[key];
|
|
188
|
+
if (value && typeof value === "object") collectIdentifierNames(value, out);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
export { esmToAmd };
|