@lifo-sh/node-runner 0.1.0 → 0.1.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/index.cjs +951 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -6
- package/dist/index.d.ts +83 -6
- package/dist/index.js +946 -134
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
NodeRunner: () => NodeRunner
|
|
23
|
+
NodeRunner: () => NodeRunner,
|
|
24
|
+
ProcessExitError: () => ProcessExitError,
|
|
25
|
+
resolveModule: () => resolveModule,
|
|
26
|
+
shouldTreatAsEsm: () => shouldTreatAsEsm,
|
|
27
|
+
transformEsmToCjs: () => transformEsmToCjs,
|
|
28
|
+
transformToCjs: () => transformToCjs
|
|
24
29
|
});
|
|
25
30
|
module.exports = __toCommonJS(index_exports);
|
|
26
31
|
|
|
@@ -78,19 +83,30 @@ var minimalPath = {
|
|
|
78
83
|
posix: null
|
|
79
84
|
};
|
|
80
85
|
minimalPath.posix = minimalPath;
|
|
81
|
-
function
|
|
82
|
-
|
|
86
|
+
function formatArgs(...args) {
|
|
87
|
+
return args.map(
|
|
83
88
|
(a) => typeof a === "string" ? a : JSON.stringify(a, null, 2) ?? String(a)
|
|
84
89
|
).join(" ");
|
|
90
|
+
}
|
|
91
|
+
function createCaptureConsole(stdout, stderr) {
|
|
92
|
+
return {
|
|
93
|
+
log: (...args) => stdout.push(formatArgs(...args)),
|
|
94
|
+
error: (...args) => stderr.push(formatArgs(...args)),
|
|
95
|
+
warn: (...args) => stderr.push(formatArgs(...args)),
|
|
96
|
+
info: (...args) => stdout.push(formatArgs(...args)),
|
|
97
|
+
debug: (...args) => stdout.push(formatArgs(...args))
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function createStreamConsole(stdout, stderr) {
|
|
85
101
|
return {
|
|
86
|
-
log: (...args) => stdout.
|
|
87
|
-
error: (...args) => stderr.
|
|
88
|
-
warn: (...args) => stderr.
|
|
89
|
-
info: (...args) => stdout.
|
|
90
|
-
debug: (...args) => stdout.
|
|
102
|
+
log: (...args) => stdout.write(formatArgs(...args) + "\n"),
|
|
103
|
+
error: (...args) => stderr.write(formatArgs(...args) + "\n"),
|
|
104
|
+
warn: (...args) => stderr.write(formatArgs(...args) + "\n"),
|
|
105
|
+
info: (...args) => stdout.write(formatArgs(...args) + "\n"),
|
|
106
|
+
debug: (...args) => stdout.write(formatArgs(...args) + "\n")
|
|
91
107
|
};
|
|
92
108
|
}
|
|
93
|
-
function createMinimalProcess(env, cwd, argv) {
|
|
109
|
+
function createMinimalProcess(env, cwd, argv, stdout, stderr) {
|
|
94
110
|
return {
|
|
95
111
|
env,
|
|
96
112
|
cwd: () => cwd,
|
|
@@ -105,12 +121,14 @@ function createMinimalProcess(env, cwd, argv) {
|
|
|
105
121
|
pid: 1,
|
|
106
122
|
ppid: 0,
|
|
107
123
|
stdout: {
|
|
108
|
-
write: (
|
|
124
|
+
write: (s) => {
|
|
125
|
+
if (stdout) stdout.write(String(s));
|
|
109
126
|
return true;
|
|
110
127
|
}
|
|
111
128
|
},
|
|
112
129
|
stderr: {
|
|
113
|
-
write: (
|
|
130
|
+
write: (s) => {
|
|
131
|
+
if (stderr) stderr.write(String(s));
|
|
114
132
|
return true;
|
|
115
133
|
}
|
|
116
134
|
},
|
|
@@ -128,13 +146,12 @@ var ProcessExitError = class extends Error {
|
|
|
128
146
|
this.code = code;
|
|
129
147
|
}
|
|
130
148
|
};
|
|
131
|
-
function createBuiltinModules(_vfs, env, cwd, argv, scriptConsole, nodeCompat) {
|
|
149
|
+
function createBuiltinModules(_vfs, env, cwd, argv, scriptConsole, nodeCompat, stdout, stderr) {
|
|
132
150
|
const builtins = /* @__PURE__ */ new Map();
|
|
133
151
|
builtins.set("path", nodeCompat?.path ?? minimalPath);
|
|
134
|
-
const process = nodeCompat?.process ?? createMinimalProcess(env, cwd, argv);
|
|
152
|
+
const process = nodeCompat?.process ?? createMinimalProcess(env, cwd, argv, stdout, stderr);
|
|
135
153
|
builtins.set("process", process);
|
|
136
|
-
|
|
137
|
-
builtins.set("console", console_);
|
|
154
|
+
builtins.set("console", scriptConsole);
|
|
138
155
|
if (nodeCompat?.fs) builtins.set("fs", nodeCompat.fs);
|
|
139
156
|
if (nodeCompat?.fsPromises) builtins.set("fs/promises", nodeCompat.fsPromises);
|
|
140
157
|
if (nodeCompat?.events) builtins.set("events", nodeCompat.events);
|
|
@@ -152,20 +169,40 @@ function createBuiltinModules(_vfs, env, cwd, argv, scriptConsole, nodeCompat) {
|
|
|
152
169
|
// src/resolver.ts
|
|
153
170
|
var textDecoder = new TextDecoder();
|
|
154
171
|
function resolveModule(vfs, id, fromDir) {
|
|
155
|
-
|
|
156
|
-
|
|
172
|
+
if (id.startsWith("#")) {
|
|
173
|
+
return resolvePackageImport(vfs, id, fromDir);
|
|
174
|
+
}
|
|
175
|
+
if (id.startsWith("./") || id.startsWith("../") || id.startsWith("/")) {
|
|
176
|
+
return resolveRelative(vfs, id, fromDir);
|
|
177
|
+
}
|
|
178
|
+
return resolveNodeModule(vfs, id, fromDir);
|
|
179
|
+
}
|
|
180
|
+
function resolveRelative(vfs, id, fromDir) {
|
|
181
|
+
const absPath = id.startsWith("/") ? id : normalizePath(fromDir + "/" + id);
|
|
182
|
+
return resolveFile(vfs, absPath);
|
|
183
|
+
}
|
|
184
|
+
function resolveFile(vfs, absPath) {
|
|
185
|
+
if (vfs.exists(absPath)) {
|
|
157
186
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
187
|
+
const stat = vfs.stat(absPath);
|
|
188
|
+
if (stat.type === "file") {
|
|
189
|
+
const source = textDecoder.decode(vfs.readFile(absPath));
|
|
190
|
+
return { path: absPath, source };
|
|
191
|
+
}
|
|
192
|
+
if (stat.type === "directory") {
|
|
193
|
+
const fromPkg = tryPackageMain(vfs, absPath);
|
|
162
194
|
if (fromPkg) return fromPkg;
|
|
163
|
-
const fromIndex = tryIndexFile(vfs,
|
|
195
|
+
const fromIndex = tryIndexFile(vfs, absPath);
|
|
164
196
|
if (fromIndex) return fromIndex;
|
|
165
|
-
continue;
|
|
166
197
|
}
|
|
167
|
-
|
|
168
|
-
|
|
198
|
+
} catch {
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (const ext of [".js", ".ts", ".mjs", ".json"]) {
|
|
202
|
+
const candidate = absPath + ext;
|
|
203
|
+
try {
|
|
204
|
+
if (vfs.exists(candidate) && vfs.stat(candidate).type === "file") {
|
|
205
|
+
const source = textDecoder.decode(vfs.readFile(candidate));
|
|
169
206
|
return { path: candidate, source };
|
|
170
207
|
}
|
|
171
208
|
} catch {
|
|
@@ -173,33 +210,149 @@ function resolveModule(vfs, id, fromDir) {
|
|
|
173
210
|
}
|
|
174
211
|
return null;
|
|
175
212
|
}
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
candidates.push(resolved + ".json");
|
|
213
|
+
function resolveNodeModule(vfs, name, fromDir) {
|
|
214
|
+
let packageName;
|
|
215
|
+
let subpath = null;
|
|
216
|
+
if (name.startsWith("@")) {
|
|
217
|
+
const parts = name.split("/");
|
|
218
|
+
if (parts.length < 2) return null;
|
|
219
|
+
packageName = parts[0] + "/" + parts[1];
|
|
220
|
+
if (parts.length > 2) subpath = parts.slice(2).join("/");
|
|
185
221
|
} else {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
222
|
+
const slashIdx = name.indexOf("/");
|
|
223
|
+
if (slashIdx !== -1) {
|
|
224
|
+
packageName = name.slice(0, slashIdx);
|
|
225
|
+
subpath = name.slice(slashIdx + 1);
|
|
226
|
+
} else {
|
|
227
|
+
packageName = name;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
let current = fromDir;
|
|
231
|
+
for (; ; ) {
|
|
232
|
+
const candidate = normalizePath(current + "/node_modules/" + packageName);
|
|
233
|
+
if (vfs.exists(candidate)) {
|
|
234
|
+
const resolved = resolvePackageEntry(vfs, candidate, subpath);
|
|
235
|
+
if (resolved) return resolved;
|
|
236
|
+
}
|
|
237
|
+
const parent = current.slice(0, current.lastIndexOf("/"));
|
|
238
|
+
if (parent === current || parent === "") break;
|
|
239
|
+
current = parent;
|
|
240
|
+
}
|
|
241
|
+
for (const globalDir of ["/usr/lib/node_modules", "/usr/share/pkg/node_modules"]) {
|
|
242
|
+
const candidate = normalizePath(globalDir + "/" + packageName);
|
|
243
|
+
if (vfs.exists(candidate)) {
|
|
244
|
+
const resolved = resolvePackageEntry(vfs, candidate, subpath);
|
|
245
|
+
if (resolved) return resolved;
|
|
194
246
|
}
|
|
195
247
|
}
|
|
196
|
-
return
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
function resolveExportsCondition(value) {
|
|
251
|
+
if (typeof value === "string") return value;
|
|
252
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
253
|
+
const cond = value;
|
|
254
|
+
if (typeof cond.require === "string") return cond.require;
|
|
255
|
+
if (typeof cond.default === "string") return cond.default;
|
|
256
|
+
if (typeof cond.import === "string") return cond.import;
|
|
257
|
+
for (const key of Object.keys(cond)) {
|
|
258
|
+
if (key === "types") continue;
|
|
259
|
+
const nested = resolveExportsCondition(cond[key]);
|
|
260
|
+
if (nested) return nested;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
function resolvePackageEntry(vfs, pkgDir, subpath) {
|
|
266
|
+
const pkgJsonPath = pkgDir + "/package.json";
|
|
267
|
+
let pkgJson = null;
|
|
268
|
+
if (vfs.exists(pkgJsonPath)) {
|
|
269
|
+
try {
|
|
270
|
+
pkgJson = JSON.parse(textDecoder.decode(vfs.readFile(pkgJsonPath)));
|
|
271
|
+
} catch {
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (subpath) {
|
|
275
|
+
if (pkgJson?.exports && typeof pkgJson.exports === "object") {
|
|
276
|
+
const exportsMap = pkgJson.exports;
|
|
277
|
+
const key = "./" + subpath;
|
|
278
|
+
if (key in exportsMap) {
|
|
279
|
+
const target = resolveExportsCondition(exportsMap[key]);
|
|
280
|
+
if (target) {
|
|
281
|
+
const resolved = resolveFile(vfs, normalizePath(pkgDir + "/" + target));
|
|
282
|
+
if (resolved) return resolved;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (const pattern of Object.keys(exportsMap)) {
|
|
286
|
+
if (pattern.endsWith("/*") && key.startsWith(pattern.slice(0, -1))) {
|
|
287
|
+
const targetPattern = resolveExportsCondition(exportsMap[pattern]);
|
|
288
|
+
if (targetPattern && targetPattern.endsWith("/*")) {
|
|
289
|
+
const suffix = key.slice(pattern.length - 1);
|
|
290
|
+
const target = targetPattern.slice(0, -1) + suffix;
|
|
291
|
+
const resolved = resolveFile(vfs, normalizePath(pkgDir + "/" + target));
|
|
292
|
+
if (resolved) return resolved;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return resolveFile(vfs, normalizePath(pkgDir + "/" + subpath));
|
|
298
|
+
}
|
|
299
|
+
if (pkgJson?.exports) {
|
|
300
|
+
const exportsVal = pkgJson.exports;
|
|
301
|
+
let rootExport = null;
|
|
302
|
+
if (typeof exportsVal === "string") {
|
|
303
|
+
rootExport = exportsVal;
|
|
304
|
+
} else if (typeof exportsVal === "object" && !Array.isArray(exportsVal)) {
|
|
305
|
+
const exportsMap = exportsVal;
|
|
306
|
+
rootExport = exportsMap["."] ?? null;
|
|
307
|
+
if (!rootExport && ("require" in exportsMap || "import" in exportsMap || "default" in exportsMap)) {
|
|
308
|
+
rootExport = exportsMap;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (rootExport) {
|
|
312
|
+
const target = resolveExportsCondition(rootExport);
|
|
313
|
+
if (target) {
|
|
314
|
+
const resolved = resolveFile(vfs, normalizePath(pkgDir + "/" + target));
|
|
315
|
+
if (resolved) return resolved;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (pkgJson?.main && typeof pkgJson.main === "string") {
|
|
320
|
+
const resolved = resolveFile(vfs, normalizePath(pkgDir + "/" + pkgJson.main));
|
|
321
|
+
if (resolved) return resolved;
|
|
322
|
+
}
|
|
323
|
+
return tryIndexFile(vfs, pkgDir);
|
|
324
|
+
}
|
|
325
|
+
function resolvePackageImport(vfs, name, fromDir) {
|
|
326
|
+
let current = fromDir;
|
|
327
|
+
for (; ; ) {
|
|
328
|
+
const pkgPath = current + "/package.json";
|
|
329
|
+
if (vfs.exists(pkgPath)) {
|
|
330
|
+
try {
|
|
331
|
+
const pkg = JSON.parse(textDecoder.decode(vfs.readFile(pkgPath)));
|
|
332
|
+
if (pkg.imports && typeof pkg.imports === "object") {
|
|
333
|
+
const importsMap = pkg.imports;
|
|
334
|
+
if (name in importsMap) {
|
|
335
|
+
const target = resolveExportsCondition(importsMap[name]);
|
|
336
|
+
if (target) {
|
|
337
|
+
return resolveFile(vfs, normalizePath(current + "/" + target));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} catch {
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
const parent = current.slice(0, current.lastIndexOf("/"));
|
|
346
|
+
if (parent === current || parent === "") break;
|
|
347
|
+
current = parent;
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
197
350
|
}
|
|
198
351
|
function tryPackageMain(vfs, dirPath) {
|
|
199
352
|
const pkgPath = dirPath + "/package.json";
|
|
200
353
|
try {
|
|
201
|
-
if (!vfs.
|
|
202
|
-
const raw = textDecoder.decode(vfs.
|
|
354
|
+
if (!vfs.exists(pkgPath)) return null;
|
|
355
|
+
const raw = textDecoder.decode(vfs.readFile(pkgPath));
|
|
203
356
|
const pkg = JSON.parse(raw);
|
|
204
357
|
const main = pkg.main || pkg.module || "index.js";
|
|
205
358
|
return resolveModule(vfs, "./" + main, dirPath);
|
|
@@ -211,8 +364,8 @@ function tryIndexFile(vfs, dirPath) {
|
|
|
211
364
|
for (const name of ["index.js", "index.ts", "index.mjs", "index.json"]) {
|
|
212
365
|
const fullPath = dirPath + "/" + name;
|
|
213
366
|
try {
|
|
214
|
-
if (!vfs.
|
|
215
|
-
const source = textDecoder.decode(vfs.
|
|
367
|
+
if (!vfs.exists(fullPath)) continue;
|
|
368
|
+
const source = textDecoder.decode(vfs.readFile(fullPath));
|
|
216
369
|
return { path: fullPath, source };
|
|
217
370
|
} catch {
|
|
218
371
|
continue;
|
|
@@ -230,20 +383,458 @@ function normalizePath(p) {
|
|
|
230
383
|
return (p.startsWith("/") ? "/" : "") + result.join("/");
|
|
231
384
|
}
|
|
232
385
|
|
|
386
|
+
// src/transformer.ts
|
|
387
|
+
var CJS_WRAPPER_PARAMS = /* @__PURE__ */ new Set([
|
|
388
|
+
"exports",
|
|
389
|
+
"require",
|
|
390
|
+
"module",
|
|
391
|
+
"__filename",
|
|
392
|
+
"__dirname",
|
|
393
|
+
"console",
|
|
394
|
+
"process",
|
|
395
|
+
"Buffer",
|
|
396
|
+
"setTimeout",
|
|
397
|
+
"setInterval",
|
|
398
|
+
"clearTimeout",
|
|
399
|
+
"clearInterval",
|
|
400
|
+
"global",
|
|
401
|
+
"__importMetaUrl",
|
|
402
|
+
"__importMeta",
|
|
403
|
+
"__importMetaResolve"
|
|
404
|
+
]);
|
|
405
|
+
function cjsDecl(name) {
|
|
406
|
+
return CJS_WRAPPER_PARAMS.has(name) ? "var" : "const";
|
|
407
|
+
}
|
|
408
|
+
function dirname(p) {
|
|
409
|
+
const idx = p.lastIndexOf("/");
|
|
410
|
+
if (idx === -1) return ".";
|
|
411
|
+
if (idx === 0) return "/";
|
|
412
|
+
return p.slice(0, idx);
|
|
413
|
+
}
|
|
414
|
+
function join(...parts) {
|
|
415
|
+
const joined = parts.join("/").replace(/\/+/g, "/");
|
|
416
|
+
return normalize(joined);
|
|
417
|
+
}
|
|
418
|
+
function extname(p) {
|
|
419
|
+
const base = p.slice(p.lastIndexOf("/") + 1);
|
|
420
|
+
const dot = base.lastIndexOf(".");
|
|
421
|
+
if (dot <= 0) return "";
|
|
422
|
+
return base.slice(dot);
|
|
423
|
+
}
|
|
424
|
+
function normalize(p) {
|
|
425
|
+
const parts = p.split("/");
|
|
426
|
+
const result = [];
|
|
427
|
+
for (const part of parts) {
|
|
428
|
+
if (part === "..") result.pop();
|
|
429
|
+
else if (part !== "." && part !== "") result.push(part);
|
|
430
|
+
}
|
|
431
|
+
return (p.startsWith("/") ? "/" : "") + result.join("/");
|
|
432
|
+
}
|
|
433
|
+
function maskStringLiterals(src) {
|
|
434
|
+
const literals = [];
|
|
435
|
+
let masked = "";
|
|
436
|
+
let i = 0;
|
|
437
|
+
while (i < src.length) {
|
|
438
|
+
const ch = src[i];
|
|
439
|
+
if (ch === "/" && i + 1 < src.length && src[i + 1] === "/") {
|
|
440
|
+
const nl = src.indexOf("\n", i);
|
|
441
|
+
const end = nl === -1 ? src.length : nl;
|
|
442
|
+
masked += src.slice(i, end);
|
|
443
|
+
i = end;
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (ch === "/" && i + 1 < src.length && src[i + 1] === "*") {
|
|
447
|
+
const end = src.indexOf("*/", i + 2);
|
|
448
|
+
const close = end === -1 ? src.length : end + 2;
|
|
449
|
+
masked += src.slice(i, close);
|
|
450
|
+
i = close;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (ch === "/" && i + 1 < src.length && src[i + 1] !== "/" && src[i + 1] !== "*") {
|
|
454
|
+
let k = i - 1;
|
|
455
|
+
while (k >= 0 && (src[k] === " " || src[k] === " " || src[k] === "\n" || src[k] === "\r")) k--;
|
|
456
|
+
const prev = k >= 0 ? src[k] : "\0";
|
|
457
|
+
if ("\0=([{,;!&|^~?:+-*%<>/)]}".includes(prev) || k >= 1 && /\b(?:return|typeof|void|delete|throw|new|case|of|in|yield|await)\s*$/.test(src.slice(Math.max(0, k - 11), k + 1))) {
|
|
458
|
+
const regStart = i;
|
|
459
|
+
i++;
|
|
460
|
+
while (i < src.length && src[i] !== "\n") {
|
|
461
|
+
if (src[i] === "\\") {
|
|
462
|
+
i += 2;
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
if (src[i] === "/") {
|
|
466
|
+
i++;
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
if (src[i] === "[") {
|
|
470
|
+
i++;
|
|
471
|
+
while (i < src.length && src[i] !== "]" && src[i] !== "\n") {
|
|
472
|
+
if (src[i] === "\\") i++;
|
|
473
|
+
i++;
|
|
474
|
+
}
|
|
475
|
+
if (i < src.length && src[i] === "]") i++;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
i++;
|
|
479
|
+
}
|
|
480
|
+
while (i < src.length && /[gimsuyv]/.test(src[i])) i++;
|
|
481
|
+
masked += src.slice(regStart, i);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
486
|
+
const start = i;
|
|
487
|
+
const quote = ch;
|
|
488
|
+
i++;
|
|
489
|
+
while (i < src.length) {
|
|
490
|
+
if (src[i] === "\\") {
|
|
491
|
+
i += 2;
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
if (src[i] === quote) {
|
|
495
|
+
i++;
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
if (quote === "`" && src[i] === "$" && i + 1 < src.length && src[i + 1] === "{") {
|
|
499
|
+
let depth = 1;
|
|
500
|
+
i += 2;
|
|
501
|
+
while (i < src.length && depth > 0) {
|
|
502
|
+
if (src[i] === "{") depth++;
|
|
503
|
+
else if (src[i] === "}") depth--;
|
|
504
|
+
else if (src[i] === "\\") i++;
|
|
505
|
+
else if (src[i] === "'" || src[i] === '"') {
|
|
506
|
+
const q = src[i];
|
|
507
|
+
i++;
|
|
508
|
+
while (i < src.length && src[i] !== q) {
|
|
509
|
+
if (src[i] === "\\") i++;
|
|
510
|
+
i++;
|
|
511
|
+
}
|
|
512
|
+
if (i < src.length) i++;
|
|
513
|
+
continue;
|
|
514
|
+
} else if (src[i] === "`") {
|
|
515
|
+
i++;
|
|
516
|
+
while (i < src.length && src[i] !== "`") {
|
|
517
|
+
if (src[i] === "\\") i++;
|
|
518
|
+
i++;
|
|
519
|
+
}
|
|
520
|
+
if (i < src.length) i++;
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
i++;
|
|
524
|
+
}
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
i++;
|
|
528
|
+
}
|
|
529
|
+
const literal = src.slice(start, i);
|
|
530
|
+
const idx = literals.length;
|
|
531
|
+
literals.push(literal);
|
|
532
|
+
masked += quote + "__LIFO_S" + idx + "__" + quote;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
masked += ch;
|
|
536
|
+
i++;
|
|
537
|
+
}
|
|
538
|
+
return { masked, literals };
|
|
539
|
+
}
|
|
540
|
+
function unmaskStringLiterals(src, literals) {
|
|
541
|
+
return src.replace(
|
|
542
|
+
/(['"`])__LIFO_S(\d+)__\1/g,
|
|
543
|
+
(_match, _quote, idxStr) => literals[parseInt(idxStr, 10)]
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
function isEsmSource(source) {
|
|
547
|
+
return /(?:^|\n|;)\s*(?:import\s*[\w{*('".]|export\s+|export\s*\{)/.test(source);
|
|
548
|
+
}
|
|
549
|
+
function shouldTreatAsEsm(source, filename, vfs) {
|
|
550
|
+
const ext = extname(filename);
|
|
551
|
+
if (ext === ".mjs") return true;
|
|
552
|
+
if (ext === ".cjs") return false;
|
|
553
|
+
if (vfs && ext === ".js") {
|
|
554
|
+
let dir = dirname(filename);
|
|
555
|
+
for (; ; ) {
|
|
556
|
+
const pkgPath = join(dir, "package.json");
|
|
557
|
+
if (vfs.exists(pkgPath)) {
|
|
558
|
+
try {
|
|
559
|
+
const pkg = JSON.parse(vfs.readFileString(pkgPath));
|
|
560
|
+
if (pkg.type === "module") return true;
|
|
561
|
+
if (pkg.type === "commonjs") return false;
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
const parent = dirname(dir);
|
|
567
|
+
if (parent === dir) break;
|
|
568
|
+
dir = parent;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
return isEsmSource(source);
|
|
572
|
+
}
|
|
573
|
+
function transformEsmToCjs(source) {
|
|
574
|
+
let result = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
575
|
+
result = result.split("import.meta.url").join("__importMetaUrl");
|
|
576
|
+
result = result.split("import.meta.dirname").join("__dirname");
|
|
577
|
+
result = result.split("import.meta.filename").join("__filename");
|
|
578
|
+
result = result.split("import.meta.require").join("require");
|
|
579
|
+
result = result.split("import.meta.resolve").join("__importMetaResolve");
|
|
580
|
+
result = result.split("import.meta").join("__importMeta");
|
|
581
|
+
const { masked, literals } = maskStringLiterals(result);
|
|
582
|
+
result = masked;
|
|
583
|
+
result = result.replace(
|
|
584
|
+
/;([ \t]*(?:import\s*[\w${*('".]|export[\s{*]))/g,
|
|
585
|
+
";\n$1"
|
|
586
|
+
);
|
|
587
|
+
const trailingExports = [];
|
|
588
|
+
let hasDefaultExport = false;
|
|
589
|
+
let hasNamedExport = false;
|
|
590
|
+
const importSources = /* @__PURE__ */ new Map();
|
|
591
|
+
hasDefaultExport = /(?:^|\n)\s*export\s+default\s+/.test(result);
|
|
592
|
+
hasNamedExport = /(?:^|\n)\s*export\s+(?:const|let|var|function|class|\{|\*\s+from)/.test(result);
|
|
593
|
+
result = result.replace(/^[ \t]*import\s+type\s+.*?from\s+(['"`]).*?\1[ \t]*;?$/gm, "");
|
|
594
|
+
result = result.replace(/^[ \t]*export\s+type\s+\{[^}]*\}(?:\s+from\s+(['"`]).*?\1)?[ \t]*;?$/gm, "");
|
|
595
|
+
result = result.replace(/^[ \t]*export\s+type\s+\*\s+from\s+(['"`]).*?\1[ \t]*;?$/gm, "");
|
|
596
|
+
result = result.replace(
|
|
597
|
+
/(?:^|\n)([ \t]*)import\s+([\w$]+)\s*,\s*\{([^}]+)\}\s*from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
598
|
+
(match, indent, defaultName, imports, mod) => {
|
|
599
|
+
if (imports.includes("${")) return match;
|
|
600
|
+
const tmp = "__mod_" + defaultName;
|
|
601
|
+
const mapped = imports.split(",").map((s) => {
|
|
602
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
603
|
+
const sourceProp = parts[0].trim();
|
|
604
|
+
const localName = parts.length === 2 ? parts[1].trim() : sourceProp;
|
|
605
|
+
if (localName) importSources.set(localName, { modRef: tmp, prop: sourceProp });
|
|
606
|
+
if (parts.length === 2) return `${sourceProp}: ${localName}`;
|
|
607
|
+
return sourceProp;
|
|
608
|
+
}).filter((s) => s).join(", ");
|
|
609
|
+
return `
|
|
610
|
+
${indent}${cjsDecl(tmp)} ${tmp} = require(${mod});
|
|
611
|
+
${indent}${cjsDecl(defaultName)} ${defaultName} = ${tmp}.default || ${tmp};
|
|
612
|
+
${indent}const { ${mapped} } = ${tmp};`;
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
result = result.replace(
|
|
616
|
+
/(?:^|\n)([ \t]*)import\s+([\w$]+)\s*,\s*\*\s*as\s+([\w$]+)\s+from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
617
|
+
(_match, indent, defaultName, nsName, mod) => {
|
|
618
|
+
return `
|
|
619
|
+
${indent}${cjsDecl(nsName)} ${nsName} = require(${mod});
|
|
620
|
+
${indent}${cjsDecl(defaultName)} ${defaultName} = ${nsName}.default || ${nsName};`;
|
|
621
|
+
}
|
|
622
|
+
);
|
|
623
|
+
result = result.replace(
|
|
624
|
+
/(?:^|\n)([ \t]*)import\s*\{([^}]+)\}\s*from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
625
|
+
(match, indent, imports, mod) => {
|
|
626
|
+
if (imports.includes("${")) return match;
|
|
627
|
+
const modRef = "__imp_" + Math.random().toString(36).slice(2, 8);
|
|
628
|
+
const mapped = imports.split(",").map((s) => {
|
|
629
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
630
|
+
const sourceProp = parts[0].trim();
|
|
631
|
+
const localName = parts.length === 2 ? parts[1].trim() : sourceProp;
|
|
632
|
+
if (localName) importSources.set(localName, { modRef, prop: sourceProp });
|
|
633
|
+
if (parts.length === 2) return `${sourceProp}: ${localName}`;
|
|
634
|
+
return sourceProp;
|
|
635
|
+
}).filter((s) => s).join(", ");
|
|
636
|
+
return `
|
|
637
|
+
${indent}const ${modRef} = require(${mod});
|
|
638
|
+
${indent}const { ${mapped} } = ${modRef};`;
|
|
639
|
+
}
|
|
640
|
+
);
|
|
641
|
+
result = result.replace(
|
|
642
|
+
/(?:^|\n)([ \t]*)import\s*\*\s*as\s+([\w$]+)\s+from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
643
|
+
(_match, indent, name, mod) => `
|
|
644
|
+
${indent}${cjsDecl(name)} ${name} = require(${mod});`
|
|
645
|
+
);
|
|
646
|
+
result = result.replace(
|
|
647
|
+
/(?:^|\n)([ \t]*)import\s+([\w$]+)\s+from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
648
|
+
(_match, indent, name, mod) => `
|
|
649
|
+
${indent}${cjsDecl(name)} ${name} = require(${mod});`
|
|
650
|
+
);
|
|
651
|
+
result = result.replace(
|
|
652
|
+
/(?:^|\n)([ \t]*)import\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
653
|
+
(_match, indent, mod) => `
|
|
654
|
+
${indent}require(${mod});`
|
|
655
|
+
);
|
|
656
|
+
result = result.replace(/(?:^|\n)[ \t]*export\s*\{\s*\}[ \t]*;?/g, "");
|
|
657
|
+
result = result.replace(
|
|
658
|
+
/(?:^|\n)([ \t]*)export\s*\*\s*from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
659
|
+
(_match, indent, mod) => {
|
|
660
|
+
const tmpVar = "__star_" + Math.random().toString(36).slice(2, 8);
|
|
661
|
+
return `
|
|
662
|
+
${indent}const ${tmpVar} = require(${mod});
|
|
663
|
+
${indent}Object.keys(${tmpVar}).forEach(function(k) { if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, { get: function() { return ${tmpVar}[k]; }, enumerable: true, configurable: true }); });`;
|
|
664
|
+
}
|
|
665
|
+
);
|
|
666
|
+
result = result.replace(
|
|
667
|
+
/(?:^|\n)([ \t]*)export\s*\{([^}]+)\}\s*from\s*(['"][^'"]+['"])[ \t]*;?/g,
|
|
668
|
+
(match, indent, names, mod) => {
|
|
669
|
+
if (names.includes("${")) return match;
|
|
670
|
+
const tmpVar = "__re_" + Math.random().toString(36).slice(2, 8);
|
|
671
|
+
const assignments = names.split(",").map((s) => {
|
|
672
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
673
|
+
const local = parts[0].trim();
|
|
674
|
+
const exported = parts.length === 2 ? parts[1].trim() : local;
|
|
675
|
+
return `${indent}Object.defineProperty(exports, '${exported}', { get() { return ${tmpVar}.${local}; }, enumerable: true, configurable: true });`;
|
|
676
|
+
}).join("\n");
|
|
677
|
+
return `
|
|
678
|
+
${indent}const ${tmpVar} = require(${mod});
|
|
679
|
+
${assignments}`;
|
|
680
|
+
}
|
|
681
|
+
);
|
|
682
|
+
if (hasDefaultExport && hasNamedExport) {
|
|
683
|
+
result = result.replace(
|
|
684
|
+
/(?:^|\n)([ \t]*)export\s+default\s+/g,
|
|
685
|
+
(_match, indent) => `
|
|
686
|
+
${indent}exports.default = `
|
|
687
|
+
);
|
|
688
|
+
} else {
|
|
689
|
+
result = result.replace(
|
|
690
|
+
/(?:^|\n)([ \t]*)export\s+default\s+/g,
|
|
691
|
+
(_match, indent) => `
|
|
692
|
+
${indent}module.exports = `
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
result = result.replace(
|
|
696
|
+
/(?:^|\n)([ \t]*)export\s+(const|let|var)\s+([\w$]+)\s*=/g,
|
|
697
|
+
(match, indent, keyword, name) => {
|
|
698
|
+
if (match.includes("${")) return match;
|
|
699
|
+
return `
|
|
700
|
+
${indent}${keyword} ${name} = exports.${name} =`;
|
|
701
|
+
}
|
|
702
|
+
);
|
|
703
|
+
result = result.replace(
|
|
704
|
+
/(?:^|\n)([ \t]*)export\s+(async\s+function\s+([\w$]+)|function\s+([\w$]+)|class\s+([\w$]+))/g,
|
|
705
|
+
(match, indent, decl, asyncFnName, fnName, className, offset) => {
|
|
706
|
+
const nextChar = result.charAt(offset + match.length);
|
|
707
|
+
if (nextChar === "{") return match;
|
|
708
|
+
const name = asyncFnName || fnName || className;
|
|
709
|
+
trailingExports.push(`exports.${name} = ${name};`);
|
|
710
|
+
return `
|
|
711
|
+
${indent}${decl}`;
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
result = result.replace(
|
|
715
|
+
/(?:^|\n)([ \t]*)export\s*\{([^}]+)\}[ \t]*;?/g,
|
|
716
|
+
(match, _indent, names) => {
|
|
717
|
+
if (names.includes("${")) return match;
|
|
718
|
+
names.split(",").forEach((s) => {
|
|
719
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
720
|
+
const local = parts[0].trim();
|
|
721
|
+
const exported = parts.length === 2 ? parts[1].trim() : local;
|
|
722
|
+
if (!local) return;
|
|
723
|
+
const src = importSources.get(local);
|
|
724
|
+
if (src) {
|
|
725
|
+
trailingExports.push(`Object.defineProperty(exports, '${exported}', { get: function() { return ${src.modRef}.${src.prop}; }, enumerable: true, configurable: true });`);
|
|
726
|
+
} else {
|
|
727
|
+
trailingExports.push(`exports.${exported} = ${local};`);
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
return "";
|
|
731
|
+
}
|
|
732
|
+
);
|
|
733
|
+
result = result.replace(
|
|
734
|
+
/(?<!\.)(?<!\w)\bimport\s*\(\s*(['"][^'"]+['"])\s*\)/g,
|
|
735
|
+
(_match, mod) => `Promise.resolve(require(${mod}))`
|
|
736
|
+
);
|
|
737
|
+
{
|
|
738
|
+
let i = 0;
|
|
739
|
+
let out = "";
|
|
740
|
+
while (i < result.length) {
|
|
741
|
+
const importIdx = result.indexOf("import(", i);
|
|
742
|
+
if (importIdx === -1) {
|
|
743
|
+
out += result.slice(i);
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
if (importIdx > 0 && /[\w$.]/.test(result[importIdx - 1])) {
|
|
747
|
+
out += result.slice(i, importIdx + 7);
|
|
748
|
+
i = importIdx + 7;
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
{
|
|
752
|
+
let depth2 = 1;
|
|
753
|
+
let k = importIdx + 7;
|
|
754
|
+
while (k < result.length && depth2 > 0) {
|
|
755
|
+
if (result[k] === "(") depth2++;
|
|
756
|
+
else if (result[k] === ")") depth2--;
|
|
757
|
+
k++;
|
|
758
|
+
}
|
|
759
|
+
if (depth2 === 0) {
|
|
760
|
+
let afterClose = k;
|
|
761
|
+
while (afterClose < result.length && /[ \t]/.test(result[afterClose])) afterClose++;
|
|
762
|
+
if (result[afterClose] === "{") {
|
|
763
|
+
out += result.slice(i, importIdx + 7);
|
|
764
|
+
i = importIdx + 7;
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
out += result.slice(i, importIdx);
|
|
770
|
+
let depth = 1;
|
|
771
|
+
let j = importIdx + 7;
|
|
772
|
+
while (j < result.length && depth > 0) {
|
|
773
|
+
if (result[j] === "(") depth++;
|
|
774
|
+
else if (result[j] === ")") depth--;
|
|
775
|
+
j++;
|
|
776
|
+
}
|
|
777
|
+
if (depth === 0) {
|
|
778
|
+
const arg = result.slice(importIdx + 7, j - 1);
|
|
779
|
+
out += `Promise.resolve().then(function() { return require(${arg}); })`;
|
|
780
|
+
} else {
|
|
781
|
+
out += result.slice(importIdx, j);
|
|
782
|
+
}
|
|
783
|
+
i = j;
|
|
784
|
+
}
|
|
785
|
+
result = out;
|
|
786
|
+
}
|
|
787
|
+
result = result.replace(
|
|
788
|
+
/\b(const|let)\s+(__dirname|__filename|exports|require|module|console|process|Buffer|global)\b/g,
|
|
789
|
+
(_match, _kw, name) => `var ${name}`
|
|
790
|
+
);
|
|
791
|
+
if (trailingExports.length > 0) {
|
|
792
|
+
result += "\n" + trailingExports.join("\n");
|
|
793
|
+
}
|
|
794
|
+
result = unmaskStringLiterals(result, literals);
|
|
795
|
+
return result;
|
|
796
|
+
}
|
|
797
|
+
function transformToCjs(source, filename, vfs) {
|
|
798
|
+
if (shouldTreatAsEsm(source, filename, vfs)) {
|
|
799
|
+
return { code: transformEsmToCjs(source), wasEsm: true };
|
|
800
|
+
}
|
|
801
|
+
return { code: source, wasEsm: false };
|
|
802
|
+
}
|
|
803
|
+
|
|
233
804
|
// src/runner.ts
|
|
234
805
|
var textEncoder = new TextEncoder();
|
|
806
|
+
function stripShebang(src) {
|
|
807
|
+
if (src.charCodeAt(0) === 35 && src.charCodeAt(1) === 33) {
|
|
808
|
+
const nl = src.indexOf("\n");
|
|
809
|
+
if (nl === -1) return "";
|
|
810
|
+
return "\n" + src.slice(nl + 1);
|
|
811
|
+
}
|
|
812
|
+
return src;
|
|
813
|
+
}
|
|
235
814
|
var NodeRunner = class {
|
|
236
815
|
vfs;
|
|
816
|
+
moduleMapFactory;
|
|
237
817
|
nodeCompat;
|
|
238
818
|
env;
|
|
239
819
|
cwd;
|
|
240
820
|
argv;
|
|
821
|
+
stdout;
|
|
822
|
+
stderr;
|
|
823
|
+
signal;
|
|
824
|
+
globalShims;
|
|
825
|
+
/** Module cache from the last execution. Can be inspected by the caller. */
|
|
826
|
+
moduleCache = /* @__PURE__ */ new Map();
|
|
241
827
|
constructor(options) {
|
|
242
|
-
this.vfs = options.vfs ??
|
|
828
|
+
this.vfs = options.vfs ?? new import_vfs.VFS();
|
|
829
|
+
this.moduleMapFactory = options.moduleMap;
|
|
243
830
|
this.nodeCompat = options.nodeCompat;
|
|
244
831
|
this.env = options.env ?? {};
|
|
245
832
|
this.cwd = options.cwd ?? "/";
|
|
246
833
|
this.argv = options.argv ?? [];
|
|
834
|
+
this.stdout = options.stdout;
|
|
835
|
+
this.stderr = options.stderr;
|
|
836
|
+
this.signal = options.signal;
|
|
837
|
+
this.globalShims = options.globalShims;
|
|
247
838
|
if (options.files) {
|
|
248
839
|
this.writeFilesSync(options.files);
|
|
249
840
|
}
|
|
@@ -255,26 +846,16 @@ var NodeRunner = class {
|
|
|
255
846
|
for (let i = 1; i < parts.length; i++) {
|
|
256
847
|
const dir = "/" + parts.slice(0, i).join("/");
|
|
257
848
|
try {
|
|
258
|
-
this.vfs.
|
|
849
|
+
this.vfs.mkdir(dir);
|
|
259
850
|
} catch {
|
|
260
851
|
}
|
|
261
852
|
}
|
|
262
|
-
this.vfs.
|
|
853
|
+
this.vfs.writeFile(filePath, textEncoder.encode(content));
|
|
263
854
|
}
|
|
264
855
|
}
|
|
265
|
-
/** Write files to the VFS asynchronously (
|
|
856
|
+
/** Write files to the VFS asynchronously (for IndexedDB-backed VFS) */
|
|
266
857
|
async writeFiles(files) {
|
|
267
|
-
|
|
268
|
-
const parts = filePath.split("/").filter(Boolean);
|
|
269
|
-
for (let i = 1; i < parts.length; i++) {
|
|
270
|
-
const dir = "/" + parts.slice(0, i).join("/");
|
|
271
|
-
try {
|
|
272
|
-
await this.vfs.mkdir(dir);
|
|
273
|
-
} catch {
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
await this.vfs.writeFile(filePath, textEncoder.encode(content));
|
|
277
|
-
}
|
|
858
|
+
this.writeFilesSync(files);
|
|
278
859
|
}
|
|
279
860
|
/** Run a script file from the VFS, resolving extensions and index files */
|
|
280
861
|
async runFile(filePath) {
|
|
@@ -283,10 +864,14 @@ var NodeRunner = class {
|
|
|
283
864
|
const id = absPath.startsWith("/") ? absPath : "./" + absPath;
|
|
284
865
|
const resolved = resolveModule(this.vfs, id, scriptDir);
|
|
285
866
|
if (!resolved) {
|
|
867
|
+
const msg = `Error: ENOENT: no such file or directory, open '${absPath}'`;
|
|
868
|
+
if (this.stderr) {
|
|
869
|
+
this.stderr.write(msg + "\n");
|
|
870
|
+
}
|
|
286
871
|
return {
|
|
287
872
|
exitCode: 1,
|
|
288
873
|
stdout: "",
|
|
289
|
-
stderr:
|
|
874
|
+
stderr: this.stderr ? "" : msg
|
|
290
875
|
};
|
|
291
876
|
}
|
|
292
877
|
return this.execute(resolved.source, resolved.path);
|
|
@@ -301,117 +886,349 @@ var NodeRunner = class {
|
|
|
301
886
|
this.writeFilesSync({ [filePath]: source });
|
|
302
887
|
return this.runFile(filePath);
|
|
303
888
|
}
|
|
304
|
-
execute(source, absPath) {
|
|
889
|
+
async execute(source, absPath) {
|
|
890
|
+
this.moduleCache.clear();
|
|
305
891
|
const stdoutLines = [];
|
|
306
892
|
const stderrLines = [];
|
|
307
|
-
const scriptConsole =
|
|
308
|
-
const
|
|
309
|
-
|
|
893
|
+
const scriptConsole = this.stdout && this.stderr ? createStreamConsole(this.stdout, this.stderr) : this.stdout ? createStreamConsole(this.stdout, { write: (s) => stderrLines.push(s) }) : this.stderr ? createStreamConsole({ write: (s) => stdoutLines.push(s) }, this.stderr) : createCaptureConsole(stdoutLines, stderrLines);
|
|
894
|
+
const isStreaming = !!(this.stdout || this.stderr);
|
|
895
|
+
let getBuiltin;
|
|
896
|
+
if (this.moduleMapFactory) {
|
|
897
|
+
const moduleMap = this.moduleMapFactory;
|
|
898
|
+
getBuiltin = (id) => {
|
|
899
|
+
const name = id.startsWith("node:") ? id.slice(5) : id;
|
|
900
|
+
if (name in moduleMap) {
|
|
901
|
+
if (this.moduleCache.has(name)) return this.moduleCache.get(name);
|
|
902
|
+
const mod = moduleMap[name]();
|
|
903
|
+
this.moduleCache.set(name, mod);
|
|
904
|
+
return mod;
|
|
905
|
+
}
|
|
906
|
+
return void 0;
|
|
907
|
+
};
|
|
908
|
+
} else {
|
|
909
|
+
const builtins = createBuiltinModules(
|
|
910
|
+
this.vfs,
|
|
911
|
+
this.env,
|
|
912
|
+
this.cwd,
|
|
913
|
+
[absPath, ...this.argv],
|
|
914
|
+
scriptConsole,
|
|
915
|
+
this.nodeCompat,
|
|
916
|
+
this.stdout,
|
|
917
|
+
this.stderr
|
|
918
|
+
);
|
|
919
|
+
getBuiltin = (id) => {
|
|
920
|
+
const name = id.startsWith("node:") ? id.slice(5) : id;
|
|
921
|
+
return builtins.has(name) ? builtins.get(name) : void 0;
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
const processObj = getBuiltin("process") ?? createMinimalProcess(
|
|
310
925
|
this.env,
|
|
311
926
|
this.cwd,
|
|
312
927
|
[absPath, ...this.argv],
|
|
313
|
-
|
|
314
|
-
this.
|
|
928
|
+
this.stdout,
|
|
929
|
+
this.stderr
|
|
315
930
|
);
|
|
316
|
-
const
|
|
931
|
+
const bufferObj = getBuiltin("buffer");
|
|
932
|
+
const BufferClass = bufferObj && typeof bufferObj === "object" && "Buffer" in bufferObj ? bufferObj.Buffer : void 0;
|
|
933
|
+
const pObj = processObj;
|
|
934
|
+
if (pObj.stdout && typeof pObj.stdout === "object") {
|
|
935
|
+
const pStdout = pObj.stdout;
|
|
936
|
+
if (this.stdout) {
|
|
937
|
+
pStdout.write = (s) => {
|
|
938
|
+
this.stdout.write(String(s));
|
|
939
|
+
return true;
|
|
940
|
+
};
|
|
941
|
+
} else {
|
|
942
|
+
pStdout.write = (s) => {
|
|
943
|
+
stdoutLines.push(String(s));
|
|
944
|
+
return true;
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (pObj.stderr && typeof pObj.stderr === "object") {
|
|
949
|
+
const pStderr = pObj.stderr;
|
|
950
|
+
if (this.stderr) {
|
|
951
|
+
pStderr.write = (s) => {
|
|
952
|
+
this.stderr.write(String(s));
|
|
953
|
+
return true;
|
|
954
|
+
};
|
|
955
|
+
} else {
|
|
956
|
+
pStderr.write = (s) => {
|
|
957
|
+
stderrLines.push(String(s));
|
|
958
|
+
return true;
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
const self = this;
|
|
317
963
|
const createRequire = (fromDir) => {
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
const
|
|
964
|
+
const require3 = (id) => {
|
|
965
|
+
const name = id.startsWith("node:") ? id.slice(5) : id;
|
|
966
|
+
const builtin = getBuiltin(name);
|
|
967
|
+
if (builtin !== void 0) return builtin;
|
|
968
|
+
const resolved = resolveModule(self.vfs, id, fromDir);
|
|
321
969
|
if (!resolved) {
|
|
322
970
|
throw new Error(`Cannot find module '${id}'`);
|
|
323
971
|
}
|
|
324
|
-
if (moduleCache.has(resolved.path)) {
|
|
325
|
-
return moduleCache.get(resolved.path);
|
|
972
|
+
if (self.moduleCache.has(resolved.path)) {
|
|
973
|
+
return self.moduleCache.get(resolved.path);
|
|
326
974
|
}
|
|
327
975
|
if (resolved.path.endsWith(".json")) {
|
|
328
976
|
const json = JSON.parse(resolved.source);
|
|
329
|
-
moduleCache.set(resolved.path, json);
|
|
977
|
+
self.moduleCache.set(resolved.path, json);
|
|
330
978
|
return json;
|
|
331
979
|
}
|
|
332
|
-
const
|
|
333
|
-
const
|
|
334
|
-
moduleCache.set(resolved.path,
|
|
335
|
-
const moduleDir = resolved.path.slice(
|
|
336
|
-
0,
|
|
337
|
-
resolved.path.lastIndexOf("/")
|
|
338
|
-
);
|
|
980
|
+
const moduleExports2 = {};
|
|
981
|
+
const moduleObj2 = { exports: moduleExports2 };
|
|
982
|
+
self.moduleCache.set(resolved.path, moduleExports2);
|
|
983
|
+
const moduleDir = resolved.path.slice(0, resolved.path.lastIndexOf("/"));
|
|
339
984
|
const childRequire = createRequire(moduleDir);
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
985
|
+
let cleanSource = stripShebang(resolved.source);
|
|
986
|
+
const { code: cjsSource } = transformToCjs(cleanSource, resolved.path, self.vfs);
|
|
987
|
+
cleanSource = cjsSource;
|
|
988
|
+
const factory = compileModule(cleanSource, resolved.path, self.stderr);
|
|
989
|
+
const importMetaUrl = "file://" + resolved.path;
|
|
990
|
+
const importMeta = { url: importMetaUrl, dirname: moduleDir, filename: resolved.path };
|
|
991
|
+
const importMetaResolve = (specifier) => {
|
|
992
|
+
throw new Error(`import.meta.resolve('${specifier}') is not supported`);
|
|
993
|
+
};
|
|
994
|
+
const global2 = { process: processObj, Buffer: BufferClass, console: scriptConsole };
|
|
995
|
+
const ga2 = globalThis;
|
|
996
|
+
const isRealNode2 = typeof ga2.process?.pid === "number";
|
|
997
|
+
const saved2 = {};
|
|
998
|
+
if (!isRealNode2) {
|
|
999
|
+
saved2.process = ga2.process;
|
|
1000
|
+
ga2.process = processObj;
|
|
1001
|
+
saved2.Buffer = ga2.Buffer;
|
|
1002
|
+
if (BufferClass) ga2.Buffer = BufferClass;
|
|
1003
|
+
saved2.console = ga2.console;
|
|
1004
|
+
ga2.console = scriptConsole;
|
|
1005
|
+
}
|
|
1006
|
+
const savedShims2 = {};
|
|
1007
|
+
if (self.globalShims) {
|
|
1008
|
+
for (const k of Object.keys(self.globalShims)) {
|
|
1009
|
+
savedShims2[k] = ga2[k];
|
|
1010
|
+
ga2[k] = self.globalShims[k];
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
try {
|
|
1014
|
+
factory(
|
|
1015
|
+
moduleObj2.exports,
|
|
1016
|
+
childRequire,
|
|
1017
|
+
moduleObj2,
|
|
1018
|
+
resolved.path,
|
|
1019
|
+
moduleDir,
|
|
1020
|
+
scriptConsole,
|
|
1021
|
+
processObj,
|
|
1022
|
+
BufferClass,
|
|
1023
|
+
globalThis.setTimeout,
|
|
1024
|
+
globalThis.setInterval,
|
|
1025
|
+
globalThis.clearTimeout,
|
|
1026
|
+
globalThis.clearInterval,
|
|
1027
|
+
global2,
|
|
1028
|
+
importMetaUrl,
|
|
1029
|
+
importMeta,
|
|
1030
|
+
importMetaResolve
|
|
1031
|
+
);
|
|
1032
|
+
} catch (e) {
|
|
1033
|
+
if (e instanceof ProcessExitError) throw e;
|
|
1034
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
1035
|
+
if (!err.message.includes("[/")) {
|
|
1036
|
+
err.message = `[${resolved.path}] ${err.message}`;
|
|
1037
|
+
}
|
|
1038
|
+
throw err;
|
|
1039
|
+
} finally {
|
|
1040
|
+
if (self.globalShims) {
|
|
1041
|
+
for (const k of Object.keys(savedShims2)) ga2[k] = savedShims2[k];
|
|
1042
|
+
}
|
|
1043
|
+
if (!isRealNode2) {
|
|
1044
|
+
ga2.process = saved2.process;
|
|
1045
|
+
ga2.Buffer = saved2.Buffer;
|
|
1046
|
+
ga2.console = saved2.console;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
if (moduleObj2.exports !== moduleExports2) {
|
|
1050
|
+
self.moduleCache.set(resolved.path, moduleObj2.exports);
|
|
1051
|
+
}
|
|
1052
|
+
return moduleObj2.exports;
|
|
352
1053
|
};
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
1054
|
+
require3.resolve = (id) => {
|
|
1055
|
+
const name = id.startsWith("node:") ? id.slice(5) : id;
|
|
1056
|
+
if (getBuiltin(name) !== void 0) return id;
|
|
1057
|
+
const resolved = resolveModule(self.vfs, id, fromDir);
|
|
356
1058
|
if (!resolved) throw new Error(`Cannot find module '${id}'`);
|
|
357
1059
|
return resolved.path;
|
|
358
1060
|
};
|
|
359
|
-
return
|
|
1061
|
+
return require3;
|
|
360
1062
|
};
|
|
1063
|
+
if (this.moduleMapFactory) {
|
|
1064
|
+
const moduleMap = this.moduleMapFactory;
|
|
1065
|
+
moduleMap.module = () => {
|
|
1066
|
+
const makeCreateRequire = (_filename) => {
|
|
1067
|
+
const dir = typeof _filename === "string" ? _filename.slice(0, _filename.lastIndexOf("/")) || "/" : "/";
|
|
1068
|
+
return createRequire(dir);
|
|
1069
|
+
};
|
|
1070
|
+
const builtinNames = Object.keys(moduleMap);
|
|
1071
|
+
const isBuiltin = (s) => {
|
|
1072
|
+
const n = s.startsWith("node:") ? s.slice(5) : s;
|
|
1073
|
+
return builtinNames.includes(n);
|
|
1074
|
+
};
|
|
1075
|
+
return { createRequire: makeCreateRequire, builtinModules: builtinNames, isBuiltin, default: { createRequire: makeCreateRequire } };
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
361
1078
|
let exitCode = 0;
|
|
1079
|
+
let cleanMainSource = stripShebang(source);
|
|
1080
|
+
const { code: cjsMainSource, wasEsm: isEsm } = transformToCjs(cleanMainSource, absPath, this.vfs);
|
|
1081
|
+
cleanMainSource = cjsMainSource;
|
|
1082
|
+
const wrapped = isEsm ? `(async function(exports, require, module, __filename, __dirname, console, process, Buffer, setTimeout, setInterval, clearTimeout, clearInterval, global, __importMetaUrl, __importMeta, __importMetaResolve) {
|
|
1083
|
+
${cleanMainSource}
|
|
1084
|
+
})` : `(function(exports, require, module, __filename, __dirname, console, process, Buffer, setTimeout, setInterval, clearTimeout, clearInterval, global, __importMetaUrl, __importMeta, __importMetaResolve) {
|
|
1085
|
+
${cleanMainSource}
|
|
1086
|
+
})`;
|
|
1087
|
+
const scriptDir = absPath.slice(0, absPath.lastIndexOf("/")) || "/";
|
|
1088
|
+
const require2 = createRequire(scriptDir);
|
|
1089
|
+
const moduleExports = {};
|
|
1090
|
+
const moduleObj = { exports: moduleExports };
|
|
1091
|
+
const global = { process: processObj, Buffer: BufferClass, console: scriptConsole };
|
|
1092
|
+
const mainImportMetaUrl = "file://" + absPath;
|
|
1093
|
+
const mainImportMeta = { url: mainImportMetaUrl, dirname: scriptDir, filename: absPath };
|
|
1094
|
+
const mainImportMetaResolve = (specifier) => {
|
|
1095
|
+
throw new Error(`import.meta.resolve('${specifier}') is not supported`);
|
|
1096
|
+
};
|
|
1097
|
+
const ga = globalThis;
|
|
1098
|
+
const isRealNode = typeof ga.process?.pid === "number";
|
|
1099
|
+
const saved = {};
|
|
1100
|
+
if (!isRealNode) {
|
|
1101
|
+
saved.process = ga.process;
|
|
1102
|
+
ga.process = processObj;
|
|
1103
|
+
saved.Buffer = ga.Buffer;
|
|
1104
|
+
if (BufferClass) ga.Buffer = BufferClass;
|
|
1105
|
+
saved.console = ga.console;
|
|
1106
|
+
ga.console = scriptConsole;
|
|
1107
|
+
}
|
|
1108
|
+
const savedShims = {};
|
|
1109
|
+
if (this.globalShims) {
|
|
1110
|
+
for (const k of Object.keys(this.globalShims)) {
|
|
1111
|
+
savedShims[k] = ga[k];
|
|
1112
|
+
ga[k] = this.globalShims[k];
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
let pendingRejection = null;
|
|
1116
|
+
const rejectionHandler = (event) => {
|
|
1117
|
+
pendingRejection = event.reason;
|
|
1118
|
+
event.preventDefault();
|
|
1119
|
+
const msg = event.reason instanceof Error ? event.reason.stack || event.reason.message : String(event.reason);
|
|
1120
|
+
const errMsg = `[unhandledRejection] ${msg}
|
|
1121
|
+
`;
|
|
1122
|
+
if (this.stderr) this.stderr.write(errMsg);
|
|
1123
|
+
else stderrLines.push(errMsg);
|
|
1124
|
+
};
|
|
1125
|
+
if (typeof globalThis.addEventListener === "function") {
|
|
1126
|
+
globalThis.addEventListener("unhandledrejection", rejectionHandler);
|
|
1127
|
+
}
|
|
362
1128
|
try {
|
|
363
|
-
const
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
|
|
1129
|
+
const fn = new Function("return " + wrapped)();
|
|
1130
|
+
const result = fn(
|
|
1131
|
+
moduleExports,
|
|
1132
|
+
require2,
|
|
1133
|
+
moduleObj,
|
|
1134
|
+
absPath,
|
|
1135
|
+
scriptDir,
|
|
1136
|
+
scriptConsole,
|
|
1137
|
+
processObj,
|
|
1138
|
+
BufferClass,
|
|
1139
|
+
globalThis.setTimeout,
|
|
1140
|
+
globalThis.setInterval,
|
|
1141
|
+
globalThis.clearTimeout,
|
|
1142
|
+
globalThis.clearInterval,
|
|
1143
|
+
global,
|
|
1144
|
+
mainImportMetaUrl,
|
|
1145
|
+
mainImportMeta,
|
|
1146
|
+
mainImportMetaResolve
|
|
1147
|
+
);
|
|
1148
|
+
if (isEsm && result && typeof result.then === "function") {
|
|
1149
|
+
await result;
|
|
1150
|
+
}
|
|
1151
|
+
if (pendingRejection) {
|
|
1152
|
+
if (pendingRejection instanceof ProcessExitError) {
|
|
1153
|
+
exitCode = pendingRejection.code;
|
|
1154
|
+
} else {
|
|
1155
|
+
exitCode = 1;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
} catch (e) {
|
|
1159
|
+
if (e instanceof ProcessExitError) {
|
|
1160
|
+
exitCode = e.code;
|
|
387
1161
|
} else {
|
|
388
1162
|
exitCode = 1;
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
1163
|
+
const msg = e instanceof Error ? e.stack || e.message : String(e);
|
|
1164
|
+
if (this.stderr) {
|
|
1165
|
+
this.stderr.write(msg + "\n");
|
|
1166
|
+
} else {
|
|
1167
|
+
stderrLines.push(msg);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
} finally {
|
|
1171
|
+
if (this.globalShims) {
|
|
1172
|
+
for (const k of Object.keys(savedShims)) ga[k] = savedShims[k];
|
|
1173
|
+
}
|
|
1174
|
+
if (!isRealNode) {
|
|
1175
|
+
ga.process = saved.process;
|
|
1176
|
+
ga.Buffer = saved.Buffer;
|
|
1177
|
+
ga.console = saved.console;
|
|
1178
|
+
}
|
|
1179
|
+
if (typeof globalThis.removeEventListener === "function") {
|
|
1180
|
+
globalThis.removeEventListener("unhandledrejection", rejectionHandler);
|
|
392
1181
|
}
|
|
393
1182
|
}
|
|
394
1183
|
return {
|
|
395
1184
|
exitCode,
|
|
396
|
-
stdout: stdoutLines.join("\n"),
|
|
397
|
-
stderr: stderrLines.join("\n")
|
|
1185
|
+
stdout: isStreaming ? "" : stdoutLines.join("\n"),
|
|
1186
|
+
stderr: isStreaming ? "" : stderrLines.join("\n")
|
|
398
1187
|
};
|
|
399
1188
|
}
|
|
400
1189
|
};
|
|
401
|
-
function compileModule(source, filename) {
|
|
402
|
-
const wrapped = `(function(exports, require, module, __filename, __dirname, console, process) {
|
|
1190
|
+
function compileModule(source, filename, stderr) {
|
|
1191
|
+
const wrapped = `(function(exports, require, module, __filename, __dirname, console, process, Buffer, setTimeout, setInterval, clearTimeout, clearInterval, global, __importMetaUrl, __importMeta, __importMetaResolve) {
|
|
403
1192
|
${source}
|
|
404
1193
|
})`;
|
|
405
1194
|
try {
|
|
406
1195
|
return (0, eval)(wrapped);
|
|
407
1196
|
} catch (err) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
)
|
|
1197
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1198
|
+
const msg = `Failed to compile '${filename}': ${errMsg}`;
|
|
1199
|
+
if (stderr) {
|
|
1200
|
+
stderr.write(`[CJS-FAIL] file=${filename} srcLen=${source.length} err=${errMsg}
|
|
1201
|
+
`);
|
|
1202
|
+
const lines = source.split("\n");
|
|
1203
|
+
let lo = 0, hi = lines.length;
|
|
1204
|
+
while (hi - lo > 3) {
|
|
1205
|
+
const mid = lo + hi >>> 1;
|
|
1206
|
+
const partial = lines.slice(0, mid).join("\n");
|
|
1207
|
+
try {
|
|
1208
|
+
new Function(partial);
|
|
1209
|
+
lo = mid;
|
|
1210
|
+
} catch (e2) {
|
|
1211
|
+
if (e2 instanceof Error && e2.message === errMsg) hi = mid;
|
|
1212
|
+
else lo = mid;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
stderr.write(`[CJS-FAIL] error at L${lo}-${hi}, showing L${Math.max(1, lo - 25)} to L${hi + 3}:
|
|
1216
|
+
`);
|
|
1217
|
+
for (let li = Math.max(0, lo - 25); li < Math.min(lines.length, hi + 3); li++) {
|
|
1218
|
+
stderr.write(`[CJS-FAIL] ${li + 1 === lo || li + 1 === hi ? ">>>" : " "} L${li + 1}: ${lines[li]?.slice(0, 200)}
|
|
1219
|
+
`);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
throw new SyntaxError(msg);
|
|
411
1223
|
}
|
|
412
1224
|
}
|
|
413
1225
|
// Annotate the CommonJS export names for ESM import in node:
|
|
414
1226
|
0 && (module.exports = {
|
|
415
|
-
NodeRunner
|
|
1227
|
+
NodeRunner,
|
|
1228
|
+
ProcessExitError,
|
|
1229
|
+
resolveModule,
|
|
1230
|
+
shouldTreatAsEsm,
|
|
1231
|
+
transformEsmToCjs,
|
|
1232
|
+
transformToCjs
|
|
416
1233
|
});
|
|
417
1234
|
//# sourceMappingURL=index.cjs.map
|