env-runner 0.3.0 → 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.
@@ -1,345 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- import { isAbsolute } from "node:path";
3
- import { fileURLToPath, pathToFileURL } from "node:url";
4
- const VIRTUAL_MODULE_FORMATS = /* @__PURE__ */ new Set([
5
- "module",
6
- "commonjs",
7
- "module-typescript",
8
- "commonjs-typescript",
9
- "jsx",
10
- "tsx",
11
- "json",
12
- "text",
13
- "bytes",
14
- "wasm"
15
- ]);
16
- const EXTENSION_FORMATS = {
17
- ".cjs": "commonjs",
18
- ".json": "json",
19
- ".ts": "module-typescript",
20
- ".mts": "module-typescript",
21
- ".cts": "commonjs-typescript",
22
- ".jsx": "jsx",
23
- ".tsx": "tsx",
24
- ".wasm": "wasm"
25
- };
26
- function virtualModuleFormat(key, module) {
27
- return typeof module === "object" ? module.format : _extensionFormat(key) ?? "module";
28
- }
29
- function virtualModuleCodeSource(key, module) {
30
- if (module === void 0) return;
31
- const format = virtualModuleFormat(key, module);
32
- if (format === "json" || format === "text" || _isBinaryFormat(format)) return;
33
- return typeof module === "string" ? module : module.source;
34
- }
35
- function normalizeVirtualModule(key, content) {
36
- const module = typeof content === "string" || content instanceof Uint8Array ? { source: content } : content;
37
- const source = module?.source;
38
- if (typeof source !== "string" && !(source instanceof Uint8Array)) throw new TypeError(`[env-runner] virtual module "${key}" must be a string, a Uint8Array or { source, format }.`);
39
- const binary = typeof source !== "string";
40
- const format = module.format ?? _extensionFormat(key) ?? (binary ? "bytes" : "module");
41
- 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(", ")}).`);
42
- if (binary !== _isBinaryFormat(format)) throw new TypeError(`[env-runner] virtual module "${key}" has format "${format}", which needs ${binary ? "a string" : "a Uint8Array"} source.`);
43
- if (format === "wasm" && !WebAssembly.validate(source)) throw new TypeError(`[env-runner] virtual module "${key}" is not a valid WebAssembly binary.`);
44
- if (typeof content === "string") return content;
45
- return {
46
- source: binary ? new Uint8Array(source) : source,
47
- format
48
- };
49
- }
50
- function normalizeVirtualModules(virtual) {
51
- const out = {};
52
- for (const [key, content] of Object.entries(virtual)) out[key] = normalizeVirtualModule(key, content);
53
- return out;
54
- }
55
- async function resolveVirtualModules(virtual) {
56
- const entries = await Promise.all(Object.entries(virtual).map(async ([key, value]) => {
57
- return [key, normalizeVirtualModule(key, typeof value === "function" ? await value() : value)];
58
- }));
59
- return Object.fromEntries(entries);
60
- }
61
- function encodeVirtualModules(virtual) {
62
- const out = {};
63
- for (const [key, module] of Object.entries(virtual)) out[key] = module !== null && typeof module === "object" && typeof module.source !== "string" ? {
64
- source: _toBase64(module.source),
65
- format: module.format,
66
- encoding: "base64"
67
- } : module;
68
- return out;
69
- }
70
- function decodeVirtualModules(virtual) {
71
- const out = {};
72
- for (const [key, module] of Object.entries(virtual)) out[key] = module !== null && typeof module === "object" && "encoding" in module ? {
73
- source: new Uint8Array(Buffer.from(module.source, "base64")),
74
- format: module.format
75
- } : module;
76
- return out;
77
- }
78
- function virtualModuleCode(format, source) {
79
- if (format === "text") return `export default ${JSON.stringify(source)};\n`;
80
- const bytes = [
81
- `const base64 = ${JSON.stringify(_toBase64(source))};`,
82
- `let bytes;`,
83
- `if (typeof Uint8Array.fromBase64 === "function") {`,
84
- ` bytes = Uint8Array.fromBase64(base64);`,
85
- `} else {`,
86
- ` const binary = atob(base64);`,
87
- ` bytes = new Uint8Array(binary.length);`,
88
- ` for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);`,
89
- `}`
90
- ];
91
- const value = format === "wasm" ? "new WebAssembly.Module(bytes)" : "bytes";
92
- return `${bytes.join("\n")}\nexport default ${value};\n`;
93
- }
94
- function unsupportedVirtualJSXError(key, format, runtime) {
95
- 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).`);
96
- }
97
- const VIRTUAL_SCHEME = "virtual:";
98
- function createVirtualHooks(virtual, opts = {}) {
99
- const { versions, importers, forcePlainModule } = opts;
100
- const baseURL = opts.baseURL ?? _defaultBaseURL();
101
- const keyURLs = /* @__PURE__ */ new Map();
102
- const urlKeys = /* @__PURE__ */ new Map();
103
- for (const key of Object.keys(virtual)) {
104
- const url = _virtualKeyURL(key);
105
- if (url) {
106
- keyURLs.set(key, url);
107
- urlKeys.set(url, key);
108
- }
109
- }
110
- const keyOf = (url) => {
111
- if (url.startsWith(VIRTUAL_SCHEME)) {
112
- const key = _virtualURLKey(url);
113
- return key !== void 0 && Object.hasOwn(virtual, key) ? key : void 0;
114
- }
115
- return urlKeys.size > 0 && url.startsWith("file:") ? urlKeys.get(_bareURL(url)) : void 0;
116
- };
117
- const moduleFiles = importers && /* @__PURE__ */ new Set();
118
- const track = (node, context) => {
119
- const { parentURL } = context;
120
- if (!importers || !parentURL) return;
121
- let importer = keyOf(parentURL);
122
- if (importer === void 0 && !context.conditions?.includes("require")) {
123
- const file = _bareURL(parentURL);
124
- importer = moduleFiles.has(file) ? file : void 0;
125
- }
126
- if (importer !== void 0 && importer !== node) {
127
- let set = importers.get(node);
128
- if (!set) importers.set(node, set = /* @__PURE__ */ new Set());
129
- set.add(importer);
130
- }
131
- };
132
- const serve = (key, url, context) => {
133
- track(key, context);
134
- if (opts.opaquePathURL && keyURLs.has(key) && opts.opaquePathURL(keyURLs.get(key))) url = _virtualURL(key) + url.slice(_bareURL(url).length);
135
- const version = versions?.get(key);
136
- return {
137
- url: version ? _appendQuery(url, `v=${version}`) : url,
138
- shortCircuit: true
139
- };
140
- };
141
- const resolve = (specifier, context, nextResolve) => {
142
- const key = _stripQuery(specifier);
143
- if (Object.hasOwn(virtual, key)) {
144
- const keyURL = keyURLs.get(key);
145
- const url = keyURL ? keyURL + specifier.slice(key.length) : _virtualURL(specifier);
146
- return serve(key, url, context);
147
- }
148
- let parentURL = context.parentURL;
149
- if (parentURL?.startsWith(VIRTUAL_SCHEME)) {
150
- const parentKey = keyOf(parentURL);
151
- parentURL = parentKey !== void 0 && keyURLs.get(parentKey) || baseURL;
152
- }
153
- if (urlKeys.size > 0) {
154
- const url = _resolvePathSpecifier(specifier, parentURL);
155
- const pathKey = url && urlKeys.get(_bareURL(url));
156
- if (pathKey) return serve(pathKey, url, context);
157
- }
158
- const result = nextResolve(specifier, parentURL === context.parentURL ? context : {
159
- ...context,
160
- parentURL
161
- });
162
- const resolvedKey = urlKeys.size > 0 ? urlKeys.get(_bareURL(result.url)) : void 0;
163
- if (resolvedKey) return serve(resolvedKey, result.url, context);
164
- if (result.url.startsWith("file:")) {
165
- const file = _bareURL(result.url);
166
- track(file, context);
167
- const version = versions?.get(file);
168
- if (version) return {
169
- ...result,
170
- url: _appendQuery(result.url, `v=${version}`)
171
- };
172
- }
173
- return result;
174
- };
175
- const load = (url, context, nextLoad) => {
176
- const key = keyOf(url);
177
- if (key !== void 0) {
178
- const module = virtual[key];
179
- if (forcePlainModule) return {
180
- format: "module",
181
- source: module,
182
- shortCircuit: true
183
- };
184
- return {
185
- ..._nodeLoadResult(key, module),
186
- shortCircuit: true
187
- };
188
- }
189
- const result = nextLoad(url, context);
190
- if (moduleFiles && url.startsWith("file:") && _isModuleFormat(result.format)) moduleFiles.add(_bareURL(url));
191
- return result;
192
- };
193
- const updateKeys = (keys) => {
194
- for (const key of keys) {
195
- const url = keyURLs.get(key) ?? _virtualKeyURL(key);
196
- if (!url) continue;
197
- if (Object.hasOwn(virtual, key)) {
198
- keyURLs.set(key, url);
199
- urlKeys.set(url, key);
200
- continue;
201
- }
202
- keyURLs.delete(key);
203
- if (urlKeys.get(url) === key) {
204
- urlKeys.delete(url);
205
- for (const [other, otherURL] of keyURLs) if (otherURL === url) urlKeys.set(url, other);
206
- }
207
- }
208
- };
209
- return {
210
- resolve,
211
- load,
212
- updateKeys
213
- };
214
- }
215
- function _nodeLoadResult(key, module) {
216
- const format = virtualModuleFormat(key, module);
217
- const source = typeof module === "string" ? module : module.source;
218
- if (format === "text" || format === "bytes" || format === "wasm") return {
219
- format: "module",
220
- source: virtualModuleCode(format, source)
221
- };
222
- if (format === "jsx" || format === "tsx") throw unsupportedVirtualJSXError(key, format, "Node.js");
223
- return {
224
- format,
225
- source
226
- };
227
- }
228
- function stripVirtualTypeScript(specifier, source, stripTypeScriptTypes, hints) {
229
- 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.`);
230
- try {
231
- return stripTypeScriptTypes(source);
232
- } catch (error) {
233
- throw new SyntaxError(`[env-runner] failed to strip types from virtual module "${specifier}": ${error?.message || error}`, { cause: error });
234
- }
235
- }
236
- function expandVirtualInvalidation(virtual, specifier, importers) {
237
- const invalidated = [...new Set(typeof specifier === "string" ? [specifier] : specifier)];
238
- const seen = new Set(invalidated);
239
- const add = (key) => {
240
- if (!seen.has(key)) {
241
- seen.add(key);
242
- invalidated.push(key);
243
- }
244
- };
245
- for (const target of invalidated) {
246
- for (const key of importers?.get(target) ?? []) add(key);
247
- if (!Object.hasOwn(virtual, target)) continue;
248
- const refs = [
249
- `"${target}"`,
250
- `'${target}'`,
251
- "`" + target + "`"
252
- ];
253
- for (const [key, module] of Object.entries(virtual)) {
254
- const code = virtualModuleCodeSource(key, module);
255
- if (code !== void 0 && refs.some((ref) => code.includes(ref))) add(key);
256
- }
257
- }
258
- return invalidated;
259
- }
260
- function findVirtualPathKey(virtual, specifier) {
261
- const url = _virtualKeyURL(_stripQuery(specifier));
262
- if (!url) return;
263
- let match;
264
- for (const key of Object.keys(virtual)) if (_virtualKeyURL(key) === url) match = key;
265
- return match;
266
- }
267
- const _warnedPathCollisions = /* @__PURE__ */ new Set();
268
- function warnVirtualPathCollisions(keys) {
269
- try {
270
- const urlKeys = /* @__PURE__ */ new Map();
271
- for (const key of keys) {
272
- const url = _virtualKeyURL(key);
273
- if (!url) continue;
274
- const other = urlKeys.get(url);
275
- if (other !== void 0 && !_warnedPathCollisions.has(`${other}\0${key}`)) {
276
- _warnedPathCollisions.add(`${other}\0${key}`);
277
- 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).`);
278
- }
279
- urlKeys.set(url, key);
280
- }
281
- } catch {}
282
- }
283
- const virtualKeyURL = _virtualKeyURL;
284
- function virtualModuleCacheId(key) {
285
- const url = _virtualKeyURL(key);
286
- return url ? fileURLToPath(url) : _virtualURL(key);
287
- }
288
- function _virtualKeyURL(key) {
289
- if (key.startsWith("file:")) try {
290
- return _bareURL(new URL(key).href);
291
- } catch {
292
- return;
293
- }
294
- return isAbsolute(key) ? pathToFileURL(key).href : void 0;
295
- }
296
- function _virtualURL(specifier) {
297
- return VIRTUAL_SCHEME + specifier.replace(/[\0-\x20"%<>`\x7F-\u{10FFFF}]/gu, encodeURIComponent);
298
- }
299
- function _virtualURLKey(url) {
300
- try {
301
- return decodeURIComponent(_stripQuery(url.slice(8)));
302
- } catch {
303
- return;
304
- }
305
- }
306
- function _extensionFormat(key) {
307
- const extension = /\.[^./\\]+$/.exec(key)?.[0];
308
- return extension === void 0 ? void 0 : EXTENSION_FORMATS[extension];
309
- }
310
- function _isBinaryFormat(format) {
311
- return format === "bytes" || format === "wasm";
312
- }
313
- function _toBase64(bytes) {
314
- return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
315
- }
316
- function _isModuleFormat(format) {
317
- return format == null || format === "module" || format === "module-typescript";
318
- }
319
- function _stripQuery(specifier) {
320
- const qIndex = specifier.indexOf("?");
321
- return qIndex === -1 ? specifier : specifier.slice(0, qIndex);
322
- }
323
- function _bareURL(url) {
324
- const index = url.search(/[?#]/);
325
- return index === -1 ? url : url.slice(0, index);
326
- }
327
- function _appendQuery(url, param) {
328
- const hashIndex = url.startsWith(VIRTUAL_SCHEME) ? -1 : url.indexOf("#");
329
- const base = hashIndex === -1 ? url : url.slice(0, hashIndex);
330
- const hash = hashIndex === -1 ? "" : url.slice(hashIndex);
331
- return base + (base.includes("?") ? "&" : "?") + param + hash;
332
- }
333
- function _resolvePathSpecifier(specifier, parentURL) {
334
- try {
335
- if (/^\.{0,2}\//.test(specifier) || specifier.startsWith("file:")) return new URL(specifier, parentURL).href;
336
- if (isAbsolute(specifier)) {
337
- const path = _stripQuery(specifier);
338
- return pathToFileURL(path).href + specifier.slice(path.length);
339
- }
340
- } catch {}
341
- }
342
- function _defaultBaseURL() {
343
- return pathToFileURL(process.cwd() + "/").href;
344
- }
345
- export { createVirtualHooks, decodeVirtualModules, encodeVirtualModules, expandVirtualInvalidation, findVirtualPathKey, normalizeVirtualModules, resolveVirtualModules, stripVirtualTypeScript, unsupportedVirtualJSXError, virtualKeyURL, virtualModuleCacheId, virtualModuleCode, virtualModuleCodeSource, virtualModuleFormat, warnVirtualPathCollisions };