sandboxedjs 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4040,6 +4040,294 @@ var init_builtins = __esm({
4040
4040
  }
4041
4041
  });
4042
4042
 
4043
+ // src/util/binary.ts
4044
+ var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
4045
+ async function nodeBuiltin(name) {
4046
+ const specifier = `node:${name}`;
4047
+ return await import(
4048
+ /* @vite-ignore */
4049
+ /* webpackIgnore: true */
4050
+ specifier
4051
+ );
4052
+ }
4053
+ var zlibPromise = null;
4054
+ function nodeZlib() {
4055
+ zlibPromise ??= nodeBuiltin("zlib");
4056
+ return zlibPromise;
4057
+ }
4058
+ async function throughStream(data, stream) {
4059
+ const source = new Blob([data]).stream();
4060
+ const piped = source.pipeThrough(stream);
4061
+ return new Uint8Array(await new Response(piped).arrayBuffer());
4062
+ }
4063
+ async function gzip(data) {
4064
+ if (isNode) return new Uint8Array((await nodeZlib()).gzipSync(data));
4065
+ return throughStream(data, new CompressionStream("gzip"));
4066
+ }
4067
+ async function gunzip(data) {
4068
+ if (isNode) return new Uint8Array((await nodeZlib()).gunzipSync(data));
4069
+ return throughStream(data, new DecompressionStream("gzip"));
4070
+ }
4071
+ async function deflate(data) {
4072
+ if (isNode) return new Uint8Array((await nodeZlib()).deflateSync(data));
4073
+ return throughStream(data, new CompressionStream("deflate"));
4074
+ }
4075
+ async function inflate(data) {
4076
+ if (isNode) return new Uint8Array((await nodeZlib()).inflateSync(data));
4077
+ return throughStream(data, new DecompressionStream("deflate"));
4078
+ }
4079
+ async function inflateRaw(data) {
4080
+ if (isNode) return new Uint8Array((await nodeZlib()).inflateRawSync(data));
4081
+ return throughStream(data, new DecompressionStream("deflate-raw"));
4082
+ }
4083
+ var cryptoPromise = null;
4084
+ function nodeCrypto() {
4085
+ cryptoPromise ??= nodeBuiltin("crypto");
4086
+ return cryptoPromise;
4087
+ }
4088
+ var SUBTLE_NAMES = {
4089
+ sha1: "SHA-1",
4090
+ sha256: "SHA-256",
4091
+ sha384: "SHA-384",
4092
+ sha512: "SHA-512"
4093
+ };
4094
+ var UnsupportedAlgorithmError = class extends Error {
4095
+ constructor(algorithm) {
4096
+ super(`${algorithm} is not available in this environment`);
4097
+ this.name = "UnsupportedAlgorithmError";
4098
+ }
4099
+ };
4100
+ async function digestHex(algorithm, data) {
4101
+ if (isNode) {
4102
+ const { createHash } = await nodeCrypto();
4103
+ return createHash(algorithm).update(data).digest("hex");
4104
+ }
4105
+ if (algorithm === "md5") return md5Hex(data);
4106
+ const name = SUBTLE_NAMES[algorithm];
4107
+ if (!name) throw new UnsupportedAlgorithmError(algorithm);
4108
+ const buffer = await crypto.subtle.digest(name, data);
4109
+ return toHex(new Uint8Array(buffer));
4110
+ }
4111
+ async function randomUuid() {
4112
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
4113
+ const { randomUUID } = await nodeCrypto();
4114
+ return randomUUID();
4115
+ }
4116
+ function toHex(bytes) {
4117
+ let out = "";
4118
+ for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
4119
+ return out;
4120
+ }
4121
+ function md5Hex(input) {
4122
+ const S = [
4123
+ 7,
4124
+ 12,
4125
+ 17,
4126
+ 22,
4127
+ 7,
4128
+ 12,
4129
+ 17,
4130
+ 22,
4131
+ 7,
4132
+ 12,
4133
+ 17,
4134
+ 22,
4135
+ 7,
4136
+ 12,
4137
+ 17,
4138
+ 22,
4139
+ 5,
4140
+ 9,
4141
+ 14,
4142
+ 20,
4143
+ 5,
4144
+ 9,
4145
+ 14,
4146
+ 20,
4147
+ 5,
4148
+ 9,
4149
+ 14,
4150
+ 20,
4151
+ 5,
4152
+ 9,
4153
+ 14,
4154
+ 20,
4155
+ 4,
4156
+ 11,
4157
+ 16,
4158
+ 23,
4159
+ 4,
4160
+ 11,
4161
+ 16,
4162
+ 23,
4163
+ 4,
4164
+ 11,
4165
+ 16,
4166
+ 23,
4167
+ 4,
4168
+ 11,
4169
+ 16,
4170
+ 23,
4171
+ 6,
4172
+ 10,
4173
+ 15,
4174
+ 21,
4175
+ 6,
4176
+ 10,
4177
+ 15,
4178
+ 21,
4179
+ 6,
4180
+ 10,
4181
+ 15,
4182
+ 21,
4183
+ 6,
4184
+ 10,
4185
+ 15,
4186
+ 21
4187
+ ];
4188
+ const K = new Uint32Array(64);
4189
+ for (let i = 0; i < 64; i++) K[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32);
4190
+ const bitLength = input.length * 8;
4191
+ const padded = new Uint8Array(((input.length + 8 >> 6) + 1) * 64);
4192
+ padded.set(input);
4193
+ padded[input.length] = 128;
4194
+ const view = new DataView(padded.buffer);
4195
+ view.setUint32(padded.length - 8, bitLength >>> 0, true);
4196
+ view.setUint32(padded.length - 4, Math.floor(bitLength / 2 ** 32), true);
4197
+ let a0 = 1732584193;
4198
+ let b0 = 4023233417;
4199
+ let c0 = 2562383102;
4200
+ let d0 = 271733878;
4201
+ for (let chunk = 0; chunk < padded.length; chunk += 64) {
4202
+ const M = new Uint32Array(16);
4203
+ for (let i = 0; i < 16; i++) M[i] = view.getUint32(chunk + i * 4, true);
4204
+ let [a, b, c, d] = [a0, b0, c0, d0];
4205
+ for (let i = 0; i < 64; i++) {
4206
+ let f;
4207
+ let g;
4208
+ if (i < 16) {
4209
+ f = b & c | ~b & d;
4210
+ g = i;
4211
+ } else if (i < 32) {
4212
+ f = d & b | ~d & c;
4213
+ g = (5 * i + 1) % 16;
4214
+ } else if (i < 48) {
4215
+ f = b ^ c ^ d;
4216
+ g = (3 * i + 5) % 16;
4217
+ } else {
4218
+ f = c ^ (b | ~d);
4219
+ g = 7 * i % 16;
4220
+ }
4221
+ const tmp = d;
4222
+ d = c;
4223
+ c = b;
4224
+ const sum = a + f + K[i] + M[g] >>> 0;
4225
+ b = b + (sum << S[i] | sum >>> 32 - S[i]) >>> 0;
4226
+ a = tmp;
4227
+ }
4228
+ a0 = a0 + a >>> 0;
4229
+ b0 = b0 + b >>> 0;
4230
+ c0 = c0 + c >>> 0;
4231
+ d0 = d0 + d >>> 0;
4232
+ }
4233
+ const out = new Uint8Array(16);
4234
+ new DataView(out.buffer).setUint32(0, a0, true);
4235
+ new DataView(out.buffer).setUint32(4, b0, true);
4236
+ new DataView(out.buffer).setUint32(8, c0, true);
4237
+ new DataView(out.buffer).setUint32(12, d0, true);
4238
+ return toHex(out);
4239
+ }
4240
+
4241
+ // src/runtime/esbuild-host.ts
4242
+ var INITIALIZE_CALLS = /\.initialize\(\s*\{\s*wasmURL:[^}]*\}\s*\)/g;
4243
+ var installed = null;
4244
+ function installEsbuildRuntime() {
4245
+ installed ??= install().catch((error) => {
4246
+ if (process.env.SANDBOXEDJS_DEBUG) {
4247
+ console.error("[sandboxedjs] esbuild runtime unavailable:", error);
4248
+ }
4249
+ });
4250
+ return installed;
4251
+ }
4252
+ async function install() {
4253
+ const workerPath = await buildPatchedWorker();
4254
+ if (!workerPath) return;
4255
+ const { createNodeHost, setRuntimeHost } = await import('@scelar/nodepod/headless');
4256
+ setRuntimeHost(createNodeHost({ workerPath }));
4257
+ }
4258
+ async function buildPatchedWorker() {
4259
+ const { createRequire } = await nodeBuiltin("module");
4260
+ const fs = await nodeBuiltin("fs/promises");
4261
+ const os = await nodeBuiltin("os");
4262
+ const path = await nodeBuiltin("path");
4263
+ const url = await nodeBuiltin("url");
4264
+ const crypto2 = await nodeBuiltin("crypto");
4265
+ const require2 = createRequire(path.join(process.cwd(), "index.js"));
4266
+ let workerPath;
4267
+ let wasmPath;
4268
+ let browserEntry;
4269
+ try {
4270
+ workerPath = path.join(
4271
+ path.dirname(require2.resolve("@scelar/nodepod/headless")),
4272
+ "__worker__.js"
4273
+ );
4274
+ const esbuildRoot = path.dirname(require2.resolve("esbuild-wasm/package.json"));
4275
+ wasmPath = path.join(esbuildRoot, "esbuild.wasm");
4276
+ browserEntry = path.join(esbuildRoot, "esm", "browser.min.js");
4277
+ } catch {
4278
+ return null;
4279
+ }
4280
+ const [source, wasmStat] = await Promise.all([
4281
+ fs.readFile(workerPath, "utf8"),
4282
+ fs.stat(wasmPath)
4283
+ ]);
4284
+ if (!INITIALIZE_CALLS.test(source)) {
4285
+ return null;
4286
+ }
4287
+ INITIALIZE_CALLS.lastIndex = 0;
4288
+ const WASM_URL = /`https:\/\/esm\.sh\/esbuild-wasm@\$\{[A-Za-z0-9_$]+\}\/esbuild\.wasm`/g;
4289
+ const MODULE_URL = /`https:\/\/esm\.sh\/esbuild-wasm@\$\{[A-Za-z0-9_$]+\}`/g;
4290
+ const initCall = `.initialize(await __sandboxedjsEsbuildInit(${JSON.stringify(wasmPath)}, ${JSON.stringify(url.pathToFileURL(wasmPath).href)}))`;
4291
+ const patched = [
4292
+ // The helper is needed by the bundle itself and again inside the nested
4293
+ // worker it builds from a template, which is a separate script.
4294
+ INIT_HELPER,
4295
+ source.replace(WASM_URL, JSON.stringify(url.pathToFileURL(wasmPath).href)).replace(MODULE_URL, JSON.stringify(url.pathToFileURL(browserEntry).href)).replace(INITIALIZE_CALLS, initCall).replace("function ensureEsbuild() {", `${INIT_HELPER}
4296
+
4297
+ function ensureEsbuild() {`)
4298
+ ].join("\n");
4299
+ const fingerprint = crypto2.createHash("sha256").update(`${source.length}:${wasmStat.size}:${patched.length}`).digest("hex").slice(0, 16);
4300
+ const cached = path.join(os.tmpdir(), `sandboxedjs-worker-${fingerprint}.js`);
4301
+ try {
4302
+ await fs.access(cached);
4303
+ } catch {
4304
+ const staging = `${cached}.${process.pid}.tmp`;
4305
+ await fs.writeFile(staging, patched, "utf8");
4306
+ await fs.rename(staging, cached);
4307
+ }
4308
+ return cached;
4309
+ }
4310
+ var INIT_HELPER = `let __sandboxedjsWasmUrl = null;
4311
+ async function __sandboxedjsEsbuildInit(wasmPath, wasmUrl) {
4312
+ // esbuild-wasm is a browser build: it resolves its wasm against document
4313
+ // location. There is no document here, and a bare origin is enough.
4314
+ if (typeof globalThis.location === "undefined") {
4315
+ globalThis.location = { href: "file:///", origin: "null", protocol: "file:" };
4316
+ }
4317
+ // esbuild-wasm fetches its wasm, and fetch cannot read a file: URL, so the
4318
+ // bytes are inlined as a data: URL instead \u2014 the one scheme both the ESM
4319
+ // loader and fetch accept. Built once and reused; it is ~15MB of base64.
4320
+ // Handing over a pre-compiled WebAssembly.Module instead does not work: the
4321
+ // Go glue supplies its own import object and rejects a foreign module.
4322
+ try {
4323
+ if (__sandboxedjsWasmUrl === null && typeof require === "function") {
4324
+ const bytes = require("node:fs").readFileSync(wasmPath);
4325
+ __sandboxedjsWasmUrl = "data:application/wasm;base64," + bytes.toString("base64");
4326
+ }
4327
+ } catch (err) { /* fall back to the file URL below */ }
4328
+ return { wasmURL: __sandboxedjsWasmUrl || wasmUrl, worker: false };
4329
+ }`;
4330
+
4043
4331
  // src/fs/vfs.ts
4044
4332
  init_errno();
4045
4333
  init_path();
@@ -15132,206 +15420,6 @@ var commands5 = [grep, find, xargs, diff, cmp];
15132
15420
  // src/bin/archive.ts
15133
15421
  init_mode();
15134
15422
  init_path();
15135
-
15136
- // src/util/binary.ts
15137
- var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
15138
- async function nodeBuiltin(name) {
15139
- const specifier = `node:${name}`;
15140
- return await import(
15141
- /* @vite-ignore */
15142
- /* webpackIgnore: true */
15143
- specifier
15144
- );
15145
- }
15146
- var zlibPromise = null;
15147
- function nodeZlib() {
15148
- zlibPromise ??= nodeBuiltin("zlib");
15149
- return zlibPromise;
15150
- }
15151
- async function throughStream(data, stream) {
15152
- const source = new Blob([data]).stream();
15153
- const piped = source.pipeThrough(stream);
15154
- return new Uint8Array(await new Response(piped).arrayBuffer());
15155
- }
15156
- async function gzip(data) {
15157
- if (isNode) return new Uint8Array((await nodeZlib()).gzipSync(data));
15158
- return throughStream(data, new CompressionStream("gzip"));
15159
- }
15160
- async function gunzip(data) {
15161
- if (isNode) return new Uint8Array((await nodeZlib()).gunzipSync(data));
15162
- return throughStream(data, new DecompressionStream("gzip"));
15163
- }
15164
- async function deflate(data) {
15165
- if (isNode) return new Uint8Array((await nodeZlib()).deflateSync(data));
15166
- return throughStream(data, new CompressionStream("deflate"));
15167
- }
15168
- async function inflate(data) {
15169
- if (isNode) return new Uint8Array((await nodeZlib()).inflateSync(data));
15170
- return throughStream(data, new DecompressionStream("deflate"));
15171
- }
15172
- async function inflateRaw(data) {
15173
- if (isNode) return new Uint8Array((await nodeZlib()).inflateRawSync(data));
15174
- return throughStream(data, new DecompressionStream("deflate-raw"));
15175
- }
15176
- var cryptoPromise = null;
15177
- function nodeCrypto() {
15178
- cryptoPromise ??= nodeBuiltin("crypto");
15179
- return cryptoPromise;
15180
- }
15181
- var SUBTLE_NAMES = {
15182
- sha1: "SHA-1",
15183
- sha256: "SHA-256",
15184
- sha384: "SHA-384",
15185
- sha512: "SHA-512"
15186
- };
15187
- var UnsupportedAlgorithmError = class extends Error {
15188
- constructor(algorithm) {
15189
- super(`${algorithm} is not available in this environment`);
15190
- this.name = "UnsupportedAlgorithmError";
15191
- }
15192
- };
15193
- async function digestHex(algorithm, data) {
15194
- if (isNode) {
15195
- const { createHash } = await nodeCrypto();
15196
- return createHash(algorithm).update(data).digest("hex");
15197
- }
15198
- if (algorithm === "md5") return md5Hex(data);
15199
- const name = SUBTLE_NAMES[algorithm];
15200
- if (!name) throw new UnsupportedAlgorithmError(algorithm);
15201
- const buffer = await crypto.subtle.digest(name, data);
15202
- return toHex(new Uint8Array(buffer));
15203
- }
15204
- async function randomUuid() {
15205
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
15206
- const { randomUUID } = await nodeCrypto();
15207
- return randomUUID();
15208
- }
15209
- function toHex(bytes) {
15210
- let out = "";
15211
- for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
15212
- return out;
15213
- }
15214
- function md5Hex(input) {
15215
- const S = [
15216
- 7,
15217
- 12,
15218
- 17,
15219
- 22,
15220
- 7,
15221
- 12,
15222
- 17,
15223
- 22,
15224
- 7,
15225
- 12,
15226
- 17,
15227
- 22,
15228
- 7,
15229
- 12,
15230
- 17,
15231
- 22,
15232
- 5,
15233
- 9,
15234
- 14,
15235
- 20,
15236
- 5,
15237
- 9,
15238
- 14,
15239
- 20,
15240
- 5,
15241
- 9,
15242
- 14,
15243
- 20,
15244
- 5,
15245
- 9,
15246
- 14,
15247
- 20,
15248
- 4,
15249
- 11,
15250
- 16,
15251
- 23,
15252
- 4,
15253
- 11,
15254
- 16,
15255
- 23,
15256
- 4,
15257
- 11,
15258
- 16,
15259
- 23,
15260
- 4,
15261
- 11,
15262
- 16,
15263
- 23,
15264
- 6,
15265
- 10,
15266
- 15,
15267
- 21,
15268
- 6,
15269
- 10,
15270
- 15,
15271
- 21,
15272
- 6,
15273
- 10,
15274
- 15,
15275
- 21,
15276
- 6,
15277
- 10,
15278
- 15,
15279
- 21
15280
- ];
15281
- const K = new Uint32Array(64);
15282
- for (let i = 0; i < 64; i++) K[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32);
15283
- const bitLength = input.length * 8;
15284
- const padded = new Uint8Array(((input.length + 8 >> 6) + 1) * 64);
15285
- padded.set(input);
15286
- padded[input.length] = 128;
15287
- const view = new DataView(padded.buffer);
15288
- view.setUint32(padded.length - 8, bitLength >>> 0, true);
15289
- view.setUint32(padded.length - 4, Math.floor(bitLength / 2 ** 32), true);
15290
- let a0 = 1732584193;
15291
- let b0 = 4023233417;
15292
- let c0 = 2562383102;
15293
- let d0 = 271733878;
15294
- for (let chunk = 0; chunk < padded.length; chunk += 64) {
15295
- const M = new Uint32Array(16);
15296
- for (let i = 0; i < 16; i++) M[i] = view.getUint32(chunk + i * 4, true);
15297
- let [a, b, c, d] = [a0, b0, c0, d0];
15298
- for (let i = 0; i < 64; i++) {
15299
- let f;
15300
- let g;
15301
- if (i < 16) {
15302
- f = b & c | ~b & d;
15303
- g = i;
15304
- } else if (i < 32) {
15305
- f = d & b | ~d & c;
15306
- g = (5 * i + 1) % 16;
15307
- } else if (i < 48) {
15308
- f = b ^ c ^ d;
15309
- g = (3 * i + 5) % 16;
15310
- } else {
15311
- f = c ^ (b | ~d);
15312
- g = 7 * i % 16;
15313
- }
15314
- const tmp = d;
15315
- d = c;
15316
- c = b;
15317
- const sum = a + f + K[i] + M[g] >>> 0;
15318
- b = b + (sum << S[i] | sum >>> 32 - S[i]) >>> 0;
15319
- a = tmp;
15320
- }
15321
- a0 = a0 + a >>> 0;
15322
- b0 = b0 + b >>> 0;
15323
- c0 = c0 + c >>> 0;
15324
- d0 = d0 + d >>> 0;
15325
- }
15326
- const out = new Uint8Array(16);
15327
- new DataView(out.buffer).setUint32(0, a0, true);
15328
- new DataView(out.buffer).setUint32(4, b0, true);
15329
- new DataView(out.buffer).setUint32(8, c0, true);
15330
- new DataView(out.buffer).setUint32(12, d0, true);
15331
- return toHex(out);
15332
- }
15333
-
15334
- // src/bin/archive.ts
15335
15423
  var BLOCK = 512;
15336
15424
  var encoder4 = new TextEncoder();
15337
15425
  var decoder6 = new TextDecoder();
@@ -16639,7 +16727,7 @@ var watch = defineCommand({
16639
16727
  return 0;
16640
16728
  }
16641
16729
  });
16642
- var install = defineCommand({
16730
+ var install2 = defineCommand({
16643
16731
  name: "install",
16644
16732
  path: "/usr/bin/install",
16645
16733
  summary: "copy files and set attributes",
@@ -16758,7 +16846,7 @@ var commands9 = [
16758
16846
  timeoutCmd,
16759
16847
  nohup,
16760
16848
  watch,
16761
- install,
16849
+ install2,
16762
16850
  niceCmd,
16763
16851
  timeCmd
16764
16852
  ];
@@ -18584,12 +18672,12 @@ unless the container was created with network: { allowOutbound: true }.`,
18584
18672
  }
18585
18673
  ctx.stderr.write(`npx: installing ${packageSpec}...
18586
18674
  `);
18587
- const installed = await installPackages(ctx, [packageSpec], {
18675
+ const installed2 = await installPackages(ctx, [packageSpec], {
18588
18676
  cwd: root,
18589
18677
  save: false,
18590
18678
  quiet: true
18591
18679
  });
18592
- if (installed !== 0) return installed;
18680
+ if (installed2 !== 0) return installed2;
18593
18681
  if (!findLocalBin(ctx, command)) {
18594
18682
  const binaries = packageBinaries(ctx, root, packageName);
18595
18683
  const chosen = binaries.includes(command) ? command : binaries[0];
@@ -19018,6 +19106,7 @@ var Container = class _Container {
19018
19106
  }
19019
19107
  // ── boot ──────────────────────────────────────────────────────────────────
19020
19108
  static async create(opts = {}) {
19109
+ if (!opts.pod) await installEsbuildRuntime();
19021
19110
  const pod = opts.pod ?? await Nodepod.boot({
19022
19111
  headless: true,
19023
19112
  serviceWorker: false,