sandboxedjs 0.1.34 → 0.1.36
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/README.md +42 -0
- package/bin/sandboxedjs.mjs +5 -3
- package/dist/index.cjs +1379 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +261 -1
- package/dist/index.d.ts +261 -1
- package/dist/index.js +1374 -39
- package/dist/index.js.map +1 -1
- package/dist/rolldown-wasi-worker.js +71 -0
- package/dist/rolldown-wasi-worker.js.map +1 -0
- package/dist/worker-entry.js +33 -4
- package/dist/worker-entry.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { workerData, Worker, parentPort } from 'worker_threads';
|
|
4
|
+
|
|
5
|
+
// src/runtime/rolldown-wasi-worker.ts
|
|
6
|
+
var options = workerData ?? {};
|
|
7
|
+
var require2 = createRequire(options.runtimeAnchor ?? import.meta.url);
|
|
8
|
+
var {
|
|
9
|
+
instantiateNapiModuleSync,
|
|
10
|
+
MessageHandler,
|
|
11
|
+
WASI,
|
|
12
|
+
createFsProxy,
|
|
13
|
+
emnapiAsyncWorkPlugin,
|
|
14
|
+
emnapiTSFNPlugin
|
|
15
|
+
} = require2("@napi-rs/wasm-runtime");
|
|
16
|
+
var { memfsExported } = await import(options.fsModuleUrl);
|
|
17
|
+
Object.assign(globalThis, {
|
|
18
|
+
self: globalThis,
|
|
19
|
+
require: require2,
|
|
20
|
+
Worker,
|
|
21
|
+
importScripts(file) {
|
|
22
|
+
(0, eval)(`${readFileSync(file, "utf8")}//# sourceURL=${file}`);
|
|
23
|
+
},
|
|
24
|
+
postMessage(message) {
|
|
25
|
+
parentPort?.postMessage(message);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (parentPort) {
|
|
29
|
+
parentPort.on("message", (data) => {
|
|
30
|
+
globalThis.onmessage?.({ data });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
var errorOutputs = [];
|
|
34
|
+
var handler = new MessageHandler({
|
|
35
|
+
onLoad({ wasmModule, wasmMemory }) {
|
|
36
|
+
const wasi = new WASI({
|
|
37
|
+
/* The proxy is the whole point: every syscall goes to the main thread,
|
|
38
|
+
* which answers from the volume the container keeps in step. */
|
|
39
|
+
fs: createFsProxy(memfsExported),
|
|
40
|
+
preopens: { "/": "/" },
|
|
41
|
+
print: (...args) => console.log(...args),
|
|
42
|
+
printErr: (...args) => {
|
|
43
|
+
console.error(...args);
|
|
44
|
+
errorOutputs.push(args);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return instantiateNapiModuleSync(wasmModule, {
|
|
48
|
+
childThread: true,
|
|
49
|
+
wasi,
|
|
50
|
+
/* The wasm links a "basic" emnapi archive with no C implementations of
|
|
51
|
+
* async work or threadsafe functions, so every thread has to bring the
|
|
52
|
+
* JavaScript ones. */
|
|
53
|
+
plugins: [emnapiAsyncWorkPlugin, emnapiTSFNPlugin],
|
|
54
|
+
overwriteImports(importObject) {
|
|
55
|
+
importObject.env = {
|
|
56
|
+
...importObject.env,
|
|
57
|
+
...importObject.napi,
|
|
58
|
+
...importObject.emnapi,
|
|
59
|
+
memory: wasmMemory
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
onError(error) {
|
|
65
|
+
globalThis.postMessage({ type: "error", error, errorOutputs: [...errorOutputs] });
|
|
66
|
+
errorOutputs.length = 0;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
globalThis.onmessage = (event) => handler.handle(event);
|
|
70
|
+
//# sourceMappingURL=rolldown-wasi-worker.js.map
|
|
71
|
+
//# sourceMappingURL=rolldown-wasi-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/rolldown-wasi-worker.ts"],"names":["require"],"mappings":";;;;;AAiCA,IAAM,OAAA,GAAW,cAAc,EAAC;AAChC,IAAMA,QAAAA,GAAU,aAAA,CAAc,OAAA,CAAQ,aAAA,IAAiB,YAAY,GAAG,CAAA;AAEtE,IAAM;AAAA,EACJ,yBAAA;AAAA,EACA,cAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA,GAAIA,SAAQ,uBAAuB,CAAA;AAInC,IAAM,EAAE,aAAA,EAAc,GAAI,MAAM,OAAO,OAAA,CAAQ,WAAA,CAAA;AAU/C,MAAA,CAAO,OAAO,UAAA,EAAY;AAAA,EACxB,IAAA,EAAM,UAAA;AAAA,EACN,OAAA,EAAAA,QAAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAc,IAAA,EAAc;AAC1B,IAAA,IAAI,MAAM,CAAA,EAAG,YAAA,CAAa,MAAM,MAAM,CAAC,CAAA,cAAA,EAAiB,IAAI,CAAA,CAAE,CAAA;AAAA,EAChE,CAAA;AAAA,EACA,YAAY,OAAA,EAAkB;AAC5B,IAAA,UAAA,EAAY,YAAY,OAAO,CAAA;AAAA,EACjC;AACF,CAAC,CAAA;AAED,IAAI,UAAA,EAAY;AACd,EAAA,UAAA,CAAW,EAAA,CAAG,SAAA,EAAW,CAAC,IAAA,KAAS;AACjC,IAAC,UAAA,CAAmB,SAAA,GAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EAC1C,CAAC,CAAA;AACH;AAEA,IAAM,eAA4B,EAAC;AAEnC,IAAM,OAAA,GAAU,IAAI,cAAA,CAAe;AAAA,EACjC,MAAA,CAAO,EAAE,UAAA,EAAY,UAAA,EAAW,EAAuE;AACrG,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK;AAAA;AAAA;AAAA,MAGpB,EAAA,EAAI,cAAc,aAAa,CAAA;AAAA,MAC/B,QAAA,EAAU,EAAE,GAAA,EAAK,GAAA,EAAI;AAAA,MACrB,OAAO,CAAA,GAAI,IAAA,KAAoB,OAAA,CAAQ,GAAA,CAAI,GAAG,IAAI,CAAA;AAAA,MAClD,QAAA,EAAU,IAAI,IAAA,KAAoB;AAChC,QAAA,OAAA,CAAQ,KAAA,CAAM,GAAG,IAAI,CAAA;AACrB,QAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA,MACxB;AAAA,KACD,CAAA;AAED,IAAA,OAAO,0BAA0B,UAAA,EAAY;AAAA,MAC3C,WAAA,EAAa,IAAA;AAAA,MACb,IAAA;AAAA;AAAA;AAAA;AAAA,MAIA,OAAA,EAAS,CAAC,qBAAA,EAAuB,gBAAgB,CAAA;AAAA,MACjD,iBAAiB,YAAA,EAAmB;AAClC,QAAA,YAAA,CAAa,GAAA,GAAM;AAAA,UACjB,GAAG,YAAA,CAAa,GAAA;AAAA,UAChB,GAAG,YAAA,CAAa,IAAA;AAAA,UAChB,GAAG,YAAA,CAAa,MAAA;AAAA,UAChB,MAAA,EAAQ;AAAA,SACV;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH,CAAA;AAAA,EACA,QAAQ,KAAA,EAAgB;AACtB,IAAC,UAAA,CAAmB,WAAA,CAAY,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,YAAA,EAAc,CAAC,GAAG,YAAY,CAAA,EAAG,CAAA;AACzF,IAAA,YAAA,CAAa,MAAA,GAAS,CAAA;AAAA,EACxB;AACF,CAAC,CAAA;AAEA,UAAA,CAAmB,SAAA,GAAY,CAAC,KAAA,KAAmB,OAAA,CAAQ,OAAO,KAAK,CAAA","file":"rolldown-wasi-worker.js","sourcesContent":["/**\n * A Rolldown WASI worker thread whose filesystem is the container's.\n *\n * Rolldown's npm package ships two of these. The browser one builds its\n * filesystem from an in-memory volume proxied back to the main thread; the\n * Node one calls `node:wasi` with `preopens: { \"/\": \"/\" }` and reads the real\n * disk. Neither is usable as-is here: the browser file wants browser worker\n * globals, and the Node file wants the host's filesystem — which is precisely\n * the thing a container must not hand to the code running inside it.\n *\n * So this is the crossing of the two: Node's worker plumbing around the\n * browser's filesystem. Every path Rolldown opens on this thread is forwarded\n * to the main thread and served out of the memory volume the container mirrors\n * itself into, so the bundler and the rest of the container see one filesystem.\n *\n * Bundled as its own entry point, because a worker is fetched as its own\n * module graph rather than through the main bundle.\n */\n\nimport { createRequire } from \"node:module\";\nimport { readFileSync } from \"node:fs\";\nimport { parentPort, workerData, Worker } from \"node:worker_threads\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Resolved against the binding's own location, not this file's.\n *\n * `@napi-rs/wasm-runtime` arrives as a dependency of the Rolldown binding,\n * which an installer is free to place anywhere — nested, hoisted, in a store\n * behind a symlink. Anchoring the lookup to the package that actually depends\n * on it is what keeps this working under npm, pnpm and Yarn alike.\n */\nconst options = (workerData ?? {}) as { runtimeAnchor?: string; fsModuleUrl?: string };\nconst require = createRequire(options.runtimeAnchor ?? import.meta.url);\n\nconst {\n instantiateNapiModuleSync,\n MessageHandler,\n WASI,\n createFsProxy,\n emnapiAsyncWorkPlugin,\n emnapiTSFNPlugin,\n} = require(\"@napi-rs/wasm-runtime\");\n/* Passed in as a resolved URL: the runtime publishes `./fs` to `import` only,\n * so it cannot be required, and resolving it from here would assume the\n * installer hoisted the package next to this worker. */\nconst { memfsExported } = await import(options.fsModuleUrl!);\n\n/**\n * The browser worker globals `MessageHandler` is written against.\n *\n * emnapi decides how to talk to a thread from the environment it finds, and\n * the handler itself is written for a browser worker: it is handed events and\n * replies with a bare `postMessage`. Node's port is bridged onto those names\n * rather than the handler being rewritten.\n */\nObject.assign(globalThis, {\n self: globalThis,\n require,\n Worker,\n importScripts(file: string) {\n (0, eval)(`${readFileSync(file, \"utf8\")}//# sourceURL=${file}`);\n },\n postMessage(message: unknown) {\n parentPort?.postMessage(message);\n },\n});\n\nif (parentPort) {\n parentPort.on(\"message\", (data) => {\n (globalThis as any).onmessage?.({ data });\n });\n}\n\nconst errorOutputs: unknown[][] = [];\n\nconst handler = new MessageHandler({\n onLoad({ wasmModule, wasmMemory }: { wasmModule: WebAssembly.Module; wasmMemory: WebAssembly.Memory }) {\n const wasi = new WASI({\n /* The proxy is the whole point: every syscall goes to the main thread,\n * which answers from the volume the container keeps in step. */\n fs: createFsProxy(memfsExported),\n preopens: { \"/\": \"/\" },\n print: (...args: unknown[]) => console.log(...args),\n printErr: (...args: unknown[]) => {\n console.error(...args);\n errorOutputs.push(args);\n },\n });\n\n return instantiateNapiModuleSync(wasmModule, {\n childThread: true,\n wasi,\n /* The wasm links a \"basic\" emnapi archive with no C implementations of\n * async work or threadsafe functions, so every thread has to bring the\n * JavaScript ones. */\n plugins: [emnapiAsyncWorkPlugin, emnapiTSFNPlugin],\n overwriteImports(importObject: any) {\n importObject.env = {\n ...importObject.env,\n ...importObject.napi,\n ...importObject.emnapi,\n memory: wasmMemory,\n };\n },\n });\n },\n onError(error: unknown) {\n (globalThis as any).postMessage({ type: \"error\", error, errorOutputs: [...errorOutputs] });\n errorOutputs.length = 0;\n },\n});\n\n(globalThis as any).onmessage = (event: unknown) => handler.handle(event);\n"]}
|
package/dist/worker-entry.js
CHANGED
|
@@ -29613,6 +29613,7 @@ function createCoreModules(options) {
|
|
|
29613
29613
|
zlib: zlib_module_default
|
|
29614
29614
|
};
|
|
29615
29615
|
for (const name of stubNames) builtins[name] = createUnsupportedModule(name);
|
|
29616
|
+
builtins.net = createNetModule();
|
|
29616
29617
|
const globals = {
|
|
29617
29618
|
Buffer: Buffer2,
|
|
29618
29619
|
console: consoleObject,
|
|
@@ -30441,15 +30442,43 @@ function createStreamPromises() {
|
|
|
30441
30442
|
})
|
|
30442
30443
|
};
|
|
30443
30444
|
}
|
|
30444
|
-
function createUnsupportedModule(name) {
|
|
30445
|
+
function createUnsupportedModule(name, supported = {}) {
|
|
30445
30446
|
const unsupported = () => {
|
|
30446
30447
|
const error = new Error(`${name} is unavailable in the browser runtime`);
|
|
30447
30448
|
error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
|
|
30448
30449
|
throw error;
|
|
30449
30450
|
};
|
|
30450
|
-
|
|
30451
|
-
|
|
30452
|
-
|
|
30451
|
+
const target = { unsupported, ...supported };
|
|
30452
|
+
const module = new Proxy(target, {
|
|
30453
|
+
get(object, key) {
|
|
30454
|
+
if (key === "default") return module;
|
|
30455
|
+
return key in object ? object[key] : unsupported;
|
|
30456
|
+
}
|
|
30457
|
+
});
|
|
30458
|
+
return module;
|
|
30459
|
+
}
|
|
30460
|
+
function createNetModule() {
|
|
30461
|
+
const isIPv4 = (value) => {
|
|
30462
|
+
const parts = String(value).split(".");
|
|
30463
|
+
return parts.length === 4 && parts.every((part) => /^\d{1,3}$/.test(part) && Number(part) <= 255 && String(Number(part)) === part);
|
|
30464
|
+
};
|
|
30465
|
+
const isIPv6 = (value) => {
|
|
30466
|
+
const text = String(value);
|
|
30467
|
+
if (!text.includes(":")) return false;
|
|
30468
|
+
const [head, tail] = [text.slice(0, text.lastIndexOf(":")), text.slice(text.lastIndexOf(":") + 1)];
|
|
30469
|
+
const normalised = isIPv4(tail) ? `${head}:0:0` : text;
|
|
30470
|
+
const halves = normalised.split("::");
|
|
30471
|
+
if (halves.length > 2) return false;
|
|
30472
|
+
const groups = halves.map((half) => half === "" ? [] : half.split(":"));
|
|
30473
|
+
if (groups.some((half) => half.some((group) => !/^[0-9a-fA-F]{1,4}$/.test(group)))) return false;
|
|
30474
|
+
const count = groups.reduce((total, half) => total + half.length, 0);
|
|
30475
|
+
return halves.length === 2 ? count <= 7 : count === 8;
|
|
30476
|
+
};
|
|
30477
|
+
return createUnsupportedModule("net", {
|
|
30478
|
+
isIPv4,
|
|
30479
|
+
isIPv6,
|
|
30480
|
+
isIP: (value) => isIPv4(value) ? 4 : isIPv6(value) ? 6 : 0
|
|
30481
|
+
});
|
|
30453
30482
|
}
|
|
30454
30483
|
var stubNames = ["cluster", "dgram", "diagnostics_channel", "domain", "http2", "inspector", "net", "tls", "v8", "vm", "worker_threads"];
|
|
30455
30484
|
var builtinNames = [
|