@secure-exec/nodejs 0.2.0-rc.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 (68) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +7 -0
  3. package/dist/bindings.d.ts +31 -0
  4. package/dist/bindings.js +67 -0
  5. package/dist/bridge/active-handles.d.ts +22 -0
  6. package/dist/bridge/active-handles.js +112 -0
  7. package/dist/bridge/child-process.d.ts +99 -0
  8. package/dist/bridge/child-process.js +672 -0
  9. package/dist/bridge/dispatch.d.ts +2 -0
  10. package/dist/bridge/dispatch.js +40 -0
  11. package/dist/bridge/fs.d.ts +502 -0
  12. package/dist/bridge/fs.js +3307 -0
  13. package/dist/bridge/index.d.ts +10 -0
  14. package/dist/bridge/index.js +41 -0
  15. package/dist/bridge/module.d.ts +75 -0
  16. package/dist/bridge/module.js +325 -0
  17. package/dist/bridge/network.d.ts +1093 -0
  18. package/dist/bridge/network.js +8651 -0
  19. package/dist/bridge/os.d.ts +13 -0
  20. package/dist/bridge/os.js +256 -0
  21. package/dist/bridge/polyfills.d.ts +9 -0
  22. package/dist/bridge/polyfills.js +67 -0
  23. package/dist/bridge/process.d.ts +121 -0
  24. package/dist/bridge/process.js +1382 -0
  25. package/dist/bridge/whatwg-url.d.ts +67 -0
  26. package/dist/bridge/whatwg-url.js +712 -0
  27. package/dist/bridge-contract.d.ts +774 -0
  28. package/dist/bridge-contract.js +172 -0
  29. package/dist/bridge-handlers.d.ts +199 -0
  30. package/dist/bridge-handlers.js +4263 -0
  31. package/dist/bridge-loader.d.ts +9 -0
  32. package/dist/bridge-loader.js +87 -0
  33. package/dist/bridge-setup.d.ts +1 -0
  34. package/dist/bridge-setup.js +3 -0
  35. package/dist/bridge.js +21652 -0
  36. package/dist/builtin-modules.d.ts +25 -0
  37. package/dist/builtin-modules.js +312 -0
  38. package/dist/default-network-adapter.d.ts +13 -0
  39. package/dist/default-network-adapter.js +351 -0
  40. package/dist/driver.d.ts +87 -0
  41. package/dist/driver.js +191 -0
  42. package/dist/esm-compiler.d.ts +14 -0
  43. package/dist/esm-compiler.js +68 -0
  44. package/dist/execution-driver.d.ts +37 -0
  45. package/dist/execution-driver.js +977 -0
  46. package/dist/host-network-adapter.d.ts +7 -0
  47. package/dist/host-network-adapter.js +279 -0
  48. package/dist/index.d.ts +20 -0
  49. package/dist/index.js +23 -0
  50. package/dist/isolate-bootstrap.d.ts +86 -0
  51. package/dist/isolate-bootstrap.js +125 -0
  52. package/dist/ivm-compat.d.ts +7 -0
  53. package/dist/ivm-compat.js +31 -0
  54. package/dist/kernel-runtime.d.ts +58 -0
  55. package/dist/kernel-runtime.js +535 -0
  56. package/dist/module-access.d.ts +75 -0
  57. package/dist/module-access.js +606 -0
  58. package/dist/module-resolver.d.ts +8 -0
  59. package/dist/module-resolver.js +150 -0
  60. package/dist/os-filesystem.d.ts +42 -0
  61. package/dist/os-filesystem.js +161 -0
  62. package/dist/package-bundler.d.ts +36 -0
  63. package/dist/package-bundler.js +497 -0
  64. package/dist/polyfills.d.ts +17 -0
  65. package/dist/polyfills.js +97 -0
  66. package/dist/worker-adapter.d.ts +21 -0
  67. package/dist/worker-adapter.js +34 -0
  68. package/package.json +123 -0
@@ -0,0 +1,1382 @@
1
+ // Process module polyfill for the sandbox
2
+ // Provides Node.js process object and global polyfills for sandbox compatibility
3
+ // Re-export TextEncoder/TextDecoder from polyfills (polyfills.ts is imported first in index.ts)
4
+ import { TextEncoder, TextDecoder } from "./polyfills.js";
5
+ import { URL, URLSearchParams, installWhatwgUrlGlobals, } from "./whatwg-url.js";
6
+ // Use buffer package for spec-compliant Buffer implementation
7
+ import { Buffer as BufferPolyfill } from "buffer";
8
+ import { exposeCustomGlobal, exposeMutableRuntimeStateGlobal, } from "@secure-exec/core/internal/shared/global-exposure";
9
+ import { bridgeDispatchSync } from "./dispatch.js";
10
+ // Get config with defaults
11
+ const config = {
12
+ platform: (typeof _processConfig !== "undefined" && _processConfig.platform) ||
13
+ "linux",
14
+ arch: (typeof _processConfig !== "undefined" && _processConfig.arch) || "x64",
15
+ version: (typeof _processConfig !== "undefined" && _processConfig.version) ||
16
+ "v22.0.0",
17
+ cwd: (typeof _processConfig !== "undefined" && _processConfig.cwd) || "/root",
18
+ env: (typeof _processConfig !== "undefined" && _processConfig.env) || {},
19
+ argv: (typeof _processConfig !== "undefined" && _processConfig.argv) || [
20
+ "node",
21
+ "script.js",
22
+ ],
23
+ execPath: (typeof _processConfig !== "undefined" && _processConfig.execPath) ||
24
+ "/usr/bin/node",
25
+ pid: (typeof _processConfig !== "undefined" && _processConfig.pid) || 1,
26
+ ppid: (typeof _processConfig !== "undefined" && _processConfig.ppid) || 0,
27
+ uid: (typeof _processConfig !== "undefined" && _processConfig.uid) || 0,
28
+ gid: (typeof _processConfig !== "undefined" && _processConfig.gid) || 0,
29
+ timingMitigation: (typeof _processConfig !== "undefined" && _processConfig.timingMitigation) ||
30
+ "off",
31
+ frozenTimeMs: typeof _processConfig !== "undefined" ? _processConfig.frozenTimeMs : undefined,
32
+ };
33
+ /** Get the current timestamp, returning a frozen value when timing mitigation is active. */
34
+ function getNowMs() {
35
+ if (config.timingMitigation === "freeze" &&
36
+ typeof config.frozenTimeMs === "number") {
37
+ return config.frozenTimeMs;
38
+ }
39
+ return typeof performance !== "undefined" && performance.now
40
+ ? performance.now()
41
+ : Date.now();
42
+ }
43
+ // Start time for uptime calculation
44
+ const _processStartTime = getNowMs();
45
+ const BUFFER_MAX_LENGTH = typeof BufferPolyfill.kMaxLength ===
46
+ "number"
47
+ ? BufferPolyfill.kMaxLength
48
+ : 2147483647;
49
+ const BUFFER_MAX_STRING_LENGTH = typeof BufferPolyfill.kStringMaxLength ===
50
+ "number"
51
+ ? BufferPolyfill.kStringMaxLength
52
+ : 536870888;
53
+ const BUFFER_CONSTANTS = Object.freeze({
54
+ MAX_LENGTH: BUFFER_MAX_LENGTH,
55
+ MAX_STRING_LENGTH: BUFFER_MAX_STRING_LENGTH,
56
+ });
57
+ const bufferPolyfillMutable = BufferPolyfill;
58
+ if (typeof bufferPolyfillMutable.kMaxLength !== "number") {
59
+ bufferPolyfillMutable.kMaxLength = BUFFER_MAX_LENGTH;
60
+ }
61
+ if (typeof bufferPolyfillMutable.kStringMaxLength !== "number") {
62
+ bufferPolyfillMutable.kStringMaxLength = BUFFER_MAX_STRING_LENGTH;
63
+ }
64
+ if (typeof bufferPolyfillMutable.constants !== "object" ||
65
+ bufferPolyfillMutable.constants === null) {
66
+ bufferPolyfillMutable.constants = {
67
+ MAX_LENGTH: BUFFER_MAX_LENGTH,
68
+ MAX_STRING_LENGTH: BUFFER_MAX_STRING_LENGTH,
69
+ };
70
+ }
71
+ // Shim encoding-specific slice/write methods on Buffer.prototype.
72
+ // Node.js exposes these via internal V8 bindings (e.g. utf8Slice, latin1Write).
73
+ // Packages like ssh2 call them directly for performance.
74
+ const bufferProto = BufferPolyfill.prototype;
75
+ if (typeof bufferProto.utf8Slice !== "function") {
76
+ const encodings = ["utf8", "latin1", "ascii", "hex", "base64", "ucs2", "utf16le"];
77
+ for (const enc of encodings) {
78
+ if (typeof bufferProto[enc + "Slice"] !== "function") {
79
+ bufferProto[enc + "Slice"] = function (start, end) {
80
+ return this.toString(enc, start, end);
81
+ };
82
+ }
83
+ if (typeof bufferProto[enc + "Write"] !== "function") {
84
+ bufferProto[enc + "Write"] = function (string, offset, length) {
85
+ return this.write(string, offset ?? 0, length ?? (this.length - (offset ?? 0)), enc);
86
+ };
87
+ }
88
+ }
89
+ }
90
+ const bufferCtorMutable = BufferPolyfill;
91
+ if (typeof bufferCtorMutable.allocUnsafe === "function" &&
92
+ !bufferCtorMutable.allocUnsafe._secureExecPatched) {
93
+ const originalAllocUnsafe = bufferCtorMutable.allocUnsafe;
94
+ bufferCtorMutable.allocUnsafe = function patchedAllocUnsafe(size) {
95
+ try {
96
+ return originalAllocUnsafe.call(this, size);
97
+ }
98
+ catch (error) {
99
+ if (error instanceof RangeError &&
100
+ typeof size === "number" &&
101
+ size > BUFFER_MAX_LENGTH) {
102
+ throw new Error("Array buffer allocation failed");
103
+ }
104
+ throw error;
105
+ }
106
+ };
107
+ bufferCtorMutable.allocUnsafe._secureExecPatched = true;
108
+ }
109
+ // Exit code tracking
110
+ let _exitCode = 0;
111
+ let _exited = false;
112
+ /**
113
+ * Thrown by `process.exit()` to unwind the sandbox call stack. The host
114
+ * catches this to extract the exit code without killing the isolate.
115
+ */
116
+ export class ProcessExitError extends Error {
117
+ code;
118
+ constructor(code) {
119
+ super("process.exit(" + code + ")");
120
+ this.name = "ProcessExitError";
121
+ this.code = code;
122
+ }
123
+ }
124
+ // Make available globally
125
+ exposeCustomGlobal("ProcessExitError", ProcessExitError);
126
+ // Signal name → number mapping (POSIX standard)
127
+ const _signalNumbers = {
128
+ SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5, SIGABRT: 6,
129
+ SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10, SIGSEGV: 11, SIGUSR2: 12,
130
+ SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15, SIGCHLD: 17, SIGCONT: 18,
131
+ SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21, SIGTTOU: 22, SIGURG: 23,
132
+ SIGXCPU: 24, SIGXFSZ: 25, SIGVTALRM: 26, SIGPROF: 27, SIGWINCH: 28,
133
+ SIGIO: 29, SIGPWR: 30, SIGSYS: 31,
134
+ };
135
+ function _resolveSignal(signal) {
136
+ if (signal === undefined || signal === null)
137
+ return 15; // default SIGTERM
138
+ if (typeof signal === "number")
139
+ return signal;
140
+ const num = _signalNumbers[signal];
141
+ if (num !== undefined)
142
+ return num;
143
+ throw new Error("Unknown signal: " + signal);
144
+ }
145
+ const _processListeners = {};
146
+ const _processOnceListeners = {};
147
+ let _processMaxListeners = 10;
148
+ const _processMaxListenersWarned = new Set();
149
+ function _addListener(event, listener, once = false) {
150
+ const target = once ? _processOnceListeners : _processListeners;
151
+ if (!target[event]) {
152
+ target[event] = [];
153
+ }
154
+ target[event].push(listener);
155
+ // Warn when exceeding maxListeners (Node.js behavior: warn, don't crash)
156
+ if (_processMaxListeners > 0 && !_processMaxListenersWarned.has(event)) {
157
+ const total = (_processListeners[event]?.length ?? 0) + (_processOnceListeners[event]?.length ?? 0);
158
+ if (total > _processMaxListeners) {
159
+ _processMaxListenersWarned.add(event);
160
+ const warning = `MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${total} ${event} listeners added to [process]. MaxListeners is ${_processMaxListeners}. Use emitter.setMaxListeners() to increase limit`;
161
+ // Use console.error to emit warning without recursion risk
162
+ if (typeof _error !== "undefined") {
163
+ _error.applySync(undefined, [warning]);
164
+ }
165
+ }
166
+ }
167
+ return process;
168
+ }
169
+ function _removeListener(event, listener) {
170
+ if (_processListeners[event]) {
171
+ const idx = _processListeners[event].indexOf(listener);
172
+ if (idx !== -1)
173
+ _processListeners[event].splice(idx, 1);
174
+ }
175
+ if (_processOnceListeners[event]) {
176
+ const idx = _processOnceListeners[event].indexOf(listener);
177
+ if (idx !== -1)
178
+ _processOnceListeners[event].splice(idx, 1);
179
+ }
180
+ return process;
181
+ }
182
+ function _emit(event, ...args) {
183
+ let handled = false;
184
+ // Regular listeners
185
+ if (_processListeners[event]) {
186
+ for (const listener of _processListeners[event]) {
187
+ listener(...args);
188
+ handled = true;
189
+ }
190
+ }
191
+ // Once listeners (remove after calling)
192
+ if (_processOnceListeners[event]) {
193
+ const listeners = _processOnceListeners[event].slice();
194
+ _processOnceListeners[event] = [];
195
+ for (const listener of listeners) {
196
+ listener(...args);
197
+ handled = true;
198
+ }
199
+ }
200
+ return handled;
201
+ }
202
+ function _getStdinIsTTY() {
203
+ return (typeof __runtimeTtyConfig !== "undefined" && __runtimeTtyConfig.stdinIsTTY) || false;
204
+ }
205
+ function _getStdoutIsTTY() {
206
+ return (typeof __runtimeTtyConfig !== "undefined" && __runtimeTtyConfig.stdoutIsTTY) || false;
207
+ }
208
+ function _getStderrIsTTY() {
209
+ return (typeof __runtimeTtyConfig !== "undefined" && __runtimeTtyConfig.stderrIsTTY) || false;
210
+ }
211
+ // Stdout stream
212
+ const _stdout = {
213
+ write(data) {
214
+ if (typeof _log !== "undefined") {
215
+ _log.applySync(undefined, [String(data).replace(/\n$/, "")]);
216
+ }
217
+ return true;
218
+ },
219
+ end() {
220
+ return this;
221
+ },
222
+ on() {
223
+ return this;
224
+ },
225
+ once() {
226
+ return this;
227
+ },
228
+ emit() {
229
+ return false;
230
+ },
231
+ writable: true,
232
+ get isTTY() { return _getStdoutIsTTY(); },
233
+ columns: 80,
234
+ rows: 24,
235
+ };
236
+ // Stderr stream
237
+ const _stderr = {
238
+ write(data) {
239
+ if (typeof _error !== "undefined") {
240
+ _error.applySync(undefined, [String(data).replace(/\n$/, "")]);
241
+ }
242
+ return true;
243
+ },
244
+ end() {
245
+ return this;
246
+ },
247
+ on() {
248
+ return this;
249
+ },
250
+ once() {
251
+ return this;
252
+ },
253
+ emit() {
254
+ return false;
255
+ },
256
+ writable: true,
257
+ get isTTY() { return _getStderrIsTTY(); },
258
+ columns: 80,
259
+ rows: 24,
260
+ };
261
+ const _stdinListeners = {};
262
+ const _stdinOnceListeners = {};
263
+ // Initialize stdin state as globals for external access
264
+ exposeMutableRuntimeStateGlobal("_stdinData", (typeof _processConfig !== "undefined" && _processConfig.stdin) || "");
265
+ exposeMutableRuntimeStateGlobal("_stdinPosition", 0);
266
+ exposeMutableRuntimeStateGlobal("_stdinEnded", false);
267
+ exposeMutableRuntimeStateGlobal("_stdinFlowMode", false);
268
+ // Getters for the globals
269
+ function getStdinData() { return globalThis._stdinData; }
270
+ function setStdinDataValue(v) { globalThis._stdinData = v; }
271
+ function getStdinPosition() { return globalThis._stdinPosition; }
272
+ function setStdinPosition(v) { globalThis._stdinPosition = v; }
273
+ function getStdinEnded() { return globalThis._stdinEnded; }
274
+ function setStdinEnded(v) { globalThis._stdinEnded = v; }
275
+ function getStdinFlowMode() { return globalThis._stdinFlowMode; }
276
+ function setStdinFlowMode(v) { globalThis._stdinFlowMode = v; }
277
+ function _emitStdinData() {
278
+ if (getStdinEnded() || !getStdinData())
279
+ return;
280
+ // In flowing mode, emit all remaining data
281
+ if (getStdinFlowMode() && getStdinPosition() < getStdinData().length) {
282
+ const chunk = getStdinData().slice(getStdinPosition());
283
+ setStdinPosition(getStdinData().length);
284
+ // Emit data event
285
+ const dataListeners = [...(_stdinListeners["data"] || []), ...(_stdinOnceListeners["data"] || [])];
286
+ _stdinOnceListeners["data"] = [];
287
+ for (const listener of dataListeners) {
288
+ listener(chunk);
289
+ }
290
+ // Emit end after all data
291
+ setStdinEnded(true);
292
+ const endListeners = [...(_stdinListeners["end"] || []), ...(_stdinOnceListeners["end"] || [])];
293
+ _stdinOnceListeners["end"] = [];
294
+ for (const listener of endListeners) {
295
+ listener();
296
+ }
297
+ // Emit close
298
+ const closeListeners = [...(_stdinListeners["close"] || []), ...(_stdinOnceListeners["close"] || [])];
299
+ _stdinOnceListeners["close"] = [];
300
+ for (const listener of closeListeners) {
301
+ listener();
302
+ }
303
+ }
304
+ }
305
+ const _stdin = {
306
+ readable: true,
307
+ paused: true,
308
+ encoding: null,
309
+ read(size) {
310
+ if (getStdinPosition() >= getStdinData().length)
311
+ return null;
312
+ const chunk = size ? getStdinData().slice(getStdinPosition(), getStdinPosition() + size) : getStdinData().slice(getStdinPosition());
313
+ setStdinPosition(getStdinPosition() + chunk.length);
314
+ return chunk;
315
+ },
316
+ on(event, listener) {
317
+ if (!_stdinListeners[event])
318
+ _stdinListeners[event] = [];
319
+ _stdinListeners[event].push(listener);
320
+ // When 'end' listener is added and we have data, emit everything synchronously
321
+ // This works because typical patterns register 'data' then 'end' listeners
322
+ if (event === "end" && getStdinData() && !getStdinEnded()) {
323
+ setStdinFlowMode(true);
324
+ // Emit synchronously - all listeners should be registered by now
325
+ _emitStdinData();
326
+ }
327
+ return this;
328
+ },
329
+ once(event, listener) {
330
+ if (!_stdinOnceListeners[event])
331
+ _stdinOnceListeners[event] = [];
332
+ _stdinOnceListeners[event].push(listener);
333
+ return this;
334
+ },
335
+ off(event, listener) {
336
+ if (_stdinListeners[event]) {
337
+ const idx = _stdinListeners[event].indexOf(listener);
338
+ if (idx !== -1)
339
+ _stdinListeners[event].splice(idx, 1);
340
+ }
341
+ return this;
342
+ },
343
+ removeListener(event, listener) {
344
+ return this.off(event, listener);
345
+ },
346
+ emit(event, ...args) {
347
+ const listeners = [...(_stdinListeners[event] || []), ...(_stdinOnceListeners[event] || [])];
348
+ _stdinOnceListeners[event] = [];
349
+ for (const listener of listeners) {
350
+ listener(args[0]);
351
+ }
352
+ return listeners.length > 0;
353
+ },
354
+ pause() {
355
+ this.paused = true;
356
+ setStdinFlowMode(false);
357
+ return this;
358
+ },
359
+ resume() {
360
+ this.paused = false;
361
+ setStdinFlowMode(true);
362
+ _emitStdinData();
363
+ return this;
364
+ },
365
+ setEncoding(enc) {
366
+ this.encoding = enc;
367
+ return this;
368
+ },
369
+ setRawMode(mode) {
370
+ if (!_getStdinIsTTY()) {
371
+ throw new Error("setRawMode is not supported when stdin is not a TTY");
372
+ }
373
+ if (typeof _ptySetRawMode !== "undefined") {
374
+ _ptySetRawMode.applySync(undefined, [mode]);
375
+ }
376
+ return this;
377
+ },
378
+ get isTTY() { return _getStdinIsTTY(); },
379
+ // For readline compatibility
380
+ [Symbol.asyncIterator]: async function* () {
381
+ const lines = getStdinData().split("\n");
382
+ for (const line of lines) {
383
+ if (line)
384
+ yield line;
385
+ }
386
+ },
387
+ };
388
+ // hrtime function with bigint method
389
+ function hrtime(prev) {
390
+ const now = getNowMs();
391
+ const seconds = Math.floor(now / 1000);
392
+ const nanoseconds = Math.floor((now % 1000) * 1e6);
393
+ if (prev) {
394
+ let diffSec = seconds - prev[0];
395
+ let diffNano = nanoseconds - prev[1];
396
+ if (diffNano < 0) {
397
+ diffSec -= 1;
398
+ diffNano += 1e9;
399
+ }
400
+ return [diffSec, diffNano];
401
+ }
402
+ return [seconds, nanoseconds];
403
+ }
404
+ hrtime.bigint = function () {
405
+ const now = getNowMs();
406
+ return BigInt(Math.floor(now * 1e6));
407
+ };
408
+ // Internal state
409
+ let _cwd = config.cwd;
410
+ let _umask = 0o022;
411
+ // The process object — typed loosely as a polyfill, cast to typeof nodeProcess on export
412
+ const process = {
413
+ // Static properties
414
+ platform: config.platform,
415
+ arch: config.arch,
416
+ version: config.version,
417
+ versions: {
418
+ node: config.version.replace(/^v/, ""),
419
+ v8: "11.3.244.8",
420
+ uv: "1.44.2",
421
+ zlib: "1.2.13",
422
+ brotli: "1.0.9",
423
+ ares: "1.19.0",
424
+ modules: "108",
425
+ nghttp2: "1.52.0",
426
+ napi: "8",
427
+ llhttp: "8.1.0",
428
+ openssl: "3.0.8",
429
+ cldr: "42.0",
430
+ icu: "72.1",
431
+ tz: "2022g",
432
+ unicode: "15.0",
433
+ },
434
+ pid: config.pid,
435
+ ppid: config.ppid,
436
+ execPath: config.execPath,
437
+ execArgv: [],
438
+ argv: config.argv,
439
+ argv0: config.argv[0] || "node",
440
+ title: "node",
441
+ env: config.env,
442
+ // Config stubs
443
+ config: {
444
+ target_defaults: {
445
+ cflags: [],
446
+ default_configuration: "Release",
447
+ defines: [],
448
+ include_dirs: [],
449
+ libraries: [],
450
+ },
451
+ variables: {
452
+ node_prefix: "/usr",
453
+ node_shared_libuv: false,
454
+ },
455
+ },
456
+ release: {
457
+ name: "node",
458
+ sourceUrl: "https://nodejs.org/download/release/v20.0.0/node-v20.0.0.tar.gz",
459
+ headersUrl: "https://nodejs.org/download/release/v20.0.0/node-v20.0.0-headers.tar.gz",
460
+ },
461
+ // Feature flags
462
+ features: {
463
+ inspector: false,
464
+ debug: false,
465
+ uv: true,
466
+ ipv6: true,
467
+ tls_alpn: true,
468
+ tls_sni: true,
469
+ tls_ocsp: true,
470
+ tls: true,
471
+ },
472
+ // Methods
473
+ cwd() {
474
+ return _cwd;
475
+ },
476
+ chdir(dir) {
477
+ // Validate directory exists in VFS before setting cwd
478
+ let statJson;
479
+ try {
480
+ statJson = _fs.stat.applySyncPromise(undefined, [dir]);
481
+ }
482
+ catch {
483
+ const err = new Error(`ENOENT: no such file or directory, chdir '${dir}'`);
484
+ err.code = "ENOENT";
485
+ err.errno = -2;
486
+ err.syscall = "chdir";
487
+ err.path = dir;
488
+ throw err;
489
+ }
490
+ const parsed = JSON.parse(statJson);
491
+ if (!parsed.isDirectory) {
492
+ const err = new Error(`ENOTDIR: not a directory, chdir '${dir}'`);
493
+ err.code = "ENOTDIR";
494
+ err.errno = -20;
495
+ err.syscall = "chdir";
496
+ err.path = dir;
497
+ throw err;
498
+ }
499
+ _cwd = dir;
500
+ },
501
+ get exitCode() {
502
+ return _exitCode;
503
+ },
504
+ set exitCode(code) {
505
+ _exitCode = code ?? 0;
506
+ },
507
+ exit(code) {
508
+ const exitCode = code !== undefined ? code : _exitCode;
509
+ _exitCode = exitCode;
510
+ _exited = true;
511
+ // Fire exit event
512
+ try {
513
+ _emit("exit", exitCode);
514
+ }
515
+ catch (_e) {
516
+ // Ignore errors in exit handlers
517
+ }
518
+ // Throw to stop execution
519
+ throw new ProcessExitError(exitCode);
520
+ },
521
+ abort() {
522
+ return process.exit(1);
523
+ },
524
+ nextTick(callback, ...args) {
525
+ if (typeof queueMicrotask === "function") {
526
+ queueMicrotask(() => callback(...args));
527
+ }
528
+ else {
529
+ Promise.resolve().then(() => callback(...args));
530
+ }
531
+ },
532
+ hrtime: hrtime,
533
+ getuid() {
534
+ return config.uid;
535
+ },
536
+ getgid() {
537
+ return config.gid;
538
+ },
539
+ geteuid() {
540
+ return config.uid;
541
+ },
542
+ getegid() {
543
+ return config.gid;
544
+ },
545
+ getgroups() {
546
+ return [config.gid];
547
+ },
548
+ setuid() { },
549
+ setgid() { },
550
+ seteuid() { },
551
+ setegid() { },
552
+ setgroups() { },
553
+ umask(mask) {
554
+ const oldMask = _umask;
555
+ if (mask !== undefined) {
556
+ _umask = mask;
557
+ }
558
+ return oldMask;
559
+ },
560
+ uptime() {
561
+ return (getNowMs() - _processStartTime) / 1000;
562
+ },
563
+ memoryUsage() {
564
+ return {
565
+ rss: 50 * 1024 * 1024,
566
+ heapTotal: 20 * 1024 * 1024,
567
+ heapUsed: 10 * 1024 * 1024,
568
+ external: 1 * 1024 * 1024,
569
+ arrayBuffers: 500 * 1024,
570
+ };
571
+ },
572
+ cpuUsage(prev) {
573
+ const usage = {
574
+ user: 1000000,
575
+ system: 500000,
576
+ };
577
+ if (prev) {
578
+ return {
579
+ user: usage.user - prev.user,
580
+ system: usage.system - prev.system,
581
+ };
582
+ }
583
+ return usage;
584
+ },
585
+ resourceUsage() {
586
+ return {
587
+ userCPUTime: 1000000,
588
+ systemCPUTime: 500000,
589
+ maxRSS: 50 * 1024,
590
+ sharedMemorySize: 0,
591
+ unsharedDataSize: 0,
592
+ unsharedStackSize: 0,
593
+ minorPageFault: 0,
594
+ majorPageFault: 0,
595
+ swappedOut: 0,
596
+ fsRead: 0,
597
+ fsWrite: 0,
598
+ ipcSent: 0,
599
+ ipcReceived: 0,
600
+ signalsCount: 0,
601
+ voluntaryContextSwitches: 0,
602
+ involuntaryContextSwitches: 0,
603
+ };
604
+ },
605
+ kill(pid, signal) {
606
+ if (pid !== process.pid) {
607
+ const err = new Error("Operation not permitted");
608
+ err.code = "EPERM";
609
+ err.errno = -1;
610
+ err.syscall = "kill";
611
+ throw err;
612
+ }
613
+ // Resolve signal name to number (default SIGTERM)
614
+ const sigNum = _resolveSignal(signal);
615
+ // Self-kill - exit with 128 + signal number (POSIX convention)
616
+ return process.exit(128 + sigNum);
617
+ },
618
+ // EventEmitter methods
619
+ on(event, listener) {
620
+ return _addListener(event, listener);
621
+ },
622
+ once(event, listener) {
623
+ return _addListener(event, listener, true);
624
+ },
625
+ removeListener(event, listener) {
626
+ return _removeListener(event, listener);
627
+ },
628
+ // off is an alias for removeListener (assigned below to be same reference)
629
+ off: null,
630
+ removeAllListeners(event) {
631
+ if (event) {
632
+ delete _processListeners[event];
633
+ delete _processOnceListeners[event];
634
+ }
635
+ else {
636
+ Object.keys(_processListeners).forEach((k) => delete _processListeners[k]);
637
+ Object.keys(_processOnceListeners).forEach((k) => delete _processOnceListeners[k]);
638
+ }
639
+ return process;
640
+ },
641
+ addListener(event, listener) {
642
+ return _addListener(event, listener);
643
+ },
644
+ emit(event, ...args) {
645
+ return _emit(event, ...args);
646
+ },
647
+ listeners(event) {
648
+ return [
649
+ ...(_processListeners[event] || []),
650
+ ...(_processOnceListeners[event] || []),
651
+ ];
652
+ },
653
+ listenerCount(event) {
654
+ return ((_processListeners[event] || []).length +
655
+ (_processOnceListeners[event] || []).length);
656
+ },
657
+ prependListener(event, listener) {
658
+ if (!_processListeners[event]) {
659
+ _processListeners[event] = [];
660
+ }
661
+ _processListeners[event].unshift(listener);
662
+ return process;
663
+ },
664
+ prependOnceListener(event, listener) {
665
+ if (!_processOnceListeners[event]) {
666
+ _processOnceListeners[event] = [];
667
+ }
668
+ _processOnceListeners[event].unshift(listener);
669
+ return process;
670
+ },
671
+ eventNames() {
672
+ return [
673
+ ...new Set([
674
+ ...Object.keys(_processListeners),
675
+ ...Object.keys(_processOnceListeners),
676
+ ]),
677
+ ];
678
+ },
679
+ setMaxListeners(n) {
680
+ _processMaxListeners = n;
681
+ return process;
682
+ },
683
+ getMaxListeners() {
684
+ return _processMaxListeners;
685
+ },
686
+ rawListeners(event) {
687
+ return process.listeners(event);
688
+ },
689
+ // Stdio streams
690
+ stdout: _stdout,
691
+ stderr: _stderr,
692
+ stdin: _stdin,
693
+ // Process state
694
+ connected: false,
695
+ // Module info (will be set by createRequire)
696
+ mainModule: undefined,
697
+ // No-op methods for compatibility
698
+ emitWarning(warning) {
699
+ const msg = typeof warning === "string" ? warning : warning.message;
700
+ _emit("warning", { message: msg, name: "Warning" });
701
+ },
702
+ binding(_name) {
703
+ throw new Error("process.binding is not supported in sandbox");
704
+ },
705
+ _linkedBinding(_name) {
706
+ throw new Error("process._linkedBinding is not supported in sandbox");
707
+ },
708
+ dlopen() {
709
+ throw new Error("process.dlopen is not supported");
710
+ },
711
+ hasUncaughtExceptionCaptureCallback() {
712
+ return false;
713
+ },
714
+ setUncaughtExceptionCaptureCallback() { },
715
+ // Send for IPC (no-op)
716
+ send() {
717
+ return false;
718
+ },
719
+ disconnect() { },
720
+ // Report
721
+ report: {
722
+ directory: "",
723
+ filename: "",
724
+ compact: false,
725
+ signal: "SIGUSR2",
726
+ reportOnFatalError: false,
727
+ reportOnSignal: false,
728
+ reportOnUncaughtException: false,
729
+ getReport() {
730
+ return {};
731
+ },
732
+ writeReport() {
733
+ return "";
734
+ },
735
+ },
736
+ // Debug port
737
+ debugPort: 9229,
738
+ // Internal state
739
+ _cwd: config.cwd,
740
+ _umask: 0o022,
741
+ };
742
+ // Make process.off === process.removeListener (same function reference)
743
+ process.off = process.removeListener;
744
+ // Add memoryUsage.rss
745
+ process.memoryUsage.rss =
746
+ function () {
747
+ return 50 * 1024 * 1024;
748
+ };
749
+ // Match Node.js Object.prototype.toString.call(process) === '[object process]'
750
+ Object.defineProperty(process, Symbol.toStringTag, {
751
+ value: "process",
752
+ writable: false,
753
+ configurable: true,
754
+ enumerable: false,
755
+ });
756
+ export default process;
757
+ // ============================================================================
758
+ // Global polyfills
759
+ // ============================================================================
760
+ const TIMER_DISPATCH = {
761
+ create: "kernelTimerCreate",
762
+ arm: "kernelTimerArm",
763
+ clear: "kernelTimerClear",
764
+ };
765
+ // queueMicrotask fallback
766
+ const _queueMicrotask = typeof queueMicrotask === "function"
767
+ ? queueMicrotask
768
+ : function (fn) {
769
+ Promise.resolve().then(fn);
770
+ };
771
+ function normalizeTimerDelay(delay) {
772
+ const numericDelay = Number(delay ?? 0);
773
+ if (!Number.isFinite(numericDelay) || numericDelay <= 0) {
774
+ return 0;
775
+ }
776
+ return Math.floor(numericDelay);
777
+ }
778
+ function getTimerId(timer) {
779
+ if (timer && typeof timer === "object" && timer._id !== undefined) {
780
+ return timer._id;
781
+ }
782
+ if (typeof timer === "number") {
783
+ return timer;
784
+ }
785
+ return undefined;
786
+ }
787
+ function createKernelTimer(delayMs, repeat) {
788
+ try {
789
+ return bridgeDispatchSync(TIMER_DISPATCH.create, delayMs, repeat);
790
+ }
791
+ catch (error) {
792
+ if (error instanceof Error && error.message.includes("EAGAIN")) {
793
+ throw new Error("ERR_RESOURCE_BUDGET_EXCEEDED: maximum number of timers exceeded");
794
+ }
795
+ throw error;
796
+ }
797
+ }
798
+ function armKernelTimer(timerId) {
799
+ bridgeDispatchSync(TIMER_DISPATCH.arm, timerId);
800
+ }
801
+ /**
802
+ * Timer handle that mimics Node.js Timeout (ref/unref/Symbol.toPrimitive).
803
+ * Timers with delay > 0 use the host's `_scheduleTimer` bridge to sleep
804
+ * without blocking the isolate's event loop.
805
+ */
806
+ class TimerHandle {
807
+ _id;
808
+ _destroyed;
809
+ constructor(id) {
810
+ this._id = id;
811
+ this._destroyed = false;
812
+ }
813
+ ref() {
814
+ return this;
815
+ }
816
+ unref() {
817
+ return this;
818
+ }
819
+ hasRef() {
820
+ return true;
821
+ }
822
+ refresh() {
823
+ return this;
824
+ }
825
+ [Symbol.toPrimitive]() {
826
+ return this._id;
827
+ }
828
+ }
829
+ const _timerEntries = new Map();
830
+ function timerDispatch(_eventType, payload) {
831
+ const timerId = typeof payload === "number"
832
+ ? payload
833
+ : Number(payload?.timerId);
834
+ if (!Number.isFinite(timerId))
835
+ return;
836
+ const entry = _timerEntries.get(timerId);
837
+ if (!entry)
838
+ return;
839
+ if (!entry.repeat) {
840
+ entry.handle._destroyed = true;
841
+ _timerEntries.delete(timerId);
842
+ }
843
+ try {
844
+ entry.callback(...entry.args);
845
+ }
846
+ catch (_e) {
847
+ // Ignore timer callback errors
848
+ }
849
+ if (entry.repeat && _timerEntries.has(timerId)) {
850
+ armKernelTimer(timerId);
851
+ }
852
+ }
853
+ export function setTimeout(callback, delay, ...args) {
854
+ const actualDelay = normalizeTimerDelay(delay);
855
+ const id = createKernelTimer(actualDelay, false);
856
+ const handle = new TimerHandle(id);
857
+ _timerEntries.set(id, {
858
+ handle,
859
+ callback,
860
+ args,
861
+ repeat: false,
862
+ });
863
+ armKernelTimer(id);
864
+ return handle;
865
+ }
866
+ export function clearTimeout(timer) {
867
+ const id = getTimerId(timer);
868
+ if (id === undefined)
869
+ return;
870
+ const entry = _timerEntries.get(id);
871
+ if (entry) {
872
+ entry.handle._destroyed = true;
873
+ _timerEntries.delete(id);
874
+ }
875
+ bridgeDispatchSync(TIMER_DISPATCH.clear, id);
876
+ }
877
+ export function setInterval(callback, delay, ...args) {
878
+ const actualDelay = Math.max(1, normalizeTimerDelay(delay));
879
+ const id = createKernelTimer(actualDelay, true);
880
+ const handle = new TimerHandle(id);
881
+ _timerEntries.set(id, {
882
+ handle,
883
+ callback,
884
+ args,
885
+ repeat: true,
886
+ });
887
+ armKernelTimer(id);
888
+ return handle;
889
+ }
890
+ export function clearInterval(timer) {
891
+ clearTimeout(timer);
892
+ }
893
+ exposeCustomGlobal("_timerDispatch", timerDispatch);
894
+ export function setImmediate(callback, ...args) {
895
+ return setTimeout(callback, 0, ...args);
896
+ }
897
+ export function clearImmediate(id) {
898
+ clearTimeout(id);
899
+ }
900
+ // TextEncoder and TextDecoder - re-export from polyfills
901
+ export { URL, URLSearchParams };
902
+ export { TextEncoder, TextDecoder };
903
+ // Buffer - use buffer package polyfill
904
+ export const Buffer = BufferPolyfill;
905
+ function throwUnsupportedCryptoApi(api) {
906
+ throw new Error(`crypto.${api} is not supported in sandbox`);
907
+ }
908
+ const kCryptoKeyToken = Symbol("secureExecCryptoKey");
909
+ const kCryptoToken = Symbol("secureExecCrypto");
910
+ const kSubtleToken = Symbol("secureExecSubtle");
911
+ const ERR_INVALID_THIS = "ERR_INVALID_THIS";
912
+ const ERR_ILLEGAL_CONSTRUCTOR = "ERR_ILLEGAL_CONSTRUCTOR";
913
+ function createNodeTypeError(message, code) {
914
+ const error = new TypeError(message);
915
+ error.code = code;
916
+ return error;
917
+ }
918
+ function createDomLikeError(name, code, message) {
919
+ const error = new Error(message);
920
+ error.name = name;
921
+ error.code = code;
922
+ return error;
923
+ }
924
+ function assertCryptoReceiver(receiver) {
925
+ if (!(receiver instanceof SandboxCrypto) || receiver._token !== kCryptoToken) {
926
+ throw createNodeTypeError("Value of \"this\" must be of type Crypto", ERR_INVALID_THIS);
927
+ }
928
+ }
929
+ function assertSubtleReceiver(receiver) {
930
+ if (!(receiver instanceof SandboxSubtleCrypto) ||
931
+ receiver._token !== kSubtleToken) {
932
+ throw createNodeTypeError("Value of \"this\" must be of type SubtleCrypto", ERR_INVALID_THIS);
933
+ }
934
+ }
935
+ function isIntegerTypedArray(value) {
936
+ if (!ArrayBuffer.isView(value) || value instanceof DataView) {
937
+ return false;
938
+ }
939
+ return (value instanceof Int8Array ||
940
+ value instanceof Int16Array ||
941
+ value instanceof Int32Array ||
942
+ value instanceof Uint8Array ||
943
+ value instanceof Uint16Array ||
944
+ value instanceof Uint32Array ||
945
+ value instanceof Uint8ClampedArray ||
946
+ value instanceof BigInt64Array ||
947
+ value instanceof BigUint64Array ||
948
+ BufferPolyfill.isBuffer(value));
949
+ }
950
+ function toBase64(data) {
951
+ if (typeof data === "string") {
952
+ return BufferPolyfill.from(data).toString("base64");
953
+ }
954
+ if (data instanceof ArrayBuffer) {
955
+ return BufferPolyfill.from(new Uint8Array(data)).toString("base64");
956
+ }
957
+ if (ArrayBuffer.isView(data)) {
958
+ return BufferPolyfill.from(new Uint8Array(data.buffer, data.byteOffset, data.byteLength)).toString("base64");
959
+ }
960
+ return BufferPolyfill.from(data).toString("base64");
961
+ }
962
+ function toArrayBuffer(data) {
963
+ const buf = BufferPolyfill.from(data, "base64");
964
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
965
+ }
966
+ function normalizeAlgorithm(algorithm) {
967
+ if (typeof algorithm === "string") {
968
+ return { name: algorithm };
969
+ }
970
+ return (algorithm ?? {});
971
+ }
972
+ function normalizeBridgeAlgorithm(algorithm) {
973
+ const normalized = { ...normalizeAlgorithm(algorithm) };
974
+ const hash = normalized.hash;
975
+ const publicExponent = normalized.publicExponent;
976
+ const iv = normalized.iv;
977
+ const additionalData = normalized.additionalData;
978
+ const salt = normalized.salt;
979
+ const info = normalized.info;
980
+ const context = normalized.context;
981
+ const label = normalized.label;
982
+ const publicKey = normalized.public;
983
+ if (hash) {
984
+ normalized.hash = normalizeAlgorithm(hash);
985
+ }
986
+ if (publicExponent && ArrayBuffer.isView(publicExponent)) {
987
+ normalized.publicExponent = BufferPolyfill.from(new Uint8Array(publicExponent.buffer, publicExponent.byteOffset, publicExponent.byteLength)).toString("base64");
988
+ }
989
+ if (iv) {
990
+ normalized.iv = toBase64(iv);
991
+ }
992
+ if (additionalData) {
993
+ normalized.additionalData = toBase64(additionalData);
994
+ }
995
+ if (salt) {
996
+ normalized.salt = toBase64(salt);
997
+ }
998
+ if (info) {
999
+ normalized.info = toBase64(info);
1000
+ }
1001
+ if (context) {
1002
+ normalized.context = toBase64(context);
1003
+ }
1004
+ if (label) {
1005
+ normalized.label = toBase64(label);
1006
+ }
1007
+ if (publicKey &&
1008
+ typeof publicKey === "object" &&
1009
+ "_keyData" in publicKey) {
1010
+ normalized.public = publicKey._keyData;
1011
+ }
1012
+ return normalized;
1013
+ }
1014
+ class SandboxCryptoKey {
1015
+ type;
1016
+ extractable;
1017
+ algorithm;
1018
+ usages;
1019
+ _keyData;
1020
+ _pem;
1021
+ _jwk;
1022
+ _raw;
1023
+ _sourceKeyObjectData;
1024
+ [kCryptoKeyToken];
1025
+ constructor(keyData, token) {
1026
+ if (token !== kCryptoKeyToken || !keyData) {
1027
+ throw createNodeTypeError("Illegal constructor", ERR_ILLEGAL_CONSTRUCTOR);
1028
+ }
1029
+ this.type = keyData.type;
1030
+ this.extractable = keyData.extractable;
1031
+ this.algorithm = keyData.algorithm;
1032
+ this.usages = keyData.usages;
1033
+ this._keyData = keyData;
1034
+ this._pem = keyData._pem;
1035
+ this._jwk = keyData._jwk;
1036
+ this._raw = keyData._raw;
1037
+ this._sourceKeyObjectData = keyData._sourceKeyObjectData;
1038
+ this[kCryptoKeyToken] = true;
1039
+ }
1040
+ }
1041
+ Object.defineProperty(SandboxCryptoKey.prototype, Symbol.toStringTag, {
1042
+ value: "CryptoKey",
1043
+ configurable: true,
1044
+ });
1045
+ Object.defineProperty(SandboxCryptoKey, Symbol.hasInstance, {
1046
+ value(candidate) {
1047
+ return Boolean(candidate &&
1048
+ typeof candidate === "object" &&
1049
+ (candidate[kCryptoKeyToken] === true ||
1050
+ ("_keyData" in candidate &&
1051
+ candidate[Symbol.toStringTag] === "CryptoKey")));
1052
+ },
1053
+ configurable: true,
1054
+ });
1055
+ function createCryptoKey(keyData) {
1056
+ const globalCryptoKey = globalThis.CryptoKey;
1057
+ if (typeof globalCryptoKey === "function" &&
1058
+ globalCryptoKey.prototype &&
1059
+ globalCryptoKey.prototype !== SandboxCryptoKey.prototype) {
1060
+ const key = Object.create(globalCryptoKey.prototype);
1061
+ key.type = keyData.type;
1062
+ key.extractable = keyData.extractable;
1063
+ key.algorithm = keyData.algorithm;
1064
+ key.usages = keyData.usages;
1065
+ key._keyData = keyData;
1066
+ key._pem = keyData._pem;
1067
+ key._jwk = keyData._jwk;
1068
+ key._raw = keyData._raw;
1069
+ key._sourceKeyObjectData = keyData._sourceKeyObjectData;
1070
+ return key;
1071
+ }
1072
+ return new SandboxCryptoKey(keyData, kCryptoKeyToken);
1073
+ }
1074
+ function subtleCall(request) {
1075
+ if (typeof _cryptoSubtle === "undefined") {
1076
+ throw new Error("crypto.subtle is not supported in sandbox");
1077
+ }
1078
+ return _cryptoSubtle.applySync(undefined, [JSON.stringify(request)]);
1079
+ }
1080
+ class SandboxSubtleCrypto {
1081
+ _token;
1082
+ constructor(token) {
1083
+ if (token !== kSubtleToken) {
1084
+ throw createNodeTypeError("Illegal constructor", ERR_ILLEGAL_CONSTRUCTOR);
1085
+ }
1086
+ this._token = token;
1087
+ }
1088
+ digest(algorithm, data) {
1089
+ assertSubtleReceiver(this);
1090
+ return Promise.resolve().then(() => {
1091
+ const result = JSON.parse(subtleCall({
1092
+ op: "digest",
1093
+ algorithm: normalizeAlgorithm(algorithm).name,
1094
+ data: toBase64(data),
1095
+ }));
1096
+ return toArrayBuffer(result.data);
1097
+ });
1098
+ }
1099
+ generateKey(algorithm, extractable, keyUsages) {
1100
+ assertSubtleReceiver(this);
1101
+ return Promise.resolve().then(() => {
1102
+ const result = JSON.parse(subtleCall({
1103
+ op: "generateKey",
1104
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1105
+ extractable,
1106
+ usages: Array.from(keyUsages),
1107
+ }));
1108
+ if ("publicKey" in result && "privateKey" in result) {
1109
+ return {
1110
+ publicKey: createCryptoKey(result.publicKey),
1111
+ privateKey: createCryptoKey(result.privateKey),
1112
+ };
1113
+ }
1114
+ return createCryptoKey(result.key);
1115
+ });
1116
+ }
1117
+ importKey(format, keyData, algorithm, extractable, keyUsages) {
1118
+ assertSubtleReceiver(this);
1119
+ return Promise.resolve().then(() => {
1120
+ const result = JSON.parse(subtleCall({
1121
+ op: "importKey",
1122
+ format,
1123
+ keyData: format === "jwk" ? keyData : toBase64(keyData),
1124
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1125
+ extractable,
1126
+ usages: Array.from(keyUsages),
1127
+ }));
1128
+ return createCryptoKey(result.key);
1129
+ });
1130
+ }
1131
+ exportKey(format, key) {
1132
+ assertSubtleReceiver(this);
1133
+ return Promise.resolve().then(() => {
1134
+ const result = JSON.parse(subtleCall({
1135
+ op: "exportKey",
1136
+ format,
1137
+ key: key._keyData,
1138
+ }));
1139
+ if (format === "jwk") {
1140
+ return result.jwk;
1141
+ }
1142
+ return toArrayBuffer(result.data ?? "");
1143
+ });
1144
+ }
1145
+ encrypt(algorithm, key, data) {
1146
+ assertSubtleReceiver(this);
1147
+ return Promise.resolve().then(() => {
1148
+ const result = JSON.parse(subtleCall({
1149
+ op: "encrypt",
1150
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1151
+ key: key._keyData,
1152
+ data: toBase64(data),
1153
+ }));
1154
+ return toArrayBuffer(result.data);
1155
+ });
1156
+ }
1157
+ decrypt(algorithm, key, data) {
1158
+ assertSubtleReceiver(this);
1159
+ return Promise.resolve().then(() => {
1160
+ const result = JSON.parse(subtleCall({
1161
+ op: "decrypt",
1162
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1163
+ key: key._keyData,
1164
+ data: toBase64(data),
1165
+ }));
1166
+ return toArrayBuffer(result.data);
1167
+ });
1168
+ }
1169
+ sign(algorithm, key, data) {
1170
+ assertSubtleReceiver(this);
1171
+ return Promise.resolve().then(() => {
1172
+ const result = JSON.parse(subtleCall({
1173
+ op: "sign",
1174
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1175
+ key: key._keyData,
1176
+ data: toBase64(data),
1177
+ }));
1178
+ return toArrayBuffer(result.data);
1179
+ });
1180
+ }
1181
+ verify(algorithm, key, signature, data) {
1182
+ assertSubtleReceiver(this);
1183
+ return Promise.resolve().then(() => {
1184
+ const result = JSON.parse(subtleCall({
1185
+ op: "verify",
1186
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1187
+ key: key._keyData,
1188
+ signature: toBase64(signature),
1189
+ data: toBase64(data),
1190
+ }));
1191
+ return result.result;
1192
+ });
1193
+ }
1194
+ deriveBits(algorithm, baseKey, length) {
1195
+ assertSubtleReceiver(this);
1196
+ return Promise.resolve().then(() => {
1197
+ const result = JSON.parse(subtleCall({
1198
+ op: "deriveBits",
1199
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1200
+ baseKey: baseKey._keyData,
1201
+ length,
1202
+ }));
1203
+ return toArrayBuffer(result.data);
1204
+ });
1205
+ }
1206
+ deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages) {
1207
+ assertSubtleReceiver(this);
1208
+ return Promise.resolve().then(() => {
1209
+ const result = JSON.parse(subtleCall({
1210
+ op: "deriveKey",
1211
+ algorithm: normalizeBridgeAlgorithm(algorithm),
1212
+ baseKey: baseKey._keyData,
1213
+ derivedKeyAlgorithm: normalizeBridgeAlgorithm(derivedKeyAlgorithm),
1214
+ extractable,
1215
+ usages: Array.from(keyUsages),
1216
+ }));
1217
+ return createCryptoKey(result.key);
1218
+ });
1219
+ }
1220
+ wrapKey(format, key, wrappingKey, wrapAlgorithm) {
1221
+ assertSubtleReceiver(this);
1222
+ return Promise.resolve().then(() => {
1223
+ const result = JSON.parse(subtleCall({
1224
+ op: "wrapKey",
1225
+ format,
1226
+ key: key._keyData,
1227
+ wrappingKey: wrappingKey._keyData,
1228
+ wrapAlgorithm: normalizeBridgeAlgorithm(wrapAlgorithm),
1229
+ }));
1230
+ return toArrayBuffer(result.data);
1231
+ });
1232
+ }
1233
+ unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) {
1234
+ assertSubtleReceiver(this);
1235
+ return Promise.resolve().then(() => {
1236
+ const result = JSON.parse(subtleCall({
1237
+ op: "unwrapKey",
1238
+ format,
1239
+ wrappedKey: toBase64(wrappedKey),
1240
+ unwrappingKey: unwrappingKey._keyData,
1241
+ unwrapAlgorithm: normalizeBridgeAlgorithm(unwrapAlgorithm),
1242
+ unwrappedKeyAlgorithm: normalizeBridgeAlgorithm(unwrappedKeyAlgorithm),
1243
+ extractable,
1244
+ usages: Array.from(keyUsages),
1245
+ }));
1246
+ return createCryptoKey(result.key);
1247
+ });
1248
+ }
1249
+ }
1250
+ const subtleCrypto = new SandboxSubtleCrypto(kSubtleToken);
1251
+ class SandboxCrypto {
1252
+ _token;
1253
+ constructor(token) {
1254
+ if (token !== kCryptoToken) {
1255
+ throw createNodeTypeError("Illegal constructor", ERR_ILLEGAL_CONSTRUCTOR);
1256
+ }
1257
+ this._token = token;
1258
+ }
1259
+ get subtle() {
1260
+ assertCryptoReceiver(this);
1261
+ return subtleCrypto;
1262
+ }
1263
+ getRandomValues(array) {
1264
+ assertCryptoReceiver(this);
1265
+ if (!isIntegerTypedArray(array)) {
1266
+ throw createDomLikeError("TypeMismatchError", 17, "The data argument must be an integer-type TypedArray");
1267
+ }
1268
+ if (typeof _cryptoRandomFill === "undefined") {
1269
+ throwUnsupportedCryptoApi("getRandomValues");
1270
+ }
1271
+ if (array.byteLength > 65536) {
1272
+ throw createDomLikeError("QuotaExceededError", 22, `The ArrayBufferView's byte length (${array.byteLength}) exceeds the number of bytes of entropy available via this API (65536)`);
1273
+ }
1274
+ const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
1275
+ try {
1276
+ const base64 = _cryptoRandomFill.applySync(undefined, [bytes.byteLength]);
1277
+ const hostBytes = BufferPolyfill.from(base64, "base64");
1278
+ if (hostBytes.byteLength !== bytes.byteLength) {
1279
+ throw new Error("invalid host entropy size");
1280
+ }
1281
+ bytes.set(hostBytes);
1282
+ return array;
1283
+ }
1284
+ catch {
1285
+ throwUnsupportedCryptoApi("getRandomValues");
1286
+ }
1287
+ }
1288
+ randomUUID() {
1289
+ assertCryptoReceiver(this);
1290
+ if (typeof _cryptoRandomUUID === "undefined") {
1291
+ throwUnsupportedCryptoApi("randomUUID");
1292
+ }
1293
+ try {
1294
+ const uuid = _cryptoRandomUUID.applySync(undefined, []);
1295
+ if (typeof uuid !== "string") {
1296
+ throw new Error("invalid host uuid");
1297
+ }
1298
+ return uuid;
1299
+ }
1300
+ catch {
1301
+ throwUnsupportedCryptoApi("randomUUID");
1302
+ }
1303
+ }
1304
+ }
1305
+ const cryptoPolyfillInstance = new SandboxCrypto(kCryptoToken);
1306
+ /**
1307
+ * Crypto polyfill that delegates to the host for entropy. `getRandomValues`
1308
+ * calls the host's `_cryptoRandomFill` bridge to get cryptographically secure
1309
+ * random bytes. Subtle crypto operations route through the host WebCrypto bridge.
1310
+ */
1311
+ export const cryptoPolyfill = cryptoPolyfillInstance;
1312
+ /**
1313
+ * Install all process/timer/URL/Buffer/crypto polyfills onto `globalThis`.
1314
+ * Called once during bridge initialization before user code runs.
1315
+ */
1316
+ export function setupGlobals() {
1317
+ const g = globalThis;
1318
+ // Process - simple assignment is sufficient since we use external: ["process"]
1319
+ // in polyfills.ts, which prevents node-stdlib-browser's process shim from being
1320
+ // bundled and overwriting our process object.
1321
+ g.process = process;
1322
+ // Timers
1323
+ g.setTimeout = setTimeout;
1324
+ g.clearTimeout = clearTimeout;
1325
+ g.setInterval = setInterval;
1326
+ g.clearInterval = clearInterval;
1327
+ g.setImmediate = setImmediate;
1328
+ g.clearImmediate = clearImmediate;
1329
+ // queueMicrotask
1330
+ if (typeof g.queueMicrotask === "undefined") {
1331
+ g.queueMicrotask = _queueMicrotask;
1332
+ }
1333
+ // URL globals must override bootstrap fallbacks and stay non-enumerable.
1334
+ installWhatwgUrlGlobals(g);
1335
+ // TextEncoder/TextDecoder
1336
+ if (typeof g.TextEncoder === "undefined") {
1337
+ g.TextEncoder = TextEncoder;
1338
+ }
1339
+ if (typeof g.TextDecoder === "undefined") {
1340
+ g.TextDecoder = TextDecoder;
1341
+ }
1342
+ // Buffer
1343
+ if (typeof g.Buffer === "undefined") {
1344
+ g.Buffer = Buffer;
1345
+ }
1346
+ const globalBuffer = g.Buffer;
1347
+ if (typeof globalBuffer.kMaxLength !== "number") {
1348
+ globalBuffer.kMaxLength = BUFFER_MAX_LENGTH;
1349
+ }
1350
+ if (typeof globalBuffer.kStringMaxLength !== "number") {
1351
+ globalBuffer.kStringMaxLength = BUFFER_MAX_STRING_LENGTH;
1352
+ }
1353
+ if (typeof globalBuffer.constants !== "object" ||
1354
+ globalBuffer.constants === null) {
1355
+ globalBuffer.constants = BUFFER_CONSTANTS;
1356
+ }
1357
+ // Crypto
1358
+ if (typeof g.Crypto === "undefined") {
1359
+ g.Crypto = SandboxCrypto;
1360
+ }
1361
+ if (typeof g.SubtleCrypto === "undefined") {
1362
+ g.SubtleCrypto = SandboxSubtleCrypto;
1363
+ }
1364
+ if (typeof g.CryptoKey === "undefined") {
1365
+ g.CryptoKey = SandboxCryptoKey;
1366
+ }
1367
+ if (typeof g.crypto === "undefined") {
1368
+ g.crypto = cryptoPolyfill;
1369
+ }
1370
+ else {
1371
+ const cryptoObj = g.crypto;
1372
+ if (typeof cryptoObj.getRandomValues === "undefined") {
1373
+ cryptoObj.getRandomValues = cryptoPolyfill.getRandomValues;
1374
+ }
1375
+ if (typeof cryptoObj.randomUUID === "undefined") {
1376
+ cryptoObj.randomUUID = cryptoPolyfill.randomUUID;
1377
+ }
1378
+ if (typeof cryptoObj.subtle === "undefined") {
1379
+ cryptoObj.subtle = cryptoPolyfill.subtle;
1380
+ }
1381
+ }
1382
+ }