env-runner 0.2.3 → 0.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.
Files changed (33) hide show
  1. package/README.md +370 -20
  2. package/dist/_chunks/common-base-runner.d.mts +486 -15
  3. package/dist/_chunks/common-base-runner.mjs +712 -32
  4. package/dist/_chunks/common-process-data.mjs +13 -0
  5. package/dist/_chunks/common-worker-utils.mjs +47 -114
  6. package/dist/_chunks/deno-process-runner.d.mts +4 -1
  7. package/dist/_chunks/deno-process-runner.mjs +9 -6
  8. package/dist/_chunks/lexer.mjs +2 -0
  9. package/dist/_chunks/libs/cjs-module-lexer.mjs +6 -1
  10. package/dist/_chunks/miniflare-runner.d.mts +26 -14
  11. package/dist/_chunks/miniflare-runner.mjs +430 -134
  12. package/dist/_chunks/netlify-runner.d.mts +3 -1
  13. package/dist/_chunks/node-worker-runner.d.mts +3 -1
  14. package/dist/_chunks/node-worker-runner.mjs +8 -4
  15. package/dist/_chunks/plugin-hooks.mjs +1656 -0
  16. package/dist/_chunks/server.mjs +21 -5
  17. package/dist/_chunks/types.d.mts +37 -1
  18. package/dist/_chunks/vercel-runner.d.mts +3 -1
  19. package/dist/cli.mjs +0 -0
  20. package/dist/index.d.mts +21 -4
  21. package/dist/runners/bun-process/runner.d.mts +4 -1
  22. package/dist/runners/bun-process/runner.mjs +12 -9
  23. package/dist/runners/bun-process/worker.mjs +12 -11
  24. package/dist/runners/deno-process/worker.mjs +12 -11
  25. package/dist/runners/node-process/runner.d.mts +3 -1
  26. package/dist/runners/node-process/runner.mjs +2 -6
  27. package/dist/runners/node-process/worker.mjs +12 -11
  28. package/dist/runners/node-worker/worker.mjs +10 -10
  29. package/dist/runners/self/runner.d.mts +5 -2
  30. package/dist/runners/self/runner.mjs +12 -0
  31. package/package.json +26 -26
  32. package/dist/_chunks/common-host-env.mjs +0 -11
  33. package/dist/_chunks/virtual-loader.mjs +0 -71
@@ -0,0 +1,1656 @@
1
+ import { init, parse } from "./libs/es-module-lexer.mjs";
2
+ import { Buffer } from "node:buffer";
3
+ import { basename, dirname, isAbsolute, join, resolve, sep } from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
6
+ import { createServer } from "node:net";
7
+ import { tmpdir } from "node:os";
8
+ import { MessageChannel, Worker, receiveMessageOnPort } from "node:worker_threads";
9
+ const VIRTUAL_MODULE_FORMATS = /* @__PURE__ */ new Set([
10
+ "module",
11
+ "commonjs",
12
+ "module-typescript",
13
+ "commonjs-typescript",
14
+ "jsx",
15
+ "tsx",
16
+ "json",
17
+ "text",
18
+ "bytes",
19
+ "wasm"
20
+ ]);
21
+ const EXTENSION_FORMATS = {
22
+ ".cjs": "commonjs",
23
+ ".json": "json",
24
+ ".ts": "module-typescript",
25
+ ".mts": "module-typescript",
26
+ ".cts": "commonjs-typescript",
27
+ ".jsx": "jsx",
28
+ ".tsx": "tsx",
29
+ ".wasm": "wasm"
30
+ };
31
+ function virtualModuleFormat(key, module) {
32
+ return typeof module === "object" ? module.format : _extensionFormat(key) ?? "module";
33
+ }
34
+ function virtualModuleCodeSource(key, module) {
35
+ if (module === void 0) return;
36
+ const format = virtualModuleFormat(key, module);
37
+ if (format === "json" || format === "text" || _isBinaryFormat(format)) return;
38
+ return typeof module === "string" ? module : module.source;
39
+ }
40
+ function normalizeVirtualModule(key, content) {
41
+ const module = typeof content === "string" || content instanceof Uint8Array ? { source: content } : content;
42
+ const source = module?.source;
43
+ if (typeof source !== "string" && !(source instanceof Uint8Array)) throw new TypeError(`[env-runner] virtual module "${key}" must be a string, a Uint8Array or { source, format }.`);
44
+ const binary = typeof source !== "string";
45
+ const format = module.format ?? _extensionFormat(key) ?? (binary ? "bytes" : "module");
46
+ if (!VIRTUAL_MODULE_FORMATS.has(format)) throw new TypeError(`[env-runner] virtual module "${key}" has an unknown format "${format}" (expected one of: ${[...VIRTUAL_MODULE_FORMATS].join(", ")}).`);
47
+ if (binary !== _isBinaryFormat(format)) throw new TypeError(`[env-runner] virtual module "${key}" has format "${format}", which needs ${binary ? "a string" : "a Uint8Array"} source.`);
48
+ if (format === "wasm" && !WebAssembly.validate(source)) throw new TypeError(`[env-runner] virtual module "${key}" is not a valid WebAssembly binary.`);
49
+ if (typeof content === "string") return content;
50
+ return {
51
+ source: binary ? new Uint8Array(source) : source,
52
+ format
53
+ };
54
+ }
55
+ function normalizeVirtualModules(virtual) {
56
+ const out = {};
57
+ for (const [key, content] of Object.entries(virtual)) out[key] = normalizeVirtualModule(key, content);
58
+ return out;
59
+ }
60
+ async function resolveVirtualModules(virtual) {
61
+ const entries = await Promise.all(Object.entries(virtual).map(async ([key, value]) => {
62
+ return [key, normalizeVirtualModule(key, typeof value === "function" ? await value() : value)];
63
+ }));
64
+ return Object.fromEntries(entries);
65
+ }
66
+ function encodeVirtualModules(virtual) {
67
+ const out = {};
68
+ for (const [key, module] of Object.entries(virtual)) out[key] = module !== null && typeof module === "object" && typeof module.source !== "string" ? {
69
+ source: _toBase64(module.source),
70
+ format: module.format,
71
+ encoding: "base64"
72
+ } : module;
73
+ return out;
74
+ }
75
+ function decodeVirtualModules(virtual) {
76
+ const out = {};
77
+ for (const [key, module] of Object.entries(virtual)) out[key] = module !== null && typeof module === "object" && "encoding" in module ? {
78
+ source: new Uint8Array(Buffer.from(module.source, "base64")),
79
+ format: module.format
80
+ } : module;
81
+ return out;
82
+ }
83
+ function virtualModuleCode(format, source) {
84
+ if (format === "text") return `export default ${JSON.stringify(source)};\n`;
85
+ const bytes = [
86
+ `const base64 = ${JSON.stringify(_toBase64(source))};`,
87
+ `let bytes;`,
88
+ `if (typeof Uint8Array.fromBase64 === "function") {`,
89
+ ` bytes = Uint8Array.fromBase64(base64);`,
90
+ `} else {`,
91
+ ` const binary = atob(base64);`,
92
+ ` bytes = new Uint8Array(binary.length);`,
93
+ ` for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);`,
94
+ `}`
95
+ ];
96
+ const value = format === "wasm" ? "new WebAssembly.Module(bytes)" : "bytes";
97
+ return `${bytes.join("\n")}\nexport default ${value};\n`;
98
+ }
99
+ function unsupportedVirtualJSXError(key, format, runtime) {
100
+ return /* @__PURE__ */ new TypeError(`[env-runner] virtual module "${key}" has format "${format}", which ${runtime} can't load from memory; pre-transpile it to JavaScript (and pass { source, format: "module" } to keep the key).`);
101
+ }
102
+ const VIRTUAL_SCHEME = "virtual:";
103
+ function createVirtualHooks(virtual, opts = {}) {
104
+ const { versions, importers, forcePlainModule } = opts;
105
+ const baseURL = opts.baseURL ?? _defaultBaseURL();
106
+ const keyURLs = /* @__PURE__ */ new Map();
107
+ const urlKeys = /* @__PURE__ */ new Map();
108
+ for (const key of Object.keys(virtual)) {
109
+ const url = _virtualKeyURL(key);
110
+ if (url) {
111
+ keyURLs.set(key, url);
112
+ urlKeys.set(url, key);
113
+ }
114
+ }
115
+ const keyOf = (url) => {
116
+ if (url.startsWith(VIRTUAL_SCHEME)) {
117
+ const key = _virtualURLKey(url);
118
+ return key !== void 0 && Object.hasOwn(virtual, key) ? key : void 0;
119
+ }
120
+ return urlKeys.size > 0 && url.startsWith("file:") ? urlKeys.get(_bareURL(url)) : void 0;
121
+ };
122
+ const moduleFiles = importers && /* @__PURE__ */ new Set();
123
+ const track = (node, context) => {
124
+ const { parentURL } = context;
125
+ if (!importers || !parentURL) return;
126
+ let importer = keyOf(parentURL);
127
+ if (importer === void 0 && !context.conditions?.includes("require")) {
128
+ const file = _bareURL(parentURL);
129
+ importer = moduleFiles.has(file) ? file : void 0;
130
+ }
131
+ if (importer !== void 0 && importer !== node) {
132
+ let set = importers.get(node);
133
+ if (!set) importers.set(node, set = /* @__PURE__ */ new Set());
134
+ set.add(importer);
135
+ }
136
+ };
137
+ const serve = (key, url, context) => {
138
+ track(key, context);
139
+ if (opts.opaquePathURL && keyURLs.has(key) && opts.opaquePathURL(keyURLs.get(key))) url = _virtualURL(key) + url.slice(_bareURL(url).length);
140
+ const version = versions?.get(key);
141
+ return {
142
+ url: version ? _appendQuery(url, `v=${version}`) : url,
143
+ shortCircuit: true
144
+ };
145
+ };
146
+ const resolve = (specifier, context, nextResolve) => {
147
+ const key = _stripQuery$1(specifier);
148
+ if (Object.hasOwn(virtual, key)) {
149
+ const keyURL = keyURLs.get(key);
150
+ const url = keyURL ? keyURL + specifier.slice(key.length) : _virtualURL(specifier);
151
+ return serve(key, url, context);
152
+ }
153
+ let parentURL = context.parentURL;
154
+ if (parentURL?.startsWith(VIRTUAL_SCHEME)) {
155
+ const parentKey = keyOf(parentURL);
156
+ parentURL = parentKey !== void 0 && keyURLs.get(parentKey) || baseURL;
157
+ }
158
+ if (urlKeys.size > 0) {
159
+ const url = _resolvePathSpecifier(specifier, parentURL);
160
+ const pathKey = url && urlKeys.get(_bareURL(url));
161
+ if (pathKey) return serve(pathKey, url, context);
162
+ }
163
+ const result = nextResolve(specifier, parentURL === context.parentURL ? context : {
164
+ ...context,
165
+ parentURL
166
+ });
167
+ const resolvedKey = urlKeys.size > 0 ? urlKeys.get(_bareURL(result.url)) : void 0;
168
+ if (resolvedKey) return serve(resolvedKey, result.url, context);
169
+ if (result.url.startsWith("file:")) {
170
+ const file = _bareURL(result.url);
171
+ track(file, context);
172
+ const version = versions?.get(file);
173
+ if (version) return {
174
+ ...result,
175
+ url: _appendQuery(result.url, `v=${version}`)
176
+ };
177
+ }
178
+ return result;
179
+ };
180
+ const load = (url, context, nextLoad) => {
181
+ const key = keyOf(url);
182
+ if (key !== void 0) {
183
+ const module = virtual[key];
184
+ if (forcePlainModule) return {
185
+ format: "module",
186
+ source: module,
187
+ shortCircuit: true
188
+ };
189
+ return {
190
+ ..._nodeLoadResult(key, module),
191
+ shortCircuit: true
192
+ };
193
+ }
194
+ const result = nextLoad(url, context);
195
+ if (moduleFiles && url.startsWith("file:") && _isModuleFormat(result.format)) moduleFiles.add(_bareURL(url));
196
+ return result;
197
+ };
198
+ const updateKeys = (keys) => {
199
+ for (const key of keys) {
200
+ const url = keyURLs.get(key) ?? _virtualKeyURL(key);
201
+ if (!url) continue;
202
+ if (Object.hasOwn(virtual, key)) {
203
+ keyURLs.set(key, url);
204
+ urlKeys.set(url, key);
205
+ continue;
206
+ }
207
+ keyURLs.delete(key);
208
+ if (urlKeys.get(url) === key) {
209
+ urlKeys.delete(url);
210
+ for (const [other, otherURL] of keyURLs) if (otherURL === url) urlKeys.set(url, other);
211
+ }
212
+ }
213
+ };
214
+ return {
215
+ resolve,
216
+ load,
217
+ updateKeys
218
+ };
219
+ }
220
+ function _nodeLoadResult(key, module) {
221
+ const format = virtualModuleFormat(key, module);
222
+ const source = typeof module === "string" ? module : module.source;
223
+ if (format === "text" || format === "bytes" || format === "wasm") return {
224
+ format: "module",
225
+ source: virtualModuleCode(format, source)
226
+ };
227
+ if (format === "jsx" || format === "tsx") throw unsupportedVirtualJSXError(key, format, "Node.js");
228
+ return {
229
+ format,
230
+ source
231
+ };
232
+ }
233
+ function stripVirtualTypeScript(specifier, source, stripTypeScriptTypes, hints) {
234
+ if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] virtual TypeScript module "${specifier}" requires \`module.stripTypeScriptTypes\` ${hints.requirement}; ${hints.remedy} or provide a pre-transpiled JavaScript source instead.`);
235
+ try {
236
+ return stripTypeScriptTypes(source);
237
+ } catch (error) {
238
+ throw new SyntaxError(`[env-runner] failed to strip types from virtual module "${specifier}": ${error?.message || error}`, { cause: error });
239
+ }
240
+ }
241
+ function expandVirtualInvalidation(virtual, specifier, importers) {
242
+ const invalidated = [...new Set(typeof specifier === "string" ? [specifier] : specifier)];
243
+ const seen = new Set(invalidated);
244
+ const add = (key) => {
245
+ if (!seen.has(key)) {
246
+ seen.add(key);
247
+ invalidated.push(key);
248
+ }
249
+ };
250
+ for (const target of invalidated) {
251
+ for (const key of importers?.get(target) ?? []) add(key);
252
+ if (!Object.hasOwn(virtual, target)) continue;
253
+ const refs = [
254
+ `"${target}"`,
255
+ `'${target}'`,
256
+ "`" + target + "`"
257
+ ];
258
+ for (const [key, module] of Object.entries(virtual)) {
259
+ const code = virtualModuleCodeSource(key, module);
260
+ if (code !== void 0 && refs.some((ref) => code.includes(ref))) add(key);
261
+ }
262
+ }
263
+ return invalidated;
264
+ }
265
+ function findVirtualPathKey(virtual, specifier) {
266
+ const url = _virtualKeyURL(_stripQuery$1(specifier));
267
+ if (!url) return;
268
+ let match;
269
+ for (const key of Object.keys(virtual)) if (_virtualKeyURL(key) === url) match = key;
270
+ return match;
271
+ }
272
+ const _warnedPathCollisions = /* @__PURE__ */ new Set();
273
+ function warnVirtualPathCollisions(keys) {
274
+ try {
275
+ const urlKeys = /* @__PURE__ */ new Map();
276
+ for (const key of keys) {
277
+ const url = _virtualKeyURL(key);
278
+ if (!url) continue;
279
+ const other = urlKeys.get(url);
280
+ if (other !== void 0 && !_warnedPathCollisions.has(`${other}\0${key}`)) {
281
+ _warnedPathCollisions.add(`${other}\0${key}`);
282
+ console.warn(`[env-runner] virtual modules "${other}" and "${key}" name the same file; keep only one of them (which one is served depends on the runtime).`);
283
+ }
284
+ urlKeys.set(url, key);
285
+ }
286
+ } catch {}
287
+ }
288
+ const virtualKeyURL = _virtualKeyURL;
289
+ function virtualModuleCacheId(key) {
290
+ const url = _virtualKeyURL(key);
291
+ return url ? fileURLToPath(url) : _virtualURL(key);
292
+ }
293
+ function _virtualKeyURL(key) {
294
+ if (key.startsWith("file:")) try {
295
+ return _bareURL(new URL(key).href);
296
+ } catch {
297
+ return;
298
+ }
299
+ return isAbsolute(key) ? pathToFileURL(key).href : void 0;
300
+ }
301
+ function _virtualURL(specifier) {
302
+ return VIRTUAL_SCHEME + specifier.replace(/[\0-\x20"%<>`\x7F-\u{10FFFF}]/gu, encodeURIComponent);
303
+ }
304
+ function _virtualURLKey(url) {
305
+ try {
306
+ return decodeURIComponent(_stripQuery$1(url.slice(8)));
307
+ } catch {
308
+ return;
309
+ }
310
+ }
311
+ function _extensionFormat(key) {
312
+ const extension = /\.[^./\\]+$/.exec(key)?.[0];
313
+ return extension === void 0 ? void 0 : EXTENSION_FORMATS[extension];
314
+ }
315
+ function _isBinaryFormat(format) {
316
+ return format === "bytes" || format === "wasm";
317
+ }
318
+ function _toBase64(bytes) {
319
+ return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
320
+ }
321
+ function _isModuleFormat(format) {
322
+ return format == null || format === "module" || format === "module-typescript";
323
+ }
324
+ function _stripQuery$1(specifier) {
325
+ const qIndex = specifier.indexOf("?");
326
+ return qIndex === -1 ? specifier : specifier.slice(0, qIndex);
327
+ }
328
+ function _bareURL(url) {
329
+ const index = url.search(/[?#]/);
330
+ return index === -1 ? url : url.slice(0, index);
331
+ }
332
+ function _appendQuery(url, param) {
333
+ const hashIndex = url.startsWith(VIRTUAL_SCHEME) ? -1 : url.indexOf("#");
334
+ const base = hashIndex === -1 ? url : url.slice(0, hashIndex);
335
+ const hash = hashIndex === -1 ? "" : url.slice(hashIndex);
336
+ return base + (base.includes("?") ? "&" : "?") + param + hash;
337
+ }
338
+ function _resolvePathSpecifier(specifier, parentURL) {
339
+ try {
340
+ if (/^\.{0,2}\//.test(specifier) || specifier.startsWith("file:")) return new URL(specifier, parentURL).href;
341
+ if (isAbsolute(specifier)) {
342
+ const path = _stripQuery$1(specifier);
343
+ return pathToFileURL(path).href + specifier.slice(path.length);
344
+ }
345
+ } catch {}
346
+ }
347
+ function _defaultBaseURL() {
348
+ return pathToFileURL(process.cwd() + "/").href;
349
+ }
350
+ const SCRIPT_MODULE_TYPES = [
351
+ "js",
352
+ "jsx",
353
+ "ts",
354
+ "tsx"
355
+ ];
356
+ function isNodeModulesId(id) {
357
+ return stripQuery(id).includes("/node_modules/");
358
+ }
359
+ function moduleTypeOf(path) {
360
+ const ext = /\.([^./\\?]+)$/.exec(stripQuery(path))?.[1]?.toLowerCase();
361
+ if (!ext || /^[cm]?js$/.test(ext)) return "js";
362
+ if (/^[cm]?ts$/.test(ext)) return "ts";
363
+ return ext;
364
+ }
365
+ function normalizeFilterId(id) {
366
+ const path = stripQuery(id);
367
+ return path.replaceAll("\\", "/") + id.slice(path.length);
368
+ }
369
+ function stripQuery(id) {
370
+ const qIndex = id.indexOf("?");
371
+ return qIndex === -1 ? id : id.slice(0, qIndex);
372
+ }
373
+ function queryOf(id) {
374
+ const qIndex = id.indexOf("?");
375
+ if (qIndex === -1) return "";
376
+ const hashIndex = id.indexOf("#", qIndex);
377
+ return hashIndex === -1 ? id.slice(qIndex) : id.slice(qIndex, hashIndex);
378
+ }
379
+ const INTERNAL_PARAMS = /* @__PURE__ */ new Set([
380
+ "__envRunnerReload",
381
+ "__env_runner_virtual",
382
+ "__env_runner_disk",
383
+ "__env_runner_plugin",
384
+ "__cjs"
385
+ ]);
386
+ function stripInternalQuery(id, version) {
387
+ const qIndex = id.indexOf("?");
388
+ if (qIndex === -1) return id;
389
+ const params = id.slice(qIndex + 1).split("&");
390
+ if (version && params.at(-1) === `v=${version}`) params.pop();
391
+ const kept = params.filter((param) => !_isInternalParam(param));
392
+ return id.slice(0, qIndex) + (kept.length > 0 ? `?${kept.join("&")}` : "");
393
+ }
394
+ function restoreInternalQuery(id, from) {
395
+ const internal = queryOf(from).slice(1).split("&").filter(_isInternalParam);
396
+ if (internal.length === 0) return id;
397
+ return id + (id.includes("?") ? "&" : "?") + internal.join("&");
398
+ }
399
+ function _isInternalParam(param) {
400
+ return INTERNAL_PARAMS.has(param.split("=", 1)[0]);
401
+ }
402
+ function compileFilter(include, exclude, match) {
403
+ return {
404
+ include,
405
+ exclude,
406
+ test: (value) => !exclude.some((pattern) => match(pattern, value)) && (include.length === 0 || include.some((pattern) => match(pattern, value)))
407
+ };
408
+ }
409
+ function deserializePattern(pattern) {
410
+ return new RegExp(pattern.source, pattern.flags);
411
+ }
412
+ function compileFilterExpressions(expressions) {
413
+ const compiled = expressions.map(({ kind, expr }) => ({
414
+ include: kind === "include",
415
+ test: _compileNode(expr)
416
+ }));
417
+ const hasInclude = compiled.some((expr) => expr.include);
418
+ return (id, moduleType, code) => {
419
+ let unknown = false;
420
+ for (const expr of compiled) {
421
+ const result = expr.test(id, moduleType, code);
422
+ if (result === void 0) unknown = true;
423
+ else if (result) return unknown ? void 0 : expr.include;
424
+ }
425
+ return unknown ? void 0 : !hasInclude;
426
+ };
427
+ }
428
+ function _compileNode(node) {
429
+ switch (node.kind) {
430
+ case "and":
431
+ case "or": {
432
+ const args = node.args.map(_compileNode);
433
+ const decisive = node.kind === "or";
434
+ return (id, moduleType, code) => {
435
+ let result = !decisive;
436
+ for (const arg of args) {
437
+ const value = arg(id, moduleType, code);
438
+ if (value === decisive) return decisive;
439
+ if (value === void 0) result = void 0;
440
+ }
441
+ return result;
442
+ };
443
+ }
444
+ case "not": {
445
+ const expr = _compileNode(node.expr);
446
+ return (id, moduleType, code) => {
447
+ const value = expr(id, moduleType, code);
448
+ return value === void 0 ? void 0 : !value;
449
+ };
450
+ }
451
+ case "id": {
452
+ const pattern = deserializePattern(node.pattern);
453
+ return (id) => pattern.test(id);
454
+ }
455
+ case "moduleType": return (_id, moduleType) => moduleType === node.pattern;
456
+ case "code": {
457
+ const pattern = typeof node.pattern === "string" ? node.pattern : deserializePattern(node.pattern);
458
+ return (_id, _moduleType, code) => code === void 0 ? void 0 : typeof pattern === "string" ? code.includes(pattern) : pattern.test(code);
459
+ }
460
+ case "query": {
461
+ const { key, pattern } = node;
462
+ const regexp = typeof pattern === "object" ? deserializePattern(pattern) : void 0;
463
+ return (id) => {
464
+ const params = new URLSearchParams(queryOf(id));
465
+ if (typeof pattern === "boolean") return params.has(key) === pattern;
466
+ const value = params.get(key);
467
+ return regexp ? regexp.test(value ?? "") : value === pattern;
468
+ };
469
+ }
470
+ }
471
+ }
472
+ function requiredMatch(moduleType) {
473
+ if (SCRIPT_MODULE_TYPES.includes(moduleType)) return;
474
+ return moduleType === "json" || moduleType === "node" || moduleType === "wasm" ? "typed" : "named";
475
+ }
476
+ function compilePrefilter(filter) {
477
+ const namedLevel = filter.load ? "typed" : "named";
478
+ const nodeModules = nodeModulesIncludes(filter).map(deserializePattern);
479
+ const excluded = (id, resolved) => !resolved && isNodeModulesId(id) && !nodeModules.some((pattern) => pattern.test(id));
480
+ if (filter.expr) {
481
+ const level = _compileExpressionsLevel(filter.expr);
482
+ const levels = [
483
+ false,
484
+ true,
485
+ namedLevel,
486
+ "typed"
487
+ ];
488
+ return (id, moduleType, resolved, code) => !excluded(id, resolved) && levels[level(id, moduleType, code)];
489
+ }
490
+ const idFilter = filter.id && compileFilter(filter.id.include.map(deserializePattern), filter.id.exclude.map(deserializePattern), (pattern, value) => pattern.test(value));
491
+ const named = Boolean(idFilter?.include.length);
492
+ return (id, moduleType, resolved) => !excluded(id, resolved) && (!filter.moduleTypes || filter.moduleTypes.includes(moduleType)) && (!idFilter || idFilter.test(id)) && (filter.moduleTypes ? "typed" : named ? namedLevel : true);
493
+ }
494
+ function _compileExpressionsLevel(expressions) {
495
+ const compiled = expressions.map(({ kind, expr }) => ({
496
+ include: kind === "include",
497
+ test: _compileNode(expr),
498
+ level: _compileNodeLevel(expr)
499
+ }));
500
+ const hasInclude = compiled.some((expr) => expr.include);
501
+ return (id, moduleType, code) => {
502
+ let level = 0;
503
+ for (const expr of compiled) {
504
+ const result = expr.test(id, moduleType, code);
505
+ if (result === false) continue;
506
+ if (expr.include) level = Math.max(level, expr.level(id, moduleType, code));
507
+ if (result) return level;
508
+ }
509
+ return hasInclude ? level : Math.max(level, 1);
510
+ };
511
+ }
512
+ function _compileNodeLevel(node) {
513
+ const test = _compileNode(node);
514
+ const matched = (level) => {
515
+ return (id, moduleType, code) => test(id, moduleType, code) === false ? 0 : level;
516
+ };
517
+ switch (node.kind) {
518
+ case "and":
519
+ case "or": {
520
+ const args = node.args.map(_compileNodeLevel);
521
+ return (id, moduleType, code) => test(id, moduleType, code) === false ? 0 : Math.max(...args.map((arg) => arg(id, moduleType, code)));
522
+ }
523
+ case "id": return matched(2);
524
+ case "moduleType": return matched(3);
525
+ case "query": {
526
+ const { key } = node;
527
+ return (id, moduleType, code) => test(id, moduleType, code) === false ? 0 : new URLSearchParams(queryOf(id)).has(key) ? 2 : 1;
528
+ }
529
+ default: return matched(1);
530
+ }
531
+ }
532
+ function satisfiesMatch(match, required) {
533
+ if (match === false) return false;
534
+ return !required || match === "typed" || required === "named" && match === "named";
535
+ }
536
+ function createPrefilter(filters) {
537
+ const compiled = filters.map(compilePrefilter);
538
+ return (id, moduleType, resolved) => {
539
+ const required = requiredMatch(moduleType);
540
+ return compiled.some((test) => satisfiesMatch(test(id, moduleType, resolved), required));
541
+ };
542
+ }
543
+ function nodeModulesIncludes(filter) {
544
+ const names = (pattern) => pattern.source.includes("node_modules");
545
+ if (!filter.expr) return filter.id?.include.filter(names) ?? [];
546
+ const patterns = [];
547
+ const walk = (node) => {
548
+ if (node.kind === "id" && names(node.pattern)) patterns.push(node.pattern);
549
+ else if (node.kind === "and" || node.kind === "or") node.args.forEach(walk);
550
+ };
551
+ for (const { kind, expr } of filter.expr) if (kind === "include") walk(expr);
552
+ return patterns;
553
+ }
554
+ async function handleTransformRequest(pipeline, request) {
555
+ try {
556
+ if (request.type === "resolve") {
557
+ const resolved = await pipeline.resolveId(request.source, request.importer, request);
558
+ return {
559
+ id: request.id,
560
+ resolved
561
+ };
562
+ }
563
+ const { path } = request;
564
+ const result = await pipeline.load(path, request.virtual ? void 0 : () => readFileSync(stripQuery(path), "utf8"), { resolved: request.resolved });
565
+ return {
566
+ id: request.id,
567
+ code: result?.code,
568
+ moduleType: result?.moduleType
569
+ };
570
+ } catch (error) {
571
+ return {
572
+ id: request.id,
573
+ error: error?.message || String(error)
574
+ };
575
+ }
576
+ }
577
+ function openTransformPort(pipeline) {
578
+ const { port1, port2 } = new MessageChannel();
579
+ const state = new Int32Array(new SharedArrayBuffer(4));
580
+ port1.on("message", async (request) => {
581
+ port1.postMessage(await handleTransformRequest(pipeline, request));
582
+ Atomics.add(state, 0, 1);
583
+ Atomics.notify(state, 0);
584
+ });
585
+ port1.unref();
586
+ return {
587
+ channel: {
588
+ port: port2,
589
+ state
590
+ },
591
+ close: () => port1.close()
592
+ };
593
+ }
594
+ function openTransformSocket(pipeline) {
595
+ const { path, dir } = _socketPath();
596
+ let connection;
597
+ const server = createServer((socket) => {
598
+ if (connection) {
599
+ socket.destroy();
600
+ return;
601
+ }
602
+ connection = socket;
603
+ server.close();
604
+ process.off("exit", cleanup);
605
+ cleanup();
606
+ let buffer = "";
607
+ socket.setEncoding("utf8");
608
+ socket.on("error", () => {});
609
+ socket.on("data", (chunk) => {
610
+ buffer += chunk;
611
+ let index;
612
+ while ((index = buffer.indexOf("\n")) !== -1) {
613
+ let request;
614
+ try {
615
+ request = JSON.parse(buffer.slice(0, index));
616
+ } catch {
617
+ socket.destroy();
618
+ return;
619
+ }
620
+ buffer = buffer.slice(index + 1);
621
+ handleTransformRequest(pipeline, request).then((reply) => {
622
+ if (!socket.destroyed) socket.write(JSON.stringify(reply) + "\n");
623
+ });
624
+ }
625
+ });
626
+ });
627
+ server.on("error", (error) => {
628
+ console.error(`[env-runner] plugin transform channel failed: ${error.message}`);
629
+ });
630
+ server.listen(path);
631
+ server.unref();
632
+ const cleanup = () => {
633
+ if (dir) rmSync(dir, {
634
+ recursive: true,
635
+ force: true
636
+ });
637
+ };
638
+ process.once("exit", cleanup);
639
+ return {
640
+ channel: { socket: path },
641
+ close: () => {
642
+ server.close();
643
+ connection?.destroy();
644
+ process.off("exit", cleanup);
645
+ cleanup();
646
+ }
647
+ };
648
+ }
649
+ function _socketPath() {
650
+ if (process.platform === "win32") return { path: `\\\\.\\pipe\\${`env-runner-${process.pid}-${crypto.randomUUID()}`}` };
651
+ let base = tmpdir();
652
+ if (join(base, "env-runner-XXXXXX", "transform.sock").length >= 100) base = "/tmp";
653
+ const dir = mkdtempSync(join(base, "env-runner-"));
654
+ return {
655
+ path: join(dir, "transform.sock"),
656
+ dir
657
+ };
658
+ }
659
+ const SLOW_REQUEST_MS = 1e4;
660
+ function createTransformClient(channel) {
661
+ let port;
662
+ let state;
663
+ if (channel.port && channel.state) ({port, state} = channel);
664
+ else if (channel.socket) {
665
+ const pair = new MessageChannel();
666
+ port = pair.port1;
667
+ state = new Int32Array(new SharedArrayBuffer(4));
668
+ new Worker(BRIDGE_SOURCE, {
669
+ eval: true,
670
+ workerData: {
671
+ port: pair.port2,
672
+ state,
673
+ socket: channel.socket
674
+ },
675
+ transferList: [pair.port2]
676
+ }).unref();
677
+ } else throw new TypeError("[env-runner] invalid plugin transform channel");
678
+ let lastId = 0;
679
+ const send = (request, what) => {
680
+ const id = ++lastId;
681
+ port.postMessage({
682
+ ...request,
683
+ id
684
+ });
685
+ let warned = false;
686
+ for (;;) {
687
+ const seen = Atomics.load(state, 0);
688
+ const received = receiveMessageOnPort(port);
689
+ if (!received) {
690
+ if (Atomics.wait(state, 0, seen, SLOW_REQUEST_MS) === "timed-out" && !warned) {
691
+ warned = true;
692
+ console.warn(`[env-runner] still waiting for the runner's plugins ${what} (plugin handlers must not wait on this runner).`);
693
+ }
694
+ continue;
695
+ }
696
+ const reply = received.message;
697
+ if (reply.closed) throw new Error(`[env-runner] cannot ${what.replace(/^to /, "")}: ${reply.error}`);
698
+ if (reply.id !== id) continue;
699
+ if (reply.error !== void 0) throw new Error(reply.error);
700
+ return reply;
701
+ }
702
+ };
703
+ return {
704
+ resolve: (source, importer, options) => send({
705
+ type: "resolve",
706
+ source,
707
+ importer,
708
+ ...options
709
+ }, `to resolve "${source}"`).resolved,
710
+ load: (path, virtual, resolved) => {
711
+ const reply = send({
712
+ type: "load",
713
+ path,
714
+ virtual,
715
+ resolved
716
+ }, `to load "${path}"`);
717
+ return reply.code === void 0 ? void 0 : {
718
+ code: reply.code,
719
+ moduleType: reply.moduleType ?? "js"
720
+ };
721
+ }
722
+ };
723
+ }
724
+ const BRIDGE_SOURCE = `
725
+ const { workerData } = require("node:worker_threads");
726
+ const { connect } = require("node:net");
727
+ const { port, state, socket } = workerData;
728
+ // A crash here would leave the worker blocked: answer with an error instead.
729
+ process.on("uncaughtException", (error) => onClose(error));
730
+ const reply = (message) => {
731
+ port.postMessage(message);
732
+ Atomics.add(state, 0, 1);
733
+ Atomics.notify(state, 0);
734
+ };
735
+ let closed = false;
736
+ const onClose = (error) => {
737
+ if (!closed) {
738
+ closed = true;
739
+ reply({ closed: true, error: "the runner closed the channel" + (error ? " (" + error.message + ")" : "") });
740
+ }
741
+ };
742
+ let buffer = "";
743
+ const connection = connect(socket);
744
+ connection.setEncoding("utf8");
745
+ connection.on("data", (chunk) => {
746
+ buffer += chunk;
747
+ let index;
748
+ while ((index = buffer.indexOf("\\n")) !== -1) {
749
+ reply(JSON.parse(buffer.slice(0, index)));
750
+ buffer = buffer.slice(index + 1);
751
+ }
752
+ });
753
+ connection.on("error", onClose);
754
+ connection.on("close", () => onClose());
755
+ port.on("message", (request) => {
756
+ if (closed) {
757
+ reply({ closed: true, error: "the runner closed the channel" });
758
+ } else {
759
+ connection.write(JSON.stringify(request) + "\\n");
760
+ }
761
+ });
762
+ `;
763
+ async function registerVirtualModules(wire) {
764
+ if (!wire || Object.keys(wire).length === 0) return _once(() => {
765
+ for (const unregister of _lazyUnregisters.splice(0)) unregister();
766
+ });
767
+ let virtual = decodeVirtualModules(wire);
768
+ const { registerHooks, stripTypeScriptTypes, createRequire } = await import("node:module");
769
+ if (typeof registerHooks === "function") {
770
+ const isDeno = "Deno" in globalThis;
771
+ const prepare = isDeno ? (key, module) => _prepareForDeno(key, module, stripTypeScriptTypes) : _prepareForNode;
772
+ virtual = await _prepareVirtualModules(virtual, prepare);
773
+ const versions = /* @__PURE__ */ new Map();
774
+ const importers = /* @__PURE__ */ new Map();
775
+ const { resolve, load, updateKeys } = createVirtualHooks(virtual, {
776
+ versions,
777
+ importers,
778
+ forcePlainModule: isDeno,
779
+ opaquePathURL: isDeno ? (url) => url.endsWith(".cjs") || url.endsWith(".cts") : void 0
780
+ });
781
+ const hooks = registerHooks({
782
+ resolve,
783
+ load
784
+ });
785
+ const registration = {
786
+ virtual,
787
+ versions,
788
+ version: 0,
789
+ importers,
790
+ prepare,
791
+ updateKeys,
792
+ cache: createRequire(import.meta.url).cache
793
+ };
794
+ _hooksRegistrations.unshift(registration);
795
+ return _once(() => {
796
+ const index = _hooksRegistrations.indexOf(registration);
797
+ if (index !== -1) _hooksRegistrations.splice(index, 1);
798
+ hooks.deregister();
799
+ });
800
+ }
801
+ if (typeof globalThis.Bun?.plugin === "function") {
802
+ virtual = await _prepareVirtualModules(virtual, _prepareForBun);
803
+ const registration = _createBunRegistration(virtual, createRequire(import.meta.url).cache);
804
+ globalThis.Bun.plugin({
805
+ name: "env-runner-virtual",
806
+ setup: (build) => _setupBunPlugin(build, registration)
807
+ });
808
+ _bunRegistrations.unshift(registration);
809
+ return _once(() => {
810
+ const index = _bunRegistrations.indexOf(registration);
811
+ if (index !== -1) _bunRegistrations.splice(index, 1);
812
+ for (const path of [...registration.paths.keys(), ...registration.removed.keys()]) _bunReleasedPaths.add(path);
813
+ });
814
+ }
815
+ console.warn("[env-runner] virtual modules require `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.8) or `Bun.plugin`; skipping registration.");
816
+ return _noop$1;
817
+ }
818
+ function refreshVirtualModule(specifier) {
819
+ for (const registration of _bunRegistrations) if (Object.hasOwn(registration.virtual, specifier)) {
820
+ _bustBunModules(registration, [specifier]);
821
+ return true;
822
+ }
823
+ return false;
824
+ }
825
+ function virtualFileVersion(file) {
826
+ for (const registration of _hooksRegistrations) {
827
+ const version = registration.versions.get(file);
828
+ if (version) return version;
829
+ }
830
+ for (const registration of _bunRegistrations) {
831
+ const key = registration.paths.get(file) ?? registration.removed.get(file);
832
+ const version = key === void 0 ? void 0 : registration.versions.get(key);
833
+ if (version) return version;
834
+ }
835
+ }
836
+ async function updateVirtualModules(wire) {
837
+ const changes = decodeVirtualModules(wire);
838
+ if (_hooksRegistrations.length === 0 && _bunRegistrations.length === 0) {
839
+ const added = Object.fromEntries(Object.entries(changes).filter((entry) => entry[1] !== null));
840
+ if (Object.keys(added).length === 0) return;
841
+ const unregister = await registerVirtualModules(added);
842
+ if (_hooksRegistrations.length === 0 && _bunRegistrations.length === 0) throw new Error("Cannot update virtual modules: this runtime can't serve them");
843
+ _lazyUnregisters.push(unregister);
844
+ }
845
+ const registrations = _hooksRegistrations.length > 0 ? _hooksRegistrations : _bunRegistrations;
846
+ const groups = /* @__PURE__ */ new Map();
847
+ for (const [key, module] of Object.entries(changes)) {
848
+ const owner = registrations.find((registration) => Object.hasOwn(registration.virtual, key)) ?? (module === null ? void 0 : registrations[0]);
849
+ if (owner) {
850
+ let group = groups.get(owner);
851
+ if (!group) groups.set(owner, group = {});
852
+ group[key] = module;
853
+ }
854
+ }
855
+ const prepared = [];
856
+ for (const [registration, group] of groups) {
857
+ const prepare = "prepare" in registration ? registration.prepare : _prepareForBun;
858
+ prepared.push([registration, await _prepareVirtualModules(group, prepare)]);
859
+ }
860
+ for (const [registration, sources] of prepared) if ("updateKeys" in registration) _updateHooksRegistration(registration, sources);
861
+ else _updateBunRegistration(registration, sources);
862
+ }
863
+ function handleUpdateVirtualModules(message, sendMessage) {
864
+ _pendingUpdate = _pendingUpdate.then(() => updateVirtualModules(message.changes ?? {})).then(() => sendMessage({
865
+ event: "virtual-modules-updated",
866
+ id: message.id
867
+ }), (error) => sendMessage({
868
+ event: "virtual-modules-updated",
869
+ id: message.id,
870
+ error: error?.message || String(error)
871
+ })).catch(() => {});
872
+ return _pendingUpdate;
873
+ }
874
+ function registeredVirtualModules() {
875
+ const merged = {};
876
+ for (const registration of [..._hooksRegistrations, ..._bunRegistrations].reverse()) Object.assign(merged, registration.virtual);
877
+ return merged;
878
+ }
879
+ let _pendingUpdate = Promise.resolve();
880
+ const _lazyUnregisters = [];
881
+ function _updateHooksRegistration(registration, changes) {
882
+ const { virtual, versions, importers } = registration;
883
+ const added = [];
884
+ const removed = [];
885
+ for (const [key, module] of Object.entries(changes)) {
886
+ if (module === null) {
887
+ removed.push(key);
888
+ continue;
889
+ }
890
+ if (!Object.hasOwn(virtual, key)) added.push(key);
891
+ virtual[key] = module;
892
+ }
893
+ registration.updateKeys(added);
894
+ const targets = Object.keys(changes).flatMap((key) => {
895
+ const url = virtualKeyURL(key);
896
+ return url && url !== key ? [key, url] : [key];
897
+ });
898
+ for (const node of expandVirtualInvalidation(virtual, targets, importers)) {
899
+ versions.set(node, ++registration.version);
900
+ if (Object.hasOwn(virtual, node)) delete registration.cache[virtualModuleCacheId(node)];
901
+ }
902
+ for (const key of removed) delete virtual[key];
903
+ registration.updateKeys(removed);
904
+ }
905
+ const _hooksRegistrations = [];
906
+ const _bunRegistrations = [];
907
+ const BUN_NAMESPACE$1 = "env-runner-virtual";
908
+ const BUN_VIRTUAL_MARKER = "__env_runner_virtual";
909
+ const BUN_DISK_MARKER = "__env_runner_disk";
910
+ let _bunNamespaceLoader = false;
911
+ let _bunDynamicCallbacks = false;
912
+ const _bunDynamicNames = /* @__PURE__ */ new Set();
913
+ const _bunReleasedPaths = /* @__PURE__ */ new Set();
914
+ function _createBunRegistration(virtual, cache) {
915
+ const registration = {
916
+ virtual,
917
+ paths: /* @__PURE__ */ new Map(),
918
+ namespaced: /* @__PURE__ */ new Set(),
919
+ modules: /* @__PURE__ */ new Set(),
920
+ dynamic: /* @__PURE__ */ new Set(),
921
+ removed: /* @__PURE__ */ new Map(),
922
+ versions: /* @__PURE__ */ new Map(),
923
+ version: 0,
924
+ importers: /* @__PURE__ */ new Map(),
925
+ served: /* @__PURE__ */ new Map(),
926
+ cache
927
+ };
928
+ for (const key of Object.keys(virtual)) _addBunKey(registration, key);
929
+ return registration;
930
+ }
931
+ function _addBunKey(registration, key) {
932
+ const path = _keyPath(key);
933
+ if (path === void 0) {
934
+ (!key.includes(":") && _bunResolvable(key) ? registration.namespaced : registration.modules).add(key);
935
+ return false;
936
+ }
937
+ if (_bunResolvable(basename(path))) {
938
+ registration.paths.set(path, key);
939
+ registration.removed.delete(path);
940
+ return true;
941
+ }
942
+ registration.modules.add(key);
943
+ return false;
944
+ }
945
+ function _setupBunPlugin(build, registration) {
946
+ registration.build = build;
947
+ const query = String.raw`(?:\?.*)?$`;
948
+ const resolveFilters = [...[...registration.namespaced].map((key) => `^${_escapeRegExp(key)}${query}`), ...[...registration.paths.keys()].map((path) => String.raw`(?:^|[\\/])${_escapeRegExp(basename(path))}${query}`)];
949
+ if (resolveFilters.length > 0) build.onResolve({ filter: new RegExp(resolveFilters.join("|")) }, _resolveBunModule);
950
+ if (registration.paths.size > 0) {
951
+ const paths = [...registration.paths.keys()].map(_escapeRegExp).join("|");
952
+ const loadQuery = String.raw`(?:\?(?!${BUN_DISK_MARKER}(?:&|$)).*)?$`;
953
+ build.onLoad({ filter: new RegExp(`^(?:${paths})${loadQuery}`) }, _loadBunPath);
954
+ }
955
+ if (registration.namespaced.size > 0 && !_bunNamespaceLoader) {
956
+ _bunNamespaceLoader = true;
957
+ build.onLoad({
958
+ filter: /.*/,
959
+ namespace: BUN_NAMESPACE$1
960
+ }, _loadBunNamespaced);
961
+ }
962
+ for (const key of registration.modules) build.module(key, () => _loadBunModule(key));
963
+ }
964
+ function _installBunDynamicCallbacks(build) {
965
+ if (!_bunDynamicCallbacks) {
966
+ _bunDynamicCallbacks = true;
967
+ build.onResolve({ filter: /.*/ }, _resolveBunDynamic);
968
+ const marker = new RegExp(String.raw`\?${BUN_VIRTUAL_MARKER}(?:&|$)`);
969
+ build.onLoad({ filter: marker }, _loadBunPath);
970
+ }
971
+ if (!_bunNamespaceLoader) {
972
+ _bunNamespaceLoader = true;
973
+ build.onLoad({
974
+ filter: /.*/,
975
+ namespace: BUN_NAMESPACE$1
976
+ }, _loadBunNamespaced);
977
+ }
978
+ }
979
+ function _updateBunRegistration(registration, changes) {
980
+ const { virtual } = registration;
981
+ const removed = [];
982
+ let dynamic = false;
983
+ for (const [key, source] of Object.entries(changes)) {
984
+ if (source === null) {
985
+ removed.push(key);
986
+ continue;
987
+ }
988
+ if (!Object.hasOwn(virtual, key)) {
989
+ const path = _keyPath(key);
990
+ if (_addBunKey(registration, key)) {
991
+ registration.dynamic.add(path);
992
+ _bunDynamicNames.add(_bunSpecifierName(path));
993
+ } else if (registration.namespaced.has(key)) _bunDynamicNames.add(_bunSpecifierName(key));
994
+ dynamic ||= !registration.modules.has(key);
995
+ }
996
+ virtual[key] = source;
997
+ }
998
+ if (dynamic) _installBunDynamicCallbacks(registration.build);
999
+ _bustBunModules(registration, expandVirtualInvalidation(virtual, Object.keys(changes), registration.importers));
1000
+ for (const key of removed) _removeBunKey(registration, key);
1001
+ }
1002
+ function _removeBunKey(registration, key) {
1003
+ const { virtual, paths } = registration;
1004
+ delete virtual[key];
1005
+ registration.namespaced.delete(key);
1006
+ registration.modules.delete(key);
1007
+ const path = _keyPath(key);
1008
+ if (path === void 0 || paths.get(path) !== key) return;
1009
+ paths.delete(path);
1010
+ registration.dynamic.delete(path);
1011
+ registration.removed.set(path, key);
1012
+ for (const other of Object.keys(virtual)) if (_keyPath(other) === path) {
1013
+ paths.set(path, other);
1014
+ registration.removed.delete(path);
1015
+ }
1016
+ }
1017
+ function _resolveBunModule(args) {
1018
+ const specifier = _stripQuery(args.path);
1019
+ const query = _stripBunMarker(args.path.slice(specifier.length));
1020
+ let path;
1021
+ if (isAbsolute(specifier)) path = resolve(specifier);
1022
+ else if (/^\.\.?[\\/]/.test(specifier)) path = resolve(_bunImporterDir(args.importer), specifier);
1023
+ for (const registration of _bunRegistrations) {
1024
+ const namespaced = registration.namespaced.has(specifier);
1025
+ const key = namespaced ? specifier : path && registration.paths.get(path);
1026
+ if (!key) continue;
1027
+ _addBunImporter(registration, key, args.importer);
1028
+ const marker = !namespaced && registration.dynamic.has(path) ? BUN_VIRTUAL_MARKER : void 0;
1029
+ const served = _bunVersioned((namespaced ? specifier : path) + _withBunMarker(query, marker), registration.versions.get(key));
1030
+ _addToSetMap(registration.served, key, namespaced ? `${BUN_NAMESPACE$1}:${served}` : served);
1031
+ return namespaced ? {
1032
+ path: served,
1033
+ namespace: BUN_NAMESPACE$1
1034
+ } : { path: served };
1035
+ }
1036
+ for (const registration of _bunRegistrations) {
1037
+ const key = path && registration.removed.get(path);
1038
+ if (!key) continue;
1039
+ _addBunImporter(registration, key, args.importer);
1040
+ const served = _bunVersioned(path + _withBunMarker(query, BUN_DISK_MARKER), registration.versions.get(key));
1041
+ _addToSetMap(registration.served, key, served);
1042
+ return { path: served };
1043
+ }
1044
+ if (path && _bunReleasedPaths.has(path)) return { path: path + _withBunMarker(query, BUN_DISK_MARKER) };
1045
+ }
1046
+ function _resolveBunDynamic(args) {
1047
+ const name = _bunSpecifierName(_stripQuery(args.path));
1048
+ return _bunDynamicNames.has(name) ? _resolveBunModule(args) : void 0;
1049
+ }
1050
+ function _bunSpecifierName(specifier) {
1051
+ return specifier.slice(Math.max(specifier.lastIndexOf("/"), specifier.lastIndexOf("\\")) + 1);
1052
+ }
1053
+ function _addBunImporter(registration, key, importerId) {
1054
+ const importer = _bunKeyOf(registration, importerId);
1055
+ if (importer !== void 0 && importer !== key) _addToSetMap(registration.importers, key, importer);
1056
+ }
1057
+ function _withBunMarker(query, marker) {
1058
+ if (!marker) return query;
1059
+ return `?${marker}` + (query ? `&${query.slice(1)}` : "");
1060
+ }
1061
+ function _stripBunMarker(query) {
1062
+ for (const marker of [BUN_VIRTUAL_MARKER, BUN_DISK_MARKER]) {
1063
+ if (query === `?${marker}`) return "";
1064
+ if (query.startsWith(`?${marker}&`)) return `?${query.slice(marker.length + 2)}`;
1065
+ }
1066
+ return query;
1067
+ }
1068
+ function _loadBunPath(args) {
1069
+ const path = _stripQuery(args.path);
1070
+ for (const registration of _bunRegistrations) {
1071
+ const key = registration.paths.get(path);
1072
+ if (key !== void 0) return _serveBunModule(key, registration.virtual[key]);
1073
+ }
1074
+ }
1075
+ function _loadBunNamespaced(args) {
1076
+ const key = _stripQuery(args.path);
1077
+ return _serveBunModule(key, _bunRegistrations.find((r) => r.namespaced.has(key))?.virtual[key]);
1078
+ }
1079
+ function _loadBunModule(key) {
1080
+ return _serveBunModule(key, _bunRegistrations.find((r) => r.modules.has(key))?.virtual[key]);
1081
+ }
1082
+ function _serveBunModule(key, module) {
1083
+ if (module === void 0) throw new Error(`Cannot find virtual module "${key}" (unregistered)`);
1084
+ const format = virtualModuleFormat(key, module);
1085
+ const source = typeof module === "string" ? module : module.source;
1086
+ switch (format) {
1087
+ case "json": return {
1088
+ exports: { default: _parseBunJSON(key, source) },
1089
+ loader: "object"
1090
+ };
1091
+ case "text": return {
1092
+ exports: { default: source },
1093
+ loader: "object"
1094
+ };
1095
+ case "bytes": return {
1096
+ exports: { default: source.slice() },
1097
+ loader: "object"
1098
+ };
1099
+ case "wasm": return {
1100
+ exports: { default: new WebAssembly.Module(source) },
1101
+ loader: "object"
1102
+ };
1103
+ }
1104
+ return {
1105
+ contents: source,
1106
+ loader: format === "module-typescript" ? "ts" : format === "module" ? "js" : format
1107
+ };
1108
+ }
1109
+ function _parseBunJSON(key, source) {
1110
+ try {
1111
+ return JSON.parse(source);
1112
+ } catch (error) {
1113
+ const message = `[env-runner] invalid JSON in virtual module "${key}": ${error?.message}`;
1114
+ throw new SyntaxError(message, { cause: error });
1115
+ }
1116
+ }
1117
+ function _bustBunModules(registration, keys) {
1118
+ for (const key of keys) {
1119
+ if (registration.modules.has(key)) {
1120
+ registration.build.module(key, () => _loadBunModule(key));
1121
+ continue;
1122
+ }
1123
+ registration.versions.set(key, ++registration.version);
1124
+ for (const id of registration.served.get(key) ?? []) delete registration.cache[id];
1125
+ registration.served.delete(key);
1126
+ }
1127
+ }
1128
+ function _bunVersioned(id, version) {
1129
+ const param = `v=${version}`;
1130
+ if (!version || id.endsWith(`?${param}`) || id.endsWith(`&${param}`)) return id;
1131
+ return id + (id.includes("?") ? "&" : "?") + param;
1132
+ }
1133
+ function _keyPath(key) {
1134
+ if (key.startsWith("file:")) try {
1135
+ return fileURLToPath(key);
1136
+ } catch {
1137
+ return;
1138
+ }
1139
+ return isAbsolute(key) ? resolve(key) : void 0;
1140
+ }
1141
+ function _bunKeyOf(registration, importer) {
1142
+ const prefix = `${BUN_NAMESPACE$1}:`;
1143
+ const id = _stripQuery(importer.startsWith(prefix) ? importer.slice(prefix.length) : importer);
1144
+ return registration.paths.get(id) ?? (Object.hasOwn(registration.virtual, id) ? id : void 0);
1145
+ }
1146
+ function _bunImporterDir(importer) {
1147
+ const path = _stripQuery(importer);
1148
+ return isAbsolute(path) ? dirname(path) : process.cwd();
1149
+ }
1150
+ function _bunResolvable(specifier) {
1151
+ const dot = specifier.lastIndexOf(".");
1152
+ const code = dot === -1 ? 0 : specifier.charCodeAt(dot + 1);
1153
+ return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code > 127;
1154
+ }
1155
+ function _stripQuery(specifier) {
1156
+ const qIndex = specifier.indexOf("?");
1157
+ return qIndex === -1 ? specifier : specifier.slice(0, qIndex);
1158
+ }
1159
+ function _addToSetMap(map, key, value) {
1160
+ let set = map.get(key);
1161
+ if (!set) map.set(key, set = /* @__PURE__ */ new Set());
1162
+ set.add(value);
1163
+ }
1164
+ function _escapeRegExp(value) {
1165
+ return value.replace(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`);
1166
+ }
1167
+ async function _prepareVirtualModules(virtual, prepare) {
1168
+ if (prepare !== _prepareForNode && !_cjsLexer) {
1169
+ if (Object.entries(virtual).some(([key, module]) => module !== null && virtualModuleFormat(key, module).startsWith("commonjs"))) await loadCommonJSLexer();
1170
+ }
1171
+ const out = {};
1172
+ for (const [key, module] of Object.entries(virtual)) out[key] = module === null ? module : prepare(key, module);
1173
+ return out;
1174
+ }
1175
+ let _cjsLexer;
1176
+ async function loadCommonJSLexer() {
1177
+ if (!_cjsLexer) {
1178
+ const lexer = await import("./lexer.mjs");
1179
+ await lexer.init();
1180
+ _cjsLexer = lexer;
1181
+ }
1182
+ }
1183
+ function commonJSToESM(path, source) {
1184
+ return _commonJSToESM(path, source);
1185
+ }
1186
+ function _prepareForNode(key, module) {
1187
+ const format = virtualModuleFormat(key, module);
1188
+ if (format === "jsx" || format === "tsx") throw unsupportedVirtualJSXError(key, format, "Node.js");
1189
+ return module;
1190
+ }
1191
+ function _prepareForBun(key, module) {
1192
+ const format = virtualModuleFormat(key, module);
1193
+ if (format !== "commonjs" && format !== "commonjs-typescript") return module;
1194
+ return {
1195
+ source: _commonJSToESM(key, typeof module === "string" ? module : module.source),
1196
+ format: format === "commonjs" ? "module" : "module-typescript"
1197
+ };
1198
+ }
1199
+ function _prepareForDeno(key, module, stripTypeScriptTypes) {
1200
+ const format = virtualModuleFormat(key, module);
1201
+ const source = typeof module === "string" ? module : module.source;
1202
+ const strip = () => stripVirtualTypeScript(key, source, stripTypeScriptTypes, {
1203
+ requirement: "(custom load hooks bypass Deno's native type stripping)",
1204
+ remedy: "upgrade Deno"
1205
+ });
1206
+ switch (format) {
1207
+ case "module-typescript": return strip();
1208
+ case "commonjs": return _commonJSToESM(key, source);
1209
+ case "commonjs-typescript": return _commonJSToESM(key, strip());
1210
+ case "json": return `export default JSON.parse(${JSON.stringify(source)});`;
1211
+ case "text":
1212
+ case "bytes":
1213
+ case "wasm": return virtualModuleCode(format, source);
1214
+ case "jsx":
1215
+ case "tsx": throw unsupportedVirtualJSXError(key, format, "Deno");
1216
+ }
1217
+ return source;
1218
+ }
1219
+ function _commonJSToESM(key, source) {
1220
+ const path = _keyPath(key);
1221
+ const filename = JSON.stringify(path ?? key);
1222
+ const dir = JSON.stringify(path ? dirname(path) : process.cwd());
1223
+ const base = JSON.stringify(path ?? process.cwd() + sep);
1224
+ let names = [];
1225
+ try {
1226
+ names = _cjsLexer.parse(source).exports;
1227
+ } catch {}
1228
+ const p = "__envRunner";
1229
+ const lines = [
1230
+ `import { createRequire as ${p}CreateRequire } from "node:module"; const ${p}Module = { exports: {} }; (function (exports, require, module, __filename, __dirname) {${source}`,
1231
+ `}).call(${p}Module.exports, ${p}Module.exports, ${p}CreateRequire(${base}), ${p}Module, ${filename}, ${dir});`,
1232
+ `const ${p}Exports = ${p}Module.exports;`,
1233
+ `export { ${p}Exports as default, ${p}Exports as "module.exports" };`
1234
+ ];
1235
+ let index = 0;
1236
+ for (const name of new Set(names)) if (name !== "default" && name !== "module.exports") {
1237
+ const local = `${p}Export${index++}`;
1238
+ lines.push(`const ${local} = ${p}Exports?.[${JSON.stringify(name)}];`, `export { ${local} as ${JSON.stringify(name)} };`);
1239
+ }
1240
+ return lines.join("\n") + "\n";
1241
+ }
1242
+ const _noop$1 = () => {};
1243
+ function _once(fn) {
1244
+ let done = false;
1245
+ return () => {
1246
+ if (!done) {
1247
+ done = true;
1248
+ fn();
1249
+ }
1250
+ };
1251
+ }
1252
+ const PLUGINS_DATA_KEY = "__envRunnerPlugins";
1253
+ const PLUGIN_SCHEME = "env-runner-plugin:";
1254
+ const BUN_NAMESPACE = "env-runner-plugin";
1255
+ const BUN_OTHER_FILE = /\.(?![cm]?[jt]sx?(?:\?|$))[\w-]+(?:\?.*)?$/i;
1256
+ const BUN_LOADED_MARKER = "__env_runner_plugin";
1257
+ const BUN_LOADED_FILE = new RegExp(String.raw`\?${BUN_LOADED_MARKER}(?:&|$)`);
1258
+ let _active;
1259
+ function servedByPluginHooks(path) {
1260
+ return _active?.(path) ?? false;
1261
+ }
1262
+ async function registerPluginHooks(config, entry) {
1263
+ if (!config) return _noop;
1264
+ const prefilter = createPrefilter(config.prefilters);
1265
+ const matches = (id, resolved) => {
1266
+ const filterId = normalizeFilterId(id);
1267
+ return prefilter(filterId, moduleTypeOf(filterId), resolved);
1268
+ };
1269
+ const pluginResolved = /* @__PURE__ */ new Set();
1270
+ const resolvePrefilters = config.resolvePrefilters ?? [];
1271
+ const resolveTest = (fallback) => {
1272
+ const prefilters = resolvePrefilters.filter((prefilter) => !prefilter.fallback === !fallback);
1273
+ const test = createPrefilter(prefilters);
1274
+ return (source) => prefilters.length > 0 && test(normalizeFilterId(source), "js", true);
1275
+ };
1276
+ const resolves = resolveTest(false);
1277
+ const resolvesFailed = resolveTest(true);
1278
+ const entryId = entry && (entry.startsWith("file:") ? _urlPath(entry) : stripQuery(entry));
1279
+ const client = createTransformClient(config);
1280
+ await init;
1281
+ const { registerHooks, stripTypeScriptTypes } = await import("node:module");
1282
+ const isDeno = "Deno" in globalThis;
1283
+ if (isDeno || typeof globalThis.Bun?.plugin === "function") await loadCommonJSLexer();
1284
+ if (typeof registerHooks === "function") {
1285
+ const cwdURL = pathToFileURL(process.cwd() + "/").href;
1286
+ const serve = (path, result, context) => {
1287
+ if (result.moduleType === "json") {
1288
+ if (context.importAttributes?.type === "json" || context.conditions?.includes("require")) return {
1289
+ format: "json",
1290
+ source: result.code,
1291
+ shortCircuit: true
1292
+ };
1293
+ return {
1294
+ format: "module",
1295
+ source: jsonModuleCode(path, result.code),
1296
+ shortCircuit: true
1297
+ };
1298
+ }
1299
+ const format = transformedFormat(path, result.code, context.format);
1300
+ if (!isDeno) return {
1301
+ format: result.moduleType === "ts" ? `${format}-typescript` : format,
1302
+ source: result.code,
1303
+ shortCircuit: true
1304
+ };
1305
+ let source = result.code;
1306
+ if (result.moduleType === "ts") source = _stripTypes(path, source, stripTypeScriptTypes);
1307
+ if (format === "commonjs") source = commonJSToESM(path, source);
1308
+ return {
1309
+ format: "module",
1310
+ source,
1311
+ shortCircuit: true
1312
+ };
1313
+ };
1314
+ const hooks = registerHooks({
1315
+ ...resolvePrefilters.length > 0 && { resolve(specifier, context, nextResolve) {
1316
+ const raw = specifier.startsWith("file:") ? _urlPath(specifier, true) : specifier;
1317
+ const source = stripInternalQuery(raw);
1318
+ const ask = (fallback) => {
1319
+ const isEntry = entryId !== void 0 && stripQuery(source) === entryId;
1320
+ const resolved = client.resolve(source, isEntry ? void 0 : _importerId(context.parentURL), {
1321
+ isEntry,
1322
+ attributes: context.importAttributes,
1323
+ fallback
1324
+ });
1325
+ if (resolved && !resolved.external) {
1326
+ if (_idPath(resolved.id)) pluginResolved.add(stripQuery(resolved.id));
1327
+ return {
1328
+ url: restoreInternalQuery(_idURL(resolved.id), raw),
1329
+ shortCircuit: true
1330
+ };
1331
+ }
1332
+ if (resolved && resolved.id !== source) specifier = restoreInternalQuery(_idPath(resolved.id) ? _idURL(resolved.id) : resolved.id, raw);
1333
+ return resolved;
1334
+ };
1335
+ const before = resolves(source) ? ask(false) : void 0;
1336
+ if (before && "url" in before) return before;
1337
+ const parent = context.parentURL?.startsWith(PLUGIN_SCHEME) ? {
1338
+ ...context,
1339
+ parentURL: cwdURL
1340
+ } : context;
1341
+ if (!resolvesFailed(source)) return nextResolve(specifier, parent);
1342
+ let result;
1343
+ let failure;
1344
+ try {
1345
+ result = nextResolve(specifier, parent);
1346
+ } catch (error) {
1347
+ failure = error;
1348
+ }
1349
+ if (result && !(result.url.startsWith("file:") && !existsSync(_urlPath(result.url)))) return result;
1350
+ const resolved = ask(true);
1351
+ if (resolved && "url" in resolved) return resolved;
1352
+ if (resolved) return nextResolve(specifier, parent);
1353
+ if (failure !== void 0) throw failure;
1354
+ return result;
1355
+ } },
1356
+ load(url, context, nextLoad) {
1357
+ if (url.startsWith(PLUGIN_SCHEME)) {
1358
+ const id = _schemeId(url);
1359
+ return serve(id, client.load(id, true), context);
1360
+ }
1361
+ if (url.startsWith("file:")) {
1362
+ const id = _fileId(url);
1363
+ const resolved = pluginResolved.has(stripQuery(id));
1364
+ if (matches(id, resolved)) {
1365
+ const result = client.load(id, false, resolved);
1366
+ if (result) return serve(stripQuery(id), result, context);
1367
+ }
1368
+ }
1369
+ return nextLoad(url, context);
1370
+ }
1371
+ });
1372
+ _active = matches;
1373
+ return () => {
1374
+ if (_active === matches) _active = void 0;
1375
+ hooks.deregister();
1376
+ };
1377
+ }
1378
+ const bunPlugin = globalThis.Bun?.plugin;
1379
+ if (typeof bunPlugin === "function") {
1380
+ const filter = createBunFilter(config.prefilters);
1381
+ const served = (path) => filter.test(path);
1382
+ const serve = (path, result) => {
1383
+ if (result.moduleType === "json") {
1384
+ const value = _parseJSON(path, result.code);
1385
+ return {
1386
+ exports: {
1387
+ ...value && typeof value === "object" && !Array.isArray(value) ? value : {},
1388
+ default: value
1389
+ },
1390
+ loader: "object"
1391
+ };
1392
+ }
1393
+ const { code } = result;
1394
+ return {
1395
+ contents: transformedFormat(path, code) === "commonjs" ? commonJSToESM(path, code) : code,
1396
+ loader: result.moduleType === "ts" ? "ts" : "js"
1397
+ };
1398
+ };
1399
+ const loaded = /* @__PURE__ */ new Map();
1400
+ const loadOther = (id, resolved) => {
1401
+ const result = loaded.get(id) ?? (matches(id, resolved) ? client.load(id, false, resolved) : void 0);
1402
+ if (!result) return;
1403
+ loaded.set(id, result);
1404
+ const query = queryOf(id);
1405
+ return { path: `${stripQuery(id)}?${BUN_LOADED_MARKER}${query && `&${query.slice(1)}`}` };
1406
+ };
1407
+ const onResolve = (namespace) => ({ path, importer }) => {
1408
+ if (_bunResolving || _active !== served || !namespace && importer === "") return;
1409
+ const raw = namespace ? `${namespace}:${path}` : path;
1410
+ const source = stripInternalQuery(raw);
1411
+ const before = resolves(source);
1412
+ if (!before && !resolvesFailed(source)) return;
1413
+ const isEntry = entryId !== void 0 && stripQuery(source) === entryId;
1414
+ const importerId = isEntry ? void 0 : _bunImporterId(importer);
1415
+ let resolved = before ? client.resolve(source, importerId, { isEntry }) : void 0;
1416
+ if (!resolved && resolvesFailed(source) && !_bunResolves(raw, importer)) resolved = client.resolve(source, importerId, {
1417
+ isEntry,
1418
+ fallback: true
1419
+ });
1420
+ if (!resolved || resolved.external && resolved.id === source) return;
1421
+ if (_idPath(resolved.id)) {
1422
+ const file = stripQuery(resolved.id);
1423
+ const here = BUN_OTHER_FILE.test(file) || isNodeModulesId(normalizeFilterId(file));
1424
+ return !resolved.external && here && loadOther(resolved.id, true) || { path: restoreInternalQuery(resolved.id, raw) };
1425
+ }
1426
+ return resolved.external ? void 0 : {
1427
+ path: encodeURIComponent(resolved.id),
1428
+ namespace: BUN_NAMESPACE
1429
+ };
1430
+ };
1431
+ bunPlugin({
1432
+ name: "env-runner-plugins",
1433
+ setup(build) {
1434
+ build.onLoad({ filter }, ({ path }) => {
1435
+ const id = _bunId(path);
1436
+ const file = stripQuery(path);
1437
+ const result = _active === served && matches(id) ? client.load(id) : void 0;
1438
+ if (result) return serve(file, result);
1439
+ const contents = readFileSync(file, "utf8");
1440
+ return {
1441
+ contents: transformedFormat(file, contents) === "commonjs" ? commonJSToESM(file, contents) : contents,
1442
+ loader: _bunLoader(file)
1443
+ };
1444
+ });
1445
+ if (resolvePrefilters.length > 0) {
1446
+ build.onResolve({ filter: createBunResolveFilter(resolvePrefilters) }, onResolve());
1447
+ for (const scheme of resolveSchemes(resolvePrefilters)) build.onResolve({
1448
+ filter: /.*/,
1449
+ namespace: scheme
1450
+ }, onResolve(scheme));
1451
+ }
1452
+ build.onResolve({ filter: BUN_OTHER_FILE }, ({ path, importer }) => {
1453
+ const file = _active === served && importer ? _bunFilePath(path, importer) : void 0;
1454
+ return file === void 0 ? void 0 : loadOther(_bunId(file + queryOf(path)));
1455
+ });
1456
+ build.onLoad({ filter: BUN_LOADED_FILE }, ({ path }) => {
1457
+ const id = _bunId(path);
1458
+ const result = loaded.get(id) ?? client.load(id);
1459
+ loaded.delete(id);
1460
+ if (!result) throw new Error(`[env-runner] no plugin loaded or transformed "${id}" anymore`);
1461
+ return serve(stripQuery(path), result);
1462
+ });
1463
+ build.onLoad({
1464
+ filter: /.*/,
1465
+ namespace: BUN_NAMESPACE
1466
+ }, ({ path }) => {
1467
+ const id = decodeURIComponent(path);
1468
+ return serve(id, client.load(id, true));
1469
+ });
1470
+ }
1471
+ });
1472
+ _active = served;
1473
+ return () => {
1474
+ if (_active === served) _active = void 0;
1475
+ };
1476
+ }
1477
+ console.warn("[env-runner] `plugins` requires `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.8) or `Bun.plugin`; skipping.");
1478
+ return _noop;
1479
+ }
1480
+ let _bunResolving = false;
1481
+ function _bunResolves(specifier, importer) {
1482
+ const from = stripQuery(importer);
1483
+ _bunResolving = true;
1484
+ try {
1485
+ globalThis.Bun.resolveSync(stripQuery(specifier), isAbsolute(from) ? dirname(from) : process.cwd());
1486
+ return true;
1487
+ } catch {
1488
+ return false;
1489
+ } finally {
1490
+ _bunResolving = false;
1491
+ }
1492
+ }
1493
+ function _idPath(id) {
1494
+ return isAbsolute(stripQuery(id));
1495
+ }
1496
+ function _idURL(id) {
1497
+ if (_idPath(id)) {
1498
+ const path = stripQuery(id);
1499
+ return pathToFileURL(path).href + id.slice(path.length);
1500
+ }
1501
+ return PLUGIN_SCHEME + encodeURIComponent(id);
1502
+ }
1503
+ function _schemeId(url) {
1504
+ return decodeURIComponent(stripQuery(url.slice(18)));
1505
+ }
1506
+ function _urlPath(url, keepQuery = false) {
1507
+ return fileURLToPath(stripQuery(url)) + (keepQuery ? queryOf(url) : "");
1508
+ }
1509
+ function _fileId(url) {
1510
+ const bare = url.slice(0, url.search(/[?#]|$/));
1511
+ return stripInternalQuery(_urlPath(url, true), virtualFileVersion(bare));
1512
+ }
1513
+ function _bunId(path) {
1514
+ return stripInternalQuery(path, virtualFileVersion(stripQuery(path)));
1515
+ }
1516
+ function _importerId(parentURL) {
1517
+ if (!parentURL) return;
1518
+ if (parentURL.startsWith("file:")) return _fileId(parentURL);
1519
+ return parentURL.startsWith(PLUGIN_SCHEME) ? _schemeId(parentURL) : parentURL;
1520
+ }
1521
+ function _bunImporterId(importer) {
1522
+ if (!importer) return;
1523
+ const prefix = `${BUN_NAMESPACE}:`;
1524
+ if (importer.startsWith(prefix)) return decodeURIComponent(importer.slice(prefix.length));
1525
+ return isAbsolute(stripQuery(importer)) ? _bunId(importer) : stripQuery(importer);
1526
+ }
1527
+ function _bunFilePath(specifier, importer) {
1528
+ const path = stripQuery(specifier);
1529
+ if (isAbsolute(path)) return path;
1530
+ if (!/^\.\.?[\\/]/.test(path)) return;
1531
+ const from = stripQuery(importer);
1532
+ return resolve(isAbsolute(from) ? dirname(from) : process.cwd(), path);
1533
+ }
1534
+ function jsonModuleCode(path, json) {
1535
+ const value = _parseJSON(path, json);
1536
+ const lines = [`const json = JSON.parse(${JSON.stringify(json)});`, "export default json;"];
1537
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1538
+ let index = 0;
1539
+ for (const key of Object.keys(value)) if (key !== "default") {
1540
+ const local = `json${index++}`;
1541
+ lines.push(`const ${local} = json[${JSON.stringify(key)}];`, `export { ${local} as ${JSON.stringify(key)} };`);
1542
+ }
1543
+ }
1544
+ return lines.join("\n") + "\n";
1545
+ }
1546
+ function _parseJSON(path, source) {
1547
+ try {
1548
+ return JSON.parse(source);
1549
+ } catch (error) {
1550
+ throw new SyntaxError(`[env-runner] invalid JSON in "${path}": ${error?.message}`, { cause: error });
1551
+ }
1552
+ }
1553
+ function _stripTypes(path, code, stripTypeScriptTypes) {
1554
+ if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] "${path}" is still TypeScript after its plugins, which needs \`module.stripTypeScriptTypes\` (Deno >= 2.8.2) here: upgrade Deno or compile it in a plugin.`);
1555
+ try {
1556
+ return stripTypeScriptTypes(code);
1557
+ } catch (error) {
1558
+ throw new SyntaxError(`[env-runner] failed to strip types from "${path}" after its plugins: ${error?.message || error}`, { cause: error });
1559
+ }
1560
+ }
1561
+ const CJS_MARKERS = /\b(?:module\.exports\b|exports\.\w|require\s*\()/;
1562
+ function transformedFormat(path, code, hint) {
1563
+ if (hint?.startsWith("module")) return "module";
1564
+ if (hint?.startsWith("commonjs")) return "commonjs";
1565
+ const file = stripQuery(path);
1566
+ if (/\.m[jt]sx?$/.test(file)) return "module";
1567
+ if (/\.c[jt]sx?$/.test(file)) return "commonjs";
1568
+ if (!CJS_MARKERS.test(code)) return "module";
1569
+ try {
1570
+ return parse(code)[3] ? "module" : "commonjs";
1571
+ } catch {
1572
+ return "module";
1573
+ }
1574
+ }
1575
+ const BUN_EXTENSIONS = {
1576
+ js: [".js", ".mjs"],
1577
+ ts: [".ts", ".mts"],
1578
+ jsx: [".jsx"],
1579
+ tsx: [".tsx"]
1580
+ };
1581
+ function createBunFilter(prefilters, windows = process.platform === "win32") {
1582
+ const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1583
+ const sep = String.raw`(?:\\|\/)`;
1584
+ const foldable = (pattern) => pattern.glob || !windows;
1585
+ const plugins = prefilters.map((prefilter) => {
1586
+ const { id, moduleTypes, expr } = prefilter;
1587
+ const include = id && id.include.length > 0 && id.include.every(foldable) ? id.include : [];
1588
+ return {
1589
+ moduleTypes: expr ? void 0 : moduleTypes,
1590
+ exclude: id?.exclude.filter(foldable) ?? [],
1591
+ include,
1592
+ nodeModules: include.length > 0 && nodeModulesIncludes(prefilter).length > 0
1593
+ };
1594
+ });
1595
+ const folded = plugins.flatMap(({ include, exclude }) => [...include, ...exclude]);
1596
+ const flagSet = new Set(folded.map((pattern) => pattern.flags));
1597
+ const foldIds = flagSet.size <= 1 && !folded.some(({ source }) => /\\[1-9]|\\k<|\(\?<(?![=!])/.test(source));
1598
+ const branches = /* @__PURE__ */ new Set();
1599
+ const guard = `(?![^?]*${sep}node_modules${sep})`;
1600
+ for (const { moduleTypes, include, exclude, nodeModules } of plugins) {
1601
+ const extensions = moduleTypes ? moduleTypes.flatMap((type) => BUN_EXTENSIONS[type] ?? []) : Object.values(BUN_EXTENSIONS).flat();
1602
+ if (extensions.length === 0) continue;
1603
+ let lookaheads = "";
1604
+ if (foldIds && exclude.length > 0) lookaheads += `(?!.*?(?:${exclude.map(({ source }) => source).join("|")}))`;
1605
+ if (foldIds && include.length > 0) lookaheads += `(?=.*?(?:${include.map(({ source }) => source).join("|")}))`;
1606
+ if (nodeModules && !foldIds) lookaheads = guard;
1607
+ else if (!nodeModules) lookaheads = guard + lookaheads;
1608
+ const exts = [...new Set(extensions)].map(escape).join("|");
1609
+ branches.add(`${lookaheads}[^?]*(?:${exts})(?:\\?.*)?$`);
1610
+ }
1611
+ const marker = String.raw`\?__env_runner_(?:virtual|disk|plugin)(?:&|$)`;
1612
+ return new RegExp(`^(?![^?]*${marker})(?:${[...branches].join("|") || "(?!)"})`, foldIds ? [...flagSet][0] ?? "" : "");
1613
+ }
1614
+ function createBunResolveFilter(prefilters) {
1615
+ const includes = prefilters.map(({ id, expr }) => expr ? [] : id?.include ?? []);
1616
+ const patterns = includes.flat();
1617
+ const flags = new Set(patterns.map((pattern) => pattern.flags));
1618
+ if (includes.some((list) => list.length === 0) || flags.size > 1 || patterns.some(({ source }) => /\\[1-9]|\\k<|\(\?<(?![=!])/.test(source))) return /.*/;
1619
+ return new RegExp(patterns.map(({ source }) => `(?:${source})`).join("|"), [...flags][0]);
1620
+ }
1621
+ function resolveSchemes(prefilters) {
1622
+ const schemes = /* @__PURE__ */ new Set();
1623
+ const add = (pattern) => {
1624
+ const scheme = /^\^((?:\\?[\w+.-])+?)\\?:/.exec(pattern.source)?.[1].replaceAll("\\", "");
1625
+ if (scheme && scheme.length > 1 && /^[a-z][\w+.-]*$/i.test(scheme) && ![
1626
+ "node",
1627
+ "bun",
1628
+ "file",
1629
+ "data",
1630
+ "http",
1631
+ "https",
1632
+ "blob"
1633
+ ].includes(scheme)) schemes.add(scheme);
1634
+ };
1635
+ const walk = (node) => {
1636
+ if (node.kind === "id") add(node.pattern);
1637
+ else if (node.kind === "and" || node.kind === "or") node.args.forEach(walk);
1638
+ };
1639
+ for (const { id, expr } of prefilters) {
1640
+ id?.include.forEach(add);
1641
+ for (const { kind, expr: node } of expr ?? []) if (kind === "include") walk(node);
1642
+ }
1643
+ return [...schemes];
1644
+ }
1645
+ function _bunLoader(path) {
1646
+ const ext = path.slice(path.lastIndexOf(".") + 1);
1647
+ switch (ext) {
1648
+ case "ts":
1649
+ case "mts": return "ts";
1650
+ case "tsx":
1651
+ case "jsx": return ext;
1652
+ default: return "js";
1653
+ }
1654
+ }
1655
+ const _noop = () => {};
1656
+ export { PLUGINS_DATA_KEY, compileFilter, compileFilterExpressions, compilePrefilter, createPrefilter, encodeVirtualModules, expandVirtualInvalidation, findVirtualPathKey, handleUpdateVirtualModules, jsonModuleCode, moduleTypeOf, normalizeFilterId, normalizeVirtualModules, openTransformPort, openTransformSocket, queryOf, refreshVirtualModule, registerPluginHooks, registerVirtualModules, registeredVirtualModules, requiredMatch, resolveVirtualModules, restoreInternalQuery, satisfiesMatch, servedByPluginHooks, stripInternalQuery, stripQuery, stripVirtualTypeScript, transformedFormat, unsupportedVirtualJSXError, virtualModuleCode, virtualModuleCodeSource, virtualModuleFormat, warnVirtualPathCollisions };