@knighted/module 1.3.0 → 1.3.1
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/dist/ast.d.ts +1 -0
- package/dist/async.d.ts +4 -0
- package/dist/buildEsmPrelude.d.ts +14 -0
- package/dist/cjs/ast.d.cts +1 -0
- package/dist/cjs/async.d.cts +4 -0
- package/dist/cjs/buildEsmPrelude.d.cts +14 -0
- package/dist/cjs/exportBagToEsm.d.cts +13 -0
- package/dist/cjs/format.cjs +78 -852
- package/dist/cjs/formatVisitor.d.cts +42 -0
- package/dist/cjs/helpers/async.cjs +57 -0
- package/dist/cjs/idiomaticPlan.d.cts +28 -0
- package/dist/cjs/interopHelpers.d.cts +5 -0
- package/dist/cjs/lowerCjsRequireToImports.d.cts +17 -0
- package/dist/cjs/lowerEsmToCjs.d.cts +22 -0
- package/dist/cjs/pipeline/buildEsmPrelude.cjs +65 -0
- package/dist/cjs/pipeline/exportBagToEsm.cjs +81 -0
- package/dist/cjs/pipeline/formatVisitor.cjs +171 -0
- package/dist/cjs/pipeline/idiomaticPlan.cjs +224 -0
- package/dist/cjs/pipeline/interopHelpers.cjs +10 -0
- package/dist/cjs/pipeline/lowerCjsRequireToImports.cjs +110 -0
- package/dist/cjs/pipeline/lowerEsmToCjs.cjs +204 -0
- package/dist/exportBagToEsm.d.ts +13 -0
- package/dist/format.js +74 -848
- package/dist/formatVisitor.d.ts +42 -0
- package/dist/helpers/ast.d.ts +1 -0
- package/dist/helpers/async.d.ts +4 -0
- package/dist/helpers/async.js +50 -0
- package/dist/idiomaticPlan.d.ts +28 -0
- package/dist/interopHelpers.d.ts +5 -0
- package/dist/lowerCjsRequireToImports.d.ts +17 -0
- package/dist/lowerEsmToCjs.d.ts +22 -0
- package/dist/pipeline/buildEsmPrelude.d.ts +14 -0
- package/dist/pipeline/buildEsmPrelude.js +59 -0
- package/dist/pipeline/exportBagToEsm.d.ts +13 -0
- package/dist/pipeline/exportBagToEsm.js +75 -0
- package/dist/pipeline/formatVisitor.d.ts +42 -0
- package/dist/pipeline/formatVisitor.js +166 -0
- package/dist/pipeline/idiomaticPlan.d.ts +28 -0
- package/dist/pipeline/idiomaticPlan.js +218 -0
- package/dist/pipeline/interopHelpers.d.ts +5 -0
- package/dist/pipeline/interopHelpers.js +5 -0
- package/dist/pipeline/lowerCjsRequireToImports.d.ts +17 -0
- package/dist/pipeline/lowerCjsRequireToImports.js +102 -0
- package/dist/pipeline/lowerEsmToCjs.d.ts +22 -0
- package/dist/pipeline/lowerEsmToCjs.js +197 -0
- package/package.json +1 -1
package/dist/cjs/format.cjs
CHANGED
|
@@ -4,407 +4,27 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.format = void 0;
|
|
7
|
-
var _ast = require("./helpers/ast.cjs");
|
|
8
7
|
var _magicString = _interopRequireDefault(require("magic-string"));
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var _memberExpression = require("./formatters/memberExpression.cjs");
|
|
8
|
+
var _async = require("./helpers/async.cjs");
|
|
9
|
+
var _identifier = require("./helpers/identifier.cjs");
|
|
12
10
|
var _assignmentExpression = require("./formatters/assignmentExpression.cjs");
|
|
13
|
-
var
|
|
11
|
+
var _identifier2 = require("./formatters/identifier.cjs");
|
|
12
|
+
var _memberExpression = require("./formatters/memberExpression.cjs");
|
|
13
|
+
var _metaProperty = require("./formatters/metaProperty.cjs");
|
|
14
|
+
var _idiomaticPlan = require("./pipeline/idiomaticPlan.cjs");
|
|
15
|
+
var _buildEsmPrelude = require("./pipeline/buildEsmPrelude.cjs");
|
|
16
|
+
var _exportBagToEsm = require("./pipeline/exportBagToEsm.cjs");
|
|
17
|
+
var _lowerCjsRequireToImports = require("./pipeline/lowerCjsRequireToImports.cjs");
|
|
18
|
+
var _lowerEsmToCjs = require("./pipeline/lowerEsmToCjs.cjs");
|
|
19
|
+
var _formatVisitor = require("./pipeline/formatVisitor.cjs");
|
|
20
|
+
var _interopHelpers = require("./pipeline/interopHelpers.cjs");
|
|
14
21
|
var _exports = require("./utils/exports.cjs");
|
|
15
22
|
var _identifiers = require("./utils/identifiers.cjs");
|
|
16
|
-
var
|
|
23
|
+
var _url = require("./utils/url.cjs");
|
|
17
24
|
var _walk = require("./walk.cjs");
|
|
18
25
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
|
-
const isValidIdent = name => /^[$A-Z_a-z][$\w]*$/.test(name);
|
|
20
|
-
const expressionHasRequireCall = (node, shadowed) => {
|
|
21
|
-
let found = false;
|
|
22
|
-
const walkNode = n => {
|
|
23
|
-
if (!(0, _ast.isAstNode)(n) || found) return;
|
|
24
|
-
if ((0, _ast.isCallExpressionNode)(n) && (0, _ast.isIdentifierNode)(n.callee) && n.callee.name === 'require' && !shadowed.has('require')) {
|
|
25
|
-
found = true;
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if ((0, _ast.isCallExpressionNode)(n) && (0, _ast.isMemberExpressionNode)(n.callee) && (0, _ast.isIdentifierNode)(n.callee.object) && n.callee.object.name === 'require' && !shadowed.has('require')) {
|
|
29
|
-
found = true;
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const record = n;
|
|
33
|
-
const keys = Object.keys(record);
|
|
34
|
-
for (const key of keys) {
|
|
35
|
-
const value = record[key];
|
|
36
|
-
if (!value) continue;
|
|
37
|
-
if (Array.isArray(value)) {
|
|
38
|
-
for (const item of value) {
|
|
39
|
-
if (item && typeof item === 'object') walkNode(item);
|
|
40
|
-
if (found) return;
|
|
41
|
-
}
|
|
42
|
-
} else if (value && typeof value === 'object') {
|
|
43
|
-
walkNode(value);
|
|
44
|
-
if (found) return;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
walkNode(node);
|
|
49
|
-
return found;
|
|
50
|
-
};
|
|
51
|
-
const exportAssignment = (name, expr, live) => {
|
|
52
|
-
const prop = isValidIdent(name) ? `.${name}` : `[${JSON.stringify(name)}]`;
|
|
53
|
-
if (live === 'strict') {
|
|
54
|
-
const key = JSON.stringify(name);
|
|
55
|
-
return `Object.defineProperty(exports, ${key}, { enumerable: true, get: () => ${expr} });`;
|
|
56
|
-
}
|
|
57
|
-
return `exports${prop} = ${expr};`;
|
|
58
|
-
};
|
|
59
|
-
const defaultInteropName = '__interopDefault';
|
|
60
|
-
const interopHelper = `const ${defaultInteropName} = mod => (mod && mod.__esModule ? mod.default : mod);\n`;
|
|
61
|
-
const requireInteropName = '__requireDefault';
|
|
62
|
-
const requireInteropHelper = `const ${requireInteropName} = mod => (mod && typeof mod === 'object' && 'default' in mod ? mod.default : mod);\n`;
|
|
63
|
-
const isRequireCallee = (callee, shadowed) => {
|
|
64
|
-
if (callee.type === 'Identifier' && callee.name === 'require' && !shadowed.has('require')) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.object.name === 'module' && !shadowed.has('module') && callee.property.type === 'Identifier' && callee.property.name === 'require') {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
return false;
|
|
71
|
-
};
|
|
72
|
-
const isStaticRequire = (node, shadowed) => node.type === 'CallExpression' && isRequireCallee(node.callee, shadowed) && node.arguments.length === 1 && node.arguments[0].type === 'Literal' && typeof node.arguments[0].value === 'string';
|
|
73
|
-
const isRequireCall = (node, shadowed) => node.type === 'CallExpression' && isRequireCallee(node.callee, shadowed);
|
|
74
|
-
const lowerCjsRequireToImports = (program, code, shadowed) => {
|
|
75
|
-
const transforms = [];
|
|
76
|
-
const imports = [];
|
|
77
|
-
const hoisted = [];
|
|
78
|
-
let nsIndex = 0;
|
|
79
|
-
let needsCreateRequire = false;
|
|
80
|
-
let needsInteropHelper = false;
|
|
81
|
-
const isJsonSpecifier = value => {
|
|
82
|
-
const base = value.split(/[?#]/)[0] ?? value;
|
|
83
|
-
return base.endsWith('.json');
|
|
84
|
-
};
|
|
85
|
-
for (const stmt of program.body) {
|
|
86
|
-
if (stmt.type === 'VariableDeclaration') {
|
|
87
|
-
const decls = stmt.declarations;
|
|
88
|
-
const allStatic = decls.length > 0 && decls.every(decl => decl.init && isStaticRequire(decl.init, shadowed));
|
|
89
|
-
if (allStatic) {
|
|
90
|
-
for (const decl of decls) {
|
|
91
|
-
const init = decl.init;
|
|
92
|
-
if (!init || !(0, _ast.isCallExpressionNode)(init)) {
|
|
93
|
-
needsCreateRequire = true;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
const arg = init.arguments[0];
|
|
97
|
-
const source = code.slice(arg.start, arg.end);
|
|
98
|
-
const value = arg.value;
|
|
99
|
-
const isJson = typeof value === 'string' && isJsonSpecifier(value);
|
|
100
|
-
const ns = `__cjsImport${nsIndex++}`;
|
|
101
|
-
const jsonImport = isJson ? `${source} with { type: "json" }` : source;
|
|
102
|
-
if (decl.id.type === 'Identifier') {
|
|
103
|
-
imports.push(isJson ? `import ${ns} from ${jsonImport};\n` : `import * as ${ns} from ${jsonImport};\n`);
|
|
104
|
-
hoisted.push(isJson ? `const ${decl.id.name} = ${ns};\n` : `const ${decl.id.name} = ${requireInteropName}(${ns});\n`);
|
|
105
|
-
needsInteropHelper ||= !isJson;
|
|
106
|
-
} else if (decl.id.type === 'ObjectPattern' || decl.id.type === 'ArrayPattern') {
|
|
107
|
-
const pattern = code.slice(decl.id.start, decl.id.end);
|
|
108
|
-
imports.push(isJson ? `import ${ns} from ${jsonImport};\n` : `import * as ${ns} from ${jsonImport};\n`);
|
|
109
|
-
hoisted.push(isJson ? `const ${pattern} = ${ns};\n` : `const ${pattern} = ${requireInteropName}(${ns});\n`);
|
|
110
|
-
needsInteropHelper ||= !isJson;
|
|
111
|
-
} else {
|
|
112
|
-
needsCreateRequire = true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
transforms.push({
|
|
116
|
-
start: stmt.start,
|
|
117
|
-
end: stmt.end,
|
|
118
|
-
code: ';\n'
|
|
119
|
-
});
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
for (const decl of decls) {
|
|
123
|
-
const init = decl.init;
|
|
124
|
-
if (init && isRequireCall(init, shadowed)) {
|
|
125
|
-
needsCreateRequire = true;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (stmt.type === 'ExpressionStatement') {
|
|
130
|
-
const expr = stmt.expression;
|
|
131
|
-
if (expr && isStaticRequire(expr, shadowed)) {
|
|
132
|
-
if (!(0, _ast.isCallExpressionNode)(expr)) {
|
|
133
|
-
needsCreateRequire = true;
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
const arg = expr.arguments[0];
|
|
137
|
-
const source = code.slice(arg.start, arg.end);
|
|
138
|
-
const value = arg.value;
|
|
139
|
-
const isJson = typeof value === 'string' && isJsonSpecifier(value);
|
|
140
|
-
const jsonImport = isJson ? `${source} with { type: "json" }` : source;
|
|
141
|
-
imports.push(`import ${jsonImport};\n`);
|
|
142
|
-
transforms.push({
|
|
143
|
-
start: stmt.start,
|
|
144
|
-
end: stmt.end,
|
|
145
|
-
code: ';\n'
|
|
146
|
-
});
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
if (expr && isRequireCall(expr, shadowed)) {
|
|
150
|
-
needsCreateRequire = true;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
transforms,
|
|
156
|
-
imports,
|
|
157
|
-
hoisted,
|
|
158
|
-
needsCreateRequire,
|
|
159
|
-
needsInteropHelper
|
|
160
|
-
};
|
|
161
|
-
};
|
|
162
26
|
const isRequireMainMember = (node, shadowed) => node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'require' && !shadowed.has('require') && node.property.type === 'Identifier' && node.property.name === 'main';
|
|
163
|
-
const hasTopLevelAwait = program => {
|
|
164
|
-
let found = false;
|
|
165
|
-
const walkNode = (node, inFunction) => {
|
|
166
|
-
if (found) return;
|
|
167
|
-
if (!(0, _ast.isAstNode)(node)) return;
|
|
168
|
-
switch (node.type) {
|
|
169
|
-
case 'FunctionDeclaration':
|
|
170
|
-
case 'FunctionExpression':
|
|
171
|
-
case 'ArrowFunctionExpression':
|
|
172
|
-
case 'ClassDeclaration':
|
|
173
|
-
case 'ClassExpression':
|
|
174
|
-
inFunction = true;
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
if (!inFunction && node.type === 'AwaitExpression') {
|
|
178
|
-
found = true;
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
const record = node;
|
|
182
|
-
const keys = Object.keys(record);
|
|
183
|
-
for (const key of keys) {
|
|
184
|
-
const value = record[key];
|
|
185
|
-
if (!value) continue;
|
|
186
|
-
if (Array.isArray(value)) {
|
|
187
|
-
for (const item of value) {
|
|
188
|
-
if (item && typeof item === 'object') {
|
|
189
|
-
walkNode(item, inFunction);
|
|
190
|
-
if (found) return;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
} else if (value && typeof value === 'object') {
|
|
194
|
-
walkNode(value, inFunction);
|
|
195
|
-
if (found) return;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
walkNode(program, false);
|
|
200
|
-
return found;
|
|
201
|
-
};
|
|
202
|
-
const isAsyncContext = ancestors => {
|
|
203
|
-
for (let i = ancestors.length - 1; i >= 0; i -= 1) {
|
|
204
|
-
const node = ancestors[i];
|
|
205
|
-
if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
206
|
-
return !!node.async;
|
|
207
|
-
}
|
|
208
|
-
if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
27
|
|
|
213
|
-
// Program scope (top-level) supports await in ESM.
|
|
214
|
-
return true;
|
|
215
|
-
};
|
|
216
|
-
const lowerEsmToCjs = (program, code, opts, containsTopLevelAwait) => {
|
|
217
|
-
const live = opts.liveBindings ?? 'strict';
|
|
218
|
-
const importTransforms = [];
|
|
219
|
-
const exportTransforms = [];
|
|
220
|
-
let needsInterop = false;
|
|
221
|
-
let importIndex = 0;
|
|
222
|
-
for (const node of program.body) {
|
|
223
|
-
if (node.type === 'ImportDeclaration') {
|
|
224
|
-
const srcLiteral = code.slice(node.source.start, node.source.end);
|
|
225
|
-
const specifiers = node.specifiers ?? [];
|
|
226
|
-
const defaultSpec = specifiers.find(s => s.type === 'ImportDefaultSpecifier');
|
|
227
|
-
const namespaceSpec = specifiers.find(s => s.type === 'ImportNamespaceSpecifier');
|
|
228
|
-
const namedSpecs = specifiers.filter(s => s.type === 'ImportSpecifier');
|
|
229
|
-
|
|
230
|
-
// Side-effect import
|
|
231
|
-
if (!specifiers.length) {
|
|
232
|
-
importTransforms.push({
|
|
233
|
-
start: node.start,
|
|
234
|
-
end: node.end,
|
|
235
|
-
code: `require(${srcLiteral});\n`,
|
|
236
|
-
needsInterop: false
|
|
237
|
-
});
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
const modIdent = `__mod${importIndex++}`;
|
|
241
|
-
const lines = [];
|
|
242
|
-
lines.push(`const ${modIdent} = require(${srcLiteral});`);
|
|
243
|
-
if (namespaceSpec) {
|
|
244
|
-
lines.push(`const ${namespaceSpec.local.name} = ${modIdent};`);
|
|
245
|
-
}
|
|
246
|
-
if (defaultSpec) {
|
|
247
|
-
let init = modIdent;
|
|
248
|
-
switch (opts.cjsDefault) {
|
|
249
|
-
case 'module-exports':
|
|
250
|
-
init = modIdent;
|
|
251
|
-
break;
|
|
252
|
-
case 'none':
|
|
253
|
-
init = `${modIdent}.default`;
|
|
254
|
-
break;
|
|
255
|
-
case 'auto':
|
|
256
|
-
default:
|
|
257
|
-
init = `${defaultInteropName}(${modIdent})`;
|
|
258
|
-
needsInterop = true;
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
|
-
lines.push(`const ${defaultSpec.local.name} = ${init};`);
|
|
262
|
-
}
|
|
263
|
-
if (namedSpecs.length) {
|
|
264
|
-
const pairs = namedSpecs.map(s => {
|
|
265
|
-
const imported = (0, _ast.getModuleExportName)(s.imported);
|
|
266
|
-
if (!imported) return s.local.name;
|
|
267
|
-
const local = s.local.name;
|
|
268
|
-
return imported === local ? imported : `${imported}: ${local}`;
|
|
269
|
-
});
|
|
270
|
-
lines.push(`const { ${pairs.join(', ')} } = ${modIdent};`);
|
|
271
|
-
}
|
|
272
|
-
importTransforms.push({
|
|
273
|
-
start: node.start,
|
|
274
|
-
end: node.end,
|
|
275
|
-
code: `${lines.join('\n')}\n`,
|
|
276
|
-
needsInterop
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
if (node.type === 'ExportNamedDeclaration') {
|
|
280
|
-
// Handle declaration exports
|
|
281
|
-
if (node.declaration) {
|
|
282
|
-
const decl = node.declaration;
|
|
283
|
-
const declSrc = code.slice(decl.start, decl.end);
|
|
284
|
-
const exportedNames = [];
|
|
285
|
-
if (decl.type === 'VariableDeclaration') {
|
|
286
|
-
for (const d of decl.declarations) {
|
|
287
|
-
if (d.id.type === 'Identifier') {
|
|
288
|
-
exportedNames.push(d.id.name);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
} else if ('id' in decl && decl.id?.type === 'Identifier') {
|
|
292
|
-
exportedNames.push(decl.id.name);
|
|
293
|
-
}
|
|
294
|
-
const exportLines = exportedNames.map(name => exportAssignment(name, name, live));
|
|
295
|
-
exportTransforms.push({
|
|
296
|
-
start: node.start,
|
|
297
|
-
end: node.end,
|
|
298
|
-
code: `${declSrc}\n${exportLines.join('\n')}\n`
|
|
299
|
-
});
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Handle re-export or local specifiers
|
|
304
|
-
if (node.specifiers?.length) {
|
|
305
|
-
if (node.source) {
|
|
306
|
-
const srcLiteral = code.slice(node.source.start, node.source.end);
|
|
307
|
-
const modIdent = `__mod${importIndex++}`;
|
|
308
|
-
const lines = [`const ${modIdent} = require(${srcLiteral});`];
|
|
309
|
-
for (const spec of node.specifiers) {
|
|
310
|
-
if (spec.type !== 'ExportSpecifier') continue;
|
|
311
|
-
const exported = (0, _ast.getModuleExportName)(spec.exported);
|
|
312
|
-
const imported = (0, _ast.getModuleExportName)(spec.local);
|
|
313
|
-
if (!exported || !imported) continue;
|
|
314
|
-
let rhs = `${modIdent}.${imported}`;
|
|
315
|
-
if (imported === 'default') {
|
|
316
|
-
rhs = `${defaultInteropName}(${modIdent})`;
|
|
317
|
-
needsInterop = true;
|
|
318
|
-
}
|
|
319
|
-
lines.push(exportAssignment(exported, rhs, live));
|
|
320
|
-
}
|
|
321
|
-
exportTransforms.push({
|
|
322
|
-
start: node.start,
|
|
323
|
-
end: node.end,
|
|
324
|
-
code: `${lines.join('\n')}\n`,
|
|
325
|
-
needsInterop
|
|
326
|
-
});
|
|
327
|
-
} else {
|
|
328
|
-
const lines = [];
|
|
329
|
-
for (const spec of node.specifiers) {
|
|
330
|
-
if (spec.type !== 'ExportSpecifier') continue;
|
|
331
|
-
const exported = (0, _ast.getModuleExportName)(spec.exported);
|
|
332
|
-
const local = (0, _ast.getModuleExportName)(spec.local);
|
|
333
|
-
if (!exported || !local) continue;
|
|
334
|
-
lines.push(exportAssignment(exported, local, live));
|
|
335
|
-
}
|
|
336
|
-
exportTransforms.push({
|
|
337
|
-
start: node.start,
|
|
338
|
-
end: node.end,
|
|
339
|
-
code: `${lines.join('\n')}\n`
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
if (node.type === 'ExportDefaultDeclaration') {
|
|
345
|
-
const decl = node.declaration;
|
|
346
|
-
const useExportsObject = containsTopLevelAwait && opts.topLevelAwait !== 'error';
|
|
347
|
-
if (decl.type === 'FunctionDeclaration' || decl.type === 'ClassDeclaration') {
|
|
348
|
-
if (decl.id?.name) {
|
|
349
|
-
const declSrc = code.slice(decl.start, decl.end);
|
|
350
|
-
const assign = useExportsObject ? `exports.default = ${decl.id.name};` : `module.exports = ${decl.id.name};`;
|
|
351
|
-
exportTransforms.push({
|
|
352
|
-
start: node.start,
|
|
353
|
-
end: node.end,
|
|
354
|
-
code: `${declSrc}\n${assign}\n`
|
|
355
|
-
});
|
|
356
|
-
} else {
|
|
357
|
-
const declSrc = code.slice(decl.start, decl.end);
|
|
358
|
-
const assign = useExportsObject ? `exports.default = ${declSrc};` : `module.exports = ${declSrc};`;
|
|
359
|
-
exportTransforms.push({
|
|
360
|
-
start: node.start,
|
|
361
|
-
end: node.end,
|
|
362
|
-
code: `${assign}\n`
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
} else {
|
|
366
|
-
const exprSrc = code.slice(decl.start, decl.end);
|
|
367
|
-
const assign = useExportsObject ? `exports.default = ${exprSrc};` : `module.exports = ${exprSrc};`;
|
|
368
|
-
exportTransforms.push({
|
|
369
|
-
start: node.start,
|
|
370
|
-
end: node.end,
|
|
371
|
-
code: `${assign}\n`
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (node.type === 'ExportAllDeclaration') {
|
|
376
|
-
const srcLiteral = code.slice(node.source.start, node.source.end);
|
|
377
|
-
if ('exported' in node && node.exported) {
|
|
378
|
-
const exported = (0, _ast.getModuleExportName)(node.exported);
|
|
379
|
-
if (!exported) {
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
const modIdent = `__mod${importIndex++}`;
|
|
383
|
-
const lines = [`const ${modIdent} = require(${srcLiteral});`, exportAssignment(exported, modIdent, live)];
|
|
384
|
-
exportTransforms.push({
|
|
385
|
-
start: node.start,
|
|
386
|
-
end: node.end,
|
|
387
|
-
code: `${lines.join('\n')}\n`
|
|
388
|
-
});
|
|
389
|
-
} else {
|
|
390
|
-
const modIdent = `__mod${importIndex++}`;
|
|
391
|
-
const lines = [`const ${modIdent} = require(${srcLiteral});`];
|
|
392
|
-
const loop = `for (const k in ${modIdent}) {\n if (k === 'default') continue;\n if (!Object.prototype.hasOwnProperty.call(${modIdent}, k)) continue;\n Object.defineProperty(exports, k, { enumerable: true, get: () => ${modIdent}[k] });\n}`;
|
|
393
|
-
lines.push(loop);
|
|
394
|
-
exportTransforms.push({
|
|
395
|
-
start: node.start,
|
|
396
|
-
end: node.end,
|
|
397
|
-
code: `${lines.join('\n')}\n`
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return {
|
|
403
|
-
importTransforms,
|
|
404
|
-
exportTransforms,
|
|
405
|
-
needsInterop
|
|
406
|
-
};
|
|
407
|
-
};
|
|
408
28
|
/**
|
|
409
29
|
* Node added support for import.meta.main.
|
|
410
30
|
* Added in: v24.2.0, v22.18.0
|
|
@@ -470,206 +90,24 @@ const format = async (src, ast, opts) => {
|
|
|
470
90
|
end: firstExports?.end ?? 0
|
|
471
91
|
});
|
|
472
92
|
}
|
|
473
|
-
const reservedExports = new Set(['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield']);
|
|
474
|
-
const isValidExportName = name => /^[$A-Z_a-z][$\w]*$/.test(name) && !reservedExports.has(name);
|
|
475
|
-
const isAllowedRhs = node => {
|
|
476
|
-
return node.type === 'Identifier' || node.type === 'Literal' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression' || node.type === 'ClassExpression';
|
|
477
|
-
};
|
|
478
|
-
const buildIdiomaticPlan = () => {
|
|
479
|
-
if (idiomaticMode === 'off') return {
|
|
480
|
-
ok: false,
|
|
481
|
-
reason: 'disabled'
|
|
482
|
-
};
|
|
483
|
-
const entries = [...exportTable.values()];
|
|
484
|
-
if (!entries.length) return {
|
|
485
|
-
ok: false,
|
|
486
|
-
reason: 'no-exports'
|
|
487
|
-
};
|
|
488
|
-
if (exportTable.hasUnsupportedExportWrite) {
|
|
489
|
-
return {
|
|
490
|
-
ok: false,
|
|
491
|
-
reason: 'unsupported-left'
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
const viaSet = new Set();
|
|
495
|
-
for (const entry of entries) {
|
|
496
|
-
entry.via.forEach(v => viaSet.add(v));
|
|
497
|
-
if (entry.hasGetter) return {
|
|
498
|
-
ok: false,
|
|
499
|
-
reason: 'getter-present'
|
|
500
|
-
};
|
|
501
|
-
if (entry.reassignments.length) return {
|
|
502
|
-
ok: false,
|
|
503
|
-
reason: 'reassignment'
|
|
504
|
-
};
|
|
505
|
-
if (entry.hasNonTopLevelWrite) return {
|
|
506
|
-
ok: false,
|
|
507
|
-
reason: 'non-top-level'
|
|
508
|
-
};
|
|
509
|
-
if (entry.writes.length !== 1) return {
|
|
510
|
-
ok: false,
|
|
511
|
-
reason: 'multiple-writes'
|
|
512
|
-
};
|
|
513
|
-
if (entry.key !== 'default' && !isValidExportName(entry.key)) return {
|
|
514
|
-
ok: false,
|
|
515
|
-
reason: 'non-identifier-key'
|
|
516
|
-
};
|
|
517
|
-
}
|
|
518
|
-
if (viaSet.size > 1) return {
|
|
519
|
-
ok: false,
|
|
520
|
-
reason: 'mixed-exports'
|
|
521
|
-
};
|
|
522
|
-
const replacements = [];
|
|
523
|
-
const exportsOut = [];
|
|
524
|
-
const seen = new Set();
|
|
525
|
-
const requireShadowed = shadowedBindings;
|
|
526
|
-
const rhsSourceFor = node => {
|
|
527
|
-
const raw = code.slice(node.start, node.end);
|
|
528
|
-
return raw.replace(/\b__dirname\b/g, 'import.meta.dirname').replace(/\b__filename\b/g, 'import.meta.filename');
|
|
529
|
-
};
|
|
530
|
-
const tryObjectLiteralExport = (rhs, baseIsModuleExports, propName) => {
|
|
531
|
-
if (!baseIsModuleExports || propName !== 'exports') return null;
|
|
532
|
-
if (rhs.type !== 'ObjectExpression') return null;
|
|
533
|
-
const exportsOut = [];
|
|
534
|
-
const seenKeys = new Set();
|
|
535
|
-
for (const prop of rhs.properties) {
|
|
536
|
-
if (prop.type !== 'Property') return null;
|
|
537
|
-
if (prop.kind !== 'init') return null;
|
|
538
|
-
if (prop.computed || prop.method) return null;
|
|
539
|
-
if (prop.key.type !== 'Identifier') return null;
|
|
540
|
-
const key = prop.key.name;
|
|
541
|
-
if (key === '__proto__' || key === 'prototype') return null;
|
|
542
|
-
if (!isValidExportName(key)) return null;
|
|
543
|
-
if (seenKeys.has(key)) return null;
|
|
544
|
-
const value = prop.value.type === 'Identifier' && prop.shorthand ? prop.key : prop.value;
|
|
545
|
-
if (!isAllowedRhs(value)) return null;
|
|
546
|
-
if (expressionHasRequireCall(value, requireShadowed)) return null;
|
|
547
|
-
const rhsSrc = rhsSourceFor(value);
|
|
548
|
-
if (value.type === 'Identifier' && value.name === key) {
|
|
549
|
-
exportsOut.push(`export { ${key} };`);
|
|
550
|
-
} else if (value.type === 'Identifier') {
|
|
551
|
-
exportsOut.push(`export { ${rhsSrc} as ${key} };`);
|
|
552
|
-
} else {
|
|
553
|
-
exportsOut.push(`export const ${key} = ${rhsSrc};`);
|
|
554
|
-
}
|
|
555
|
-
seenKeys.add(key);
|
|
556
|
-
}
|
|
557
|
-
exportsOut.push(`export default ${rhsSourceFor(rhs)};`);
|
|
558
|
-
return {
|
|
559
|
-
exportsOut,
|
|
560
|
-
seenKeys
|
|
561
|
-
};
|
|
562
|
-
};
|
|
563
|
-
for (const entry of entries) {
|
|
564
|
-
const write = entry.writes[0];
|
|
565
|
-
if (write.type !== 'AssignmentExpression') {
|
|
566
|
-
return {
|
|
567
|
-
ok: false,
|
|
568
|
-
reason: 'unsupported-write-kind'
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
const left = write.left;
|
|
572
|
-
if (left.type !== 'MemberExpression' || left.computed || left.property.type !== 'Identifier') {
|
|
573
|
-
return {
|
|
574
|
-
ok: false,
|
|
575
|
-
reason: 'unsupported-left'
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
const base = left.object;
|
|
579
|
-
const propName = left.property.name;
|
|
580
|
-
const baseIsExports = base.type === 'Identifier' && base.name === 'exports';
|
|
581
|
-
const baseIsModuleExports = base.type === 'Identifier' && base.name === 'module' && propName === 'exports' || base.type === 'MemberExpression' && base.object.type === 'Identifier' && base.object.name === 'module' && base.property.type === 'Identifier' && base.property.name === 'exports';
|
|
582
|
-
if (!baseIsExports && !baseIsModuleExports) {
|
|
583
|
-
return {
|
|
584
|
-
ok: false,
|
|
585
|
-
reason: 'unsupported-base'
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
const rhs = write.right;
|
|
589
|
-
const objectLiteralPlan = tryObjectLiteralExport(rhs, baseIsModuleExports, propName);
|
|
590
|
-
if (!objectLiteralPlan) {
|
|
591
|
-
if (!isAllowedRhs(rhs)) return {
|
|
592
|
-
ok: false,
|
|
593
|
-
reason: 'unsupported-rhs'
|
|
594
|
-
};
|
|
595
|
-
if (expressionHasRequireCall(rhs, requireShadowed)) {
|
|
596
|
-
return {
|
|
597
|
-
ok: false,
|
|
598
|
-
reason: 'rhs-require'
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
const rhsSrc = rhsSourceFor(rhs);
|
|
603
|
-
if (propName === 'exports' && baseIsModuleExports) {
|
|
604
|
-
if (objectLiteralPlan) {
|
|
605
|
-
for (const line of objectLiteralPlan.exportsOut) {
|
|
606
|
-
exportsOut.push(line);
|
|
607
|
-
}
|
|
608
|
-
objectLiteralPlan.seenKeys.forEach(k => seen.add(k));
|
|
609
|
-
} else {
|
|
610
|
-
// module.exports = ... handles default
|
|
611
|
-
if (seen.has('default')) return {
|
|
612
|
-
ok: false,
|
|
613
|
-
reason: 'duplicate-default'
|
|
614
|
-
};
|
|
615
|
-
seen.add('default');
|
|
616
|
-
exportsOut.push(`export default ${rhsSrc};`);
|
|
617
|
-
}
|
|
618
|
-
} else {
|
|
619
|
-
if (seen.has(propName)) return {
|
|
620
|
-
ok: false,
|
|
621
|
-
reason: 'duplicate-key'
|
|
622
|
-
};
|
|
623
|
-
seen.add(propName);
|
|
624
|
-
if (rhs.type === 'Identifier') {
|
|
625
|
-
const rhsId = rhsSourceFor(rhs);
|
|
626
|
-
const rhsName = rhs.name;
|
|
627
|
-
if (rhsId === rhsName && rhsName === propName) {
|
|
628
|
-
exportsOut.push(`export { ${propName} };`);
|
|
629
|
-
} else if (rhsId === rhsName) {
|
|
630
|
-
exportsOut.push(`export { ${rhsId} as ${propName} };`);
|
|
631
|
-
} else {
|
|
632
|
-
exportsOut.push(`export const ${propName} = ${rhsId};`);
|
|
633
|
-
}
|
|
634
|
-
} else {
|
|
635
|
-
exportsOut.push(`export const ${propName} = ${rhsSrc};`);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Trim trailing whitespace and one optional semicolon so the idiomatic export
|
|
640
|
-
// replacement does not leave the original `;` behind (avoids emitting `;;`).
|
|
641
|
-
let end = write.end;
|
|
642
|
-
while (end < src.length && (src[end] === ' ' || src[end] === '\t')) end++;
|
|
643
|
-
if (end < src.length && src[end] === ';') end++;
|
|
644
|
-
replacements.push({
|
|
645
|
-
start: write.start,
|
|
646
|
-
end
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
if (!seen.size) return {
|
|
650
|
-
ok: false,
|
|
651
|
-
reason: 'no-seen'
|
|
652
|
-
};
|
|
653
|
-
return {
|
|
654
|
-
ok: true,
|
|
655
|
-
plan: {
|
|
656
|
-
replacements,
|
|
657
|
-
exports: exportsOut
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
};
|
|
661
93
|
if (idiomaticMode !== 'off') {
|
|
662
|
-
const res = buildIdiomaticPlan(
|
|
663
|
-
|
|
94
|
+
const res = (0, _idiomaticPlan.buildIdiomaticPlan)({
|
|
95
|
+
src,
|
|
96
|
+
code,
|
|
97
|
+
exportTable,
|
|
98
|
+
shadowedBindings,
|
|
99
|
+
idiomaticMode
|
|
100
|
+
});
|
|
101
|
+
if (res.ok) {
|
|
664
102
|
useExportsBag = false;
|
|
665
103
|
idiomaticPlan = res.plan;
|
|
666
|
-
} else
|
|
104
|
+
} else {
|
|
667
105
|
idiomaticFallbackReason = res.reason;
|
|
668
106
|
}
|
|
669
107
|
}
|
|
670
108
|
}
|
|
671
109
|
const shouldCheckTopLevelAwait = opts.target === 'commonjs' && fullTransform;
|
|
672
|
-
const containsTopLevelAwait = shouldCheckTopLevelAwait ? hasTopLevelAwait(ast.program) : false;
|
|
110
|
+
const containsTopLevelAwait = shouldCheckTopLevelAwait ? (0, _async.hasTopLevelAwait)(ast.program) : false;
|
|
673
111
|
if (idiomaticFallbackReason && idiomaticMode !== 'off') {
|
|
674
112
|
warnOnce('idiomatic-exports-fallback', `Idiomatic exports disabled for this file: ${idiomaticFallbackReason}. Falling back to helper exports.`);
|
|
675
113
|
}
|
|
@@ -697,172 +135,49 @@ const format = async (src, ast, opts) => {
|
|
|
697
135
|
hoisted,
|
|
698
136
|
needsCreateRequire: reqCreate,
|
|
699
137
|
needsInteropHelper: reqInteropHelper
|
|
700
|
-
} = lowerCjsRequireToImports(ast.program, code, shadowedBindings);
|
|
138
|
+
} = (0, _lowerCjsRequireToImports.lowerCjsRequireToImports)(ast.program, code, shadowedBindings);
|
|
701
139
|
pendingRequireTransforms = transforms;
|
|
702
140
|
hoistedImports = imports;
|
|
703
141
|
hoistedStatements = hoisted;
|
|
704
142
|
needsCreateRequire = reqCreate;
|
|
705
143
|
needsImportInterop = reqInteropHelper;
|
|
706
144
|
}
|
|
145
|
+
const walkState = {
|
|
146
|
+
importMetaRef,
|
|
147
|
+
requireMainNeedsRealpath,
|
|
148
|
+
needsCreateRequire,
|
|
149
|
+
needsRequireResolveHelper
|
|
150
|
+
};
|
|
707
151
|
await (0, _walk.ancestorWalk)(ast.program, {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
if (requireMainStrategy === 'import-meta-main') {
|
|
732
|
-
importMetaRef = true;
|
|
733
|
-
}
|
|
734
|
-
code.update(node.start, node.end, negate ? `!(${mainExpr})` : mainExpr);
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
if (shouldRaiseEsm && node.type === 'WithStatement') {
|
|
740
|
-
throw new Error('Cannot transform to ESM: with statements are not supported.');
|
|
741
|
-
}
|
|
742
|
-
if (shouldRaiseEsm && node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === 'eval' && !shadowedBindings.has('eval')) {
|
|
743
|
-
throw new Error('Cannot transform to ESM: eval is not supported.');
|
|
744
|
-
}
|
|
745
|
-
if (shouldRaiseEsm && node.type === 'CallExpression' && isRequireCall(node, shadowedBindings)) {
|
|
746
|
-
const isStatic = isStaticRequire(node, shadowedBindings);
|
|
747
|
-
const parent = ancestors[ancestors.length - 2] ?? null;
|
|
748
|
-
const grandparent = ancestors[ancestors.length - 3] ?? null;
|
|
749
|
-
const greatGrandparent = ancestors[ancestors.length - 4] ?? null;
|
|
750
|
-
|
|
751
|
-
// Hoistable cases are handled separately and don't need createRequire.
|
|
752
|
-
const topLevelExprStmt = parent?.type === 'ExpressionStatement' && grandparent?.type === 'Program';
|
|
753
|
-
const topLevelVarDecl = parent?.type === 'VariableDeclarator' && grandparent?.type === 'VariableDeclaration' && greatGrandparent?.type === 'Program';
|
|
754
|
-
const hoistableTopLevel = isStatic && (topLevelExprStmt || topLevelVarDecl);
|
|
755
|
-
if (!isStatic || !hoistableTopLevel) {
|
|
756
|
-
if (nestedRequireStrategy === 'dynamic-import') {
|
|
757
|
-
const asyncCapable = isAsyncContext(ancestors);
|
|
758
|
-
if (asyncCapable) {
|
|
759
|
-
const arg = node.arguments[0];
|
|
760
|
-
const argSrc = arg ? code.slice(arg.start, arg.end) : 'undefined';
|
|
761
|
-
const literalVal = arg?.value;
|
|
762
|
-
const isJson = arg?.type === 'Literal' && typeof literalVal === 'string' && (literalVal.split(/[?#]/)[0] ?? literalVal).endsWith('.json');
|
|
763
|
-
const importTarget = isJson ? `${argSrc} with { type: "json" }` : argSrc;
|
|
764
|
-
code.update(node.start, node.end, `(await import(${importTarget}))`);
|
|
765
|
-
return;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
needsCreateRequire = true;
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
772
|
-
const skipped = ['__filename', '__dirname'];
|
|
773
|
-
const skippedParams = node.params.filter(param => param.type === 'Identifier' && skipped.includes(param.name));
|
|
774
|
-
const skippedFuncIdentifier = node.id?.type === 'Identifier' && skipped.includes(node.id.name);
|
|
775
|
-
if (skippedParams.length || skippedFuncIdentifier) {
|
|
776
|
-
this.skip();
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
/**
|
|
781
|
-
* Check for assignment to `import.meta.url`.
|
|
782
|
-
*/
|
|
783
|
-
if (node.type === 'AssignmentExpression' && node.left.type === 'MemberExpression' && node.left.object.type === 'MetaProperty' && node.left.property.type === 'Identifier' && node.left.property.name === 'url') {
|
|
784
|
-
if (node.right.type === 'Literal' && typeof node.right.value === 'string') {
|
|
785
|
-
if (!(0, _url.isValidUrl)(node.right.value)) {
|
|
786
|
-
const rhs = code.snip(node.right.start, node.right.end).toString();
|
|
787
|
-
const assignment = code.snip(node.start, node.end).toString();
|
|
788
|
-
code.update(node.start, node.end, `/* Invalid assignment: ${rhs} is not a URL. ${assignment} */`);
|
|
789
|
-
this.skip();
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* Skip module scope CJS globals when they are object properties.
|
|
796
|
-
* Ignoring `exports` here.
|
|
797
|
-
*/
|
|
798
|
-
if (node.type === 'MemberExpression' && node.property.type === 'Identifier' && ['__filename', '__dirname'].includes(node.property.name)) {
|
|
799
|
-
this.skip();
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
/**
|
|
803
|
-
* Check for bare `module.exports` expressions.
|
|
804
|
-
*/
|
|
805
|
-
if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'module' && node.property.type === 'Identifier' && node.property.name === 'exports' && parent?.type === 'ExpressionStatement') {
|
|
806
|
-
if (opts.target === 'module') {
|
|
807
|
-
code.update(node.start, node.end, ';');
|
|
808
|
-
// Prevent parsing the `exports` identifier again.
|
|
809
|
-
this.skip();
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* Format `module.exports` and `exports` assignments.
|
|
815
|
-
*/
|
|
816
|
-
if (node.type === 'AssignmentExpression') {
|
|
817
|
-
await (0, _assignmentExpression.assignmentExpression)({
|
|
818
|
-
node,
|
|
819
|
-
parent,
|
|
820
|
-
code,
|
|
821
|
-
opts,
|
|
822
|
-
meta: exportsMeta
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
if (node.type === 'MetaProperty') {
|
|
826
|
-
(0, _metaProperty.metaProperty)(node, parent, code, opts);
|
|
827
|
-
}
|
|
828
|
-
if (node.type === 'MemberExpression') {
|
|
829
|
-
(0, _memberExpression.memberExpression)(node, parent, code, opts, shadowedBindings, {
|
|
830
|
-
onRequireResolve: () => {
|
|
831
|
-
if (shouldRaiseEsm) needsRequireResolveHelper = true;
|
|
832
|
-
},
|
|
833
|
-
requireResolveName: '__requireResolve',
|
|
834
|
-
onDiagnostic: (codeId, message, loc) => {
|
|
835
|
-
if (shouldRaiseEsm) warnOnce(codeId, message, loc);
|
|
836
|
-
}
|
|
837
|
-
}, useExportsBag, fullTransform);
|
|
838
|
-
}
|
|
839
|
-
if (shouldRaiseEsm && node.type === 'ThisExpression') {
|
|
840
|
-
const bindsThis = ancestor => {
|
|
841
|
-
return ancestor.type === 'FunctionDeclaration' || ancestor.type === 'FunctionExpression' || ancestor.type === 'ClassDeclaration' || ancestor.type === 'ClassExpression';
|
|
842
|
-
};
|
|
843
|
-
const bindingAncestor = ancestors.find(ancestor => bindsThis(ancestor));
|
|
844
|
-
const isTopLevel = !bindingAncestor;
|
|
845
|
-
if (isTopLevel) {
|
|
846
|
-
code.update(node.start, node.end, _exports.exportsRename);
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
if ((0, _identifier2.isIdentifierName)(node)) {
|
|
851
|
-
if (shouldRaiseEsm && node.type === 'Identifier' && (node.name === '__dirname' || node.name === '__filename')) {
|
|
852
|
-
importMetaRef = true;
|
|
853
|
-
}
|
|
854
|
-
(0, _identifier.identifier)({
|
|
855
|
-
node,
|
|
856
|
-
ancestors,
|
|
857
|
-
code,
|
|
858
|
-
opts,
|
|
859
|
-
meta: exportsMeta,
|
|
860
|
-
shadowed: shadowedBindings,
|
|
861
|
-
useExportsBag
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
}
|
|
152
|
+
enter: (0, _formatVisitor.buildFormatVisitor)({
|
|
153
|
+
code,
|
|
154
|
+
opts,
|
|
155
|
+
warnOnce,
|
|
156
|
+
shadowedBindings,
|
|
157
|
+
requireMainStrategy,
|
|
158
|
+
nestedRequireStrategy,
|
|
159
|
+
shouldRaiseEsm,
|
|
160
|
+
fullTransform,
|
|
161
|
+
useExportsBag,
|
|
162
|
+
exportsMeta,
|
|
163
|
+
isRequireMainMember,
|
|
164
|
+
isRequireCall: _lowerCjsRequireToImports.isRequireCall,
|
|
165
|
+
isStaticRequire: _lowerCjsRequireToImports.isStaticRequire,
|
|
166
|
+
isAsyncContext: _async.isAsyncContext,
|
|
167
|
+
isValidUrl: _url.isValidUrl,
|
|
168
|
+
isIdentifierName: _identifier.isIdentifierName,
|
|
169
|
+
assignmentExpression: _assignmentExpression.assignmentExpression,
|
|
170
|
+
metaProperty: _metaProperty.metaProperty,
|
|
171
|
+
memberExpression: _memberExpression.memberExpression,
|
|
172
|
+
identifier: _identifier2.identifier
|
|
173
|
+
}, walkState)
|
|
865
174
|
});
|
|
175
|
+
({
|
|
176
|
+
importMetaRef,
|
|
177
|
+
requireMainNeedsRealpath,
|
|
178
|
+
needsCreateRequire,
|
|
179
|
+
needsRequireResolveHelper
|
|
180
|
+
} = walkState);
|
|
866
181
|
if (pendingRequireTransforms.length) {
|
|
867
182
|
for (const t of pendingRequireTransforms) {
|
|
868
183
|
code.overwrite(t.start, t.end, t.code);
|
|
@@ -890,7 +205,7 @@ const format = async (src, ast, opts) => {
|
|
|
890
205
|
importTransforms,
|
|
891
206
|
exportTransforms,
|
|
892
207
|
needsInterop
|
|
893
|
-
} = lowerEsmToCjs(ast.program, code, opts, containsTopLevelAwait);
|
|
208
|
+
} = (0, _lowerEsmToCjs.lowerEsmToCjs)(ast.program, code, opts, containsTopLevelAwait);
|
|
894
209
|
pendingCjsTransforms = {
|
|
895
210
|
transforms: [...importTransforms, ...exportTransforms].sort((a, b) => a.start - b.start),
|
|
896
211
|
needsInterop
|
|
@@ -901,119 +216,30 @@ const format = async (src, ast, opts) => {
|
|
|
901
216
|
code.overwrite(t.start, t.end, t.code);
|
|
902
217
|
}
|
|
903
218
|
if (pendingCjsTransforms.needsInterop) {
|
|
904
|
-
code.prepend(`${interopHelper}exports.__esModule = true;\n`);
|
|
219
|
+
code.prepend(`${_interopHelpers.interopHelper}exports.__esModule = true;\n`);
|
|
905
220
|
}
|
|
906
221
|
}
|
|
907
222
|
if (useExportsBag && opts.target === 'module' && fullTransform && exportTable) {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
return 'import.meta.dirname';
|
|
915
|
-
}
|
|
916
|
-
if (name === '__filename') {
|
|
917
|
-
importMetaRef = true;
|
|
918
|
-
return 'import.meta.filename';
|
|
919
|
-
}
|
|
920
|
-
return name;
|
|
921
|
-
};
|
|
922
|
-
const tempNameFor = name => {
|
|
923
|
-
const sanitized = name.replace(/[^$\w]/g, '_') || 'value';
|
|
924
|
-
const safe = /^[0-9]/.test(sanitized) ? `_${sanitized}` : sanitized;
|
|
925
|
-
return `__export_${safe}`;
|
|
926
|
-
};
|
|
927
|
-
for (const [key, entry] of exportTable) {
|
|
928
|
-
if (entry.reassignments.length) {
|
|
929
|
-
const loc = entry.reassignments[0];
|
|
930
|
-
warnOnce(`cjs-export-reassignment:${key}`, `Export '${key}' is reassigned after export; ESM live bindings may change consumer behavior.`, {
|
|
931
|
-
start: loc.start,
|
|
932
|
-
end: loc.end
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
const lines = [];
|
|
937
|
-
const defaultEntry = exportTable.get('default');
|
|
938
|
-
if (defaultEntry) {
|
|
939
|
-
const def = defaultEntry.fromIdentifier ?? _exports.exportsRename;
|
|
940
|
-
const defExpr = exportValueFor(def);
|
|
941
|
-
if (defExpr !== def) {
|
|
942
|
-
const temp = tempNameFor(def);
|
|
943
|
-
lines.push(`const ${temp} = ${defExpr};`);
|
|
944
|
-
lines.push(`export default ${temp};`);
|
|
945
|
-
} else {
|
|
946
|
-
lines.push(`export default ${defExpr};`);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
for (const [key, entry] of exportTable) {
|
|
950
|
-
if (key === 'default') continue;
|
|
951
|
-
if (!isValidExportName(key)) {
|
|
952
|
-
warnOnce(`cjs-string-export:${key}`, `Synthesized string-literal export '${key}'. Some tooling may require bracket access to use it.`);
|
|
953
|
-
}
|
|
954
|
-
if (entry.fromIdentifier) {
|
|
955
|
-
const resolved = exportValueFor(entry.fromIdentifier);
|
|
956
|
-
if (resolved !== entry.fromIdentifier) {
|
|
957
|
-
const temp = tempNameFor(entry.fromIdentifier);
|
|
958
|
-
lines.push(`const ${temp} = ${resolved};`);
|
|
959
|
-
lines.push(`export { ${temp} as ${asExportName(key)} };`);
|
|
960
|
-
} else {
|
|
961
|
-
lines.push(`export { ${resolved} as ${asExportName(key)} };`);
|
|
962
|
-
}
|
|
963
|
-
} else {
|
|
964
|
-
const temp = tempNameFor(key);
|
|
965
|
-
lines.push(`const ${temp} = ${accessProp(key)};`);
|
|
966
|
-
lines.push(`export { ${temp} as ${asExportName(key)} };`);
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
if (lines.length) {
|
|
970
|
-
code.append(`\n${lines.join('\n')}\n`);
|
|
971
|
-
}
|
|
223
|
+
importMetaRef = (0, _exportBagToEsm.exportBagToEsm)({
|
|
224
|
+
code,
|
|
225
|
+
exportTable,
|
|
226
|
+
warnOnce,
|
|
227
|
+
importMetaRef
|
|
228
|
+
});
|
|
972
229
|
}
|
|
973
230
|
if (shouldRaiseEsm && fullTransform) {
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
importPrelude.push('import { pathToFileURL } from "node:url";\n');
|
|
987
|
-
}
|
|
988
|
-
if (hoistedImports.length) {
|
|
989
|
-
importPrelude.push(...hoistedImports);
|
|
990
|
-
}
|
|
991
|
-
const setupPrelude = [];
|
|
992
|
-
if (needsImportInterop) {
|
|
993
|
-
setupPrelude.push(requireInteropHelper);
|
|
994
|
-
}
|
|
995
|
-
if (hoistedStatements.length) {
|
|
996
|
-
setupPrelude.push(...hoistedStatements);
|
|
997
|
-
}
|
|
998
|
-
const requireInit = needsCreateRequire ? 'const require = createRequire(import.meta.url);\n' : '';
|
|
999
|
-
const requireResolveInit = needsRequireResolveHelper ? needsCreateRequire ? `const __requireResolve = (id, parent) => {
|
|
1000
|
-
const resolved = require.resolve(id, parent);
|
|
1001
|
-
return resolved.startsWith("file://") ? fileURLToPath(resolved) : resolved;
|
|
1002
|
-
};\n` : `const __requireResolve = (id, parent) => {
|
|
1003
|
-
const req = createRequire(parent ?? import.meta.url);
|
|
1004
|
-
const resolved = req.resolve(id, parent);
|
|
1005
|
-
return resolved.startsWith("file://") ? fileURLToPath(resolved) : resolved;
|
|
1006
|
-
};\n` : '';
|
|
1007
|
-
const exportsBagInit = useExportsBag ? `let ${_exports.exportsRename} = {};
|
|
1008
|
-
` : '';
|
|
1009
|
-
const modulePrelude = '';
|
|
1010
|
-
const prelude = `${importPrelude.join('')}${importPrelude.length ? '\n' : ''}${setupPrelude.join('')}${setupPrelude.length ? '\n' : ''}${requireInit}${requireResolveInit}${exportsBagInit}${modulePrelude}`;
|
|
1011
|
-
const importMetaTouch = (() => {
|
|
1012
|
-
if (importMetaPreludeMode === 'on') return 'void import.meta.filename;\n';
|
|
1013
|
-
if (importMetaPreludeMode === 'off') return '';
|
|
1014
|
-
return importMetaRef ? 'void import.meta.filename;\n' : '';
|
|
1015
|
-
})();
|
|
1016
|
-
code.prepend(`${prelude}${importMetaTouch}`);
|
|
231
|
+
const prelude = (0, _buildEsmPrelude.buildEsmPrelude)({
|
|
232
|
+
needsCreateRequire,
|
|
233
|
+
needsRequireResolveHelper,
|
|
234
|
+
requireMainNeedsRealpath,
|
|
235
|
+
hoistedImports,
|
|
236
|
+
hoistedStatements,
|
|
237
|
+
needsImportInterop,
|
|
238
|
+
importMetaPreludeMode,
|
|
239
|
+
importMetaRef,
|
|
240
|
+
useExportsBag
|
|
241
|
+
});
|
|
242
|
+
code.prepend(prelude);
|
|
1017
243
|
}
|
|
1018
244
|
if (opts.target === 'commonjs' && fullTransform && containsTopLevelAwait) {
|
|
1019
245
|
const body = code.toString();
|