@secure-exec/core 0.1.0-rc.4 → 0.1.1-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.
@@ -21,12 +21,17 @@
21
21
  return createRuntimeGlobalExposer(true);
22
22
  }
23
23
 
24
+ // isolate-runtime/src/common/global-access.ts
25
+ function setGlobalValue(name, value) {
26
+ Reflect.set(globalThis, name, value);
27
+ }
28
+
24
29
  // isolate-runtime/src/inject/bridge-initial-globals.ts
25
30
  var __runtimeExposeMutableGlobal = getRuntimeExposeMutableGlobal();
26
31
  var __bridgeSetupConfig = globalThis.__runtimeBridgeSetupConfig ?? {};
27
32
  var __initialCwd = typeof __bridgeSetupConfig.initialCwd === "string" ? __bridgeSetupConfig.initialCwd : "/";
28
- var __jsonPayloadLimitBytes = typeof __bridgeSetupConfig.jsonPayloadLimitBytes === "number" && Number.isFinite(__bridgeSetupConfig.jsonPayloadLimitBytes) ? Math.max(0, Math.floor(__bridgeSetupConfig.jsonPayloadLimitBytes)) : 4 * 1024 * 1024;
29
- var __payloadLimitErrorCode = typeof __bridgeSetupConfig.payloadLimitErrorCode === "string" && __bridgeSetupConfig.payloadLimitErrorCode.length > 0 ? __bridgeSetupConfig.payloadLimitErrorCode : "ERR_SANDBOX_PAYLOAD_TOO_LARGE";
33
+ globalThis.__runtimeJsonPayloadLimitBytes = typeof __bridgeSetupConfig.jsonPayloadLimitBytes === "number" && Number.isFinite(__bridgeSetupConfig.jsonPayloadLimitBytes) ? Math.max(0, Math.floor(__bridgeSetupConfig.jsonPayloadLimitBytes)) : 4 * 1024 * 1024;
34
+ globalThis.__runtimePayloadLimitErrorCode = typeof __bridgeSetupConfig.payloadLimitErrorCode === "string" && __bridgeSetupConfig.payloadLimitErrorCode.length > 0 ? __bridgeSetupConfig.payloadLimitErrorCode : "ERR_SANDBOX_PAYLOAD_TOO_LARGE";
30
35
  function __scEncode(value, seen) {
31
36
  if (value === null) return null;
32
37
  if (value === void 0) return { t: "undef" };
@@ -224,9 +229,11 @@
224
229
  );
225
230
  },
226
231
  deserialize: function(buffer) {
227
- if (buffer.length > __jsonPayloadLimitBytes) {
232
+ const limit = globalThis.__runtimeJsonPayloadLimitBytes ?? 4 * 1024 * 1024;
233
+ const errorCode = globalThis.__runtimePayloadLimitErrorCode ?? "ERR_SANDBOX_PAYLOAD_TOO_LARGE";
234
+ if (buffer.length > limit) {
228
235
  throw new Error(
229
- __payloadLimitErrorCode + ": v8.deserialize exceeds " + String(__jsonPayloadLimitBytes) + " bytes"
236
+ errorCode + ": v8.deserialize exceeds " + String(limit) + " bytes"
230
237
  );
231
238
  }
232
239
  const text = buffer.toString();
@@ -243,4 +250,136 @@
243
250
  }
244
251
  __runtimeExposeMutableGlobal("_pendingModules", {});
245
252
  __runtimeExposeMutableGlobal("_currentModule", { dirname: __initialCwd });
253
+ globalThis.__runtimeApplyConfig = function(config) {
254
+ if (typeof config.payloadLimitBytes === "number" && Number.isFinite(config.payloadLimitBytes)) {
255
+ globalThis.__runtimeJsonPayloadLimitBytes = Math.max(
256
+ 0,
257
+ Math.floor(config.payloadLimitBytes)
258
+ );
259
+ }
260
+ if (typeof config.payloadLimitErrorCode === "string" && config.payloadLimitErrorCode.length > 0) {
261
+ globalThis.__runtimePayloadLimitErrorCode = config.payloadLimitErrorCode;
262
+ }
263
+ if (config.timingMitigation === "freeze") {
264
+ const frozenTimeMs = typeof config.frozenTimeMs === "number" && Number.isFinite(config.frozenTimeMs) ? config.frozenTimeMs : Date.now();
265
+ const frozenDateNow = () => frozenTimeMs;
266
+ try {
267
+ Object.defineProperty(Date, "now", {
268
+ value: frozenDateNow,
269
+ configurable: false,
270
+ writable: false
271
+ });
272
+ } catch {
273
+ Date.now = frozenDateNow;
274
+ }
275
+ const OrigDate = Date;
276
+ const FrozenDate = function Date2(...args) {
277
+ if (new.target) {
278
+ if (args.length === 0) {
279
+ return new OrigDate(frozenTimeMs);
280
+ }
281
+ return new OrigDate(...args);
282
+ }
283
+ return OrigDate();
284
+ };
285
+ Object.defineProperty(FrozenDate, "prototype", {
286
+ value: OrigDate.prototype,
287
+ writable: false,
288
+ configurable: false
289
+ });
290
+ FrozenDate.now = frozenDateNow;
291
+ FrozenDate.parse = OrigDate.parse;
292
+ FrozenDate.UTC = OrigDate.UTC;
293
+ Object.defineProperty(FrozenDate, "now", {
294
+ value: frozenDateNow,
295
+ configurable: false,
296
+ writable: false
297
+ });
298
+ try {
299
+ Object.defineProperty(globalThis, "Date", {
300
+ value: FrozenDate,
301
+ configurable: false,
302
+ writable: false
303
+ });
304
+ } catch {
305
+ globalThis.Date = FrozenDate;
306
+ }
307
+ const frozenPerformanceNow = () => 0;
308
+ const origPerf = globalThis.performance;
309
+ const frozenPerf = /* @__PURE__ */ Object.create(null);
310
+ if (typeof origPerf !== "undefined" && origPerf !== null) {
311
+ const src = origPerf;
312
+ for (const key of Object.getOwnPropertyNames(
313
+ Object.getPrototypeOf(origPerf) ?? origPerf
314
+ )) {
315
+ if (key !== "now") {
316
+ try {
317
+ const val = src[key];
318
+ if (typeof val === "function") {
319
+ frozenPerf[key] = val.bind(origPerf);
320
+ } else {
321
+ frozenPerf[key] = val;
322
+ }
323
+ } catch {
324
+ }
325
+ }
326
+ }
327
+ }
328
+ Object.defineProperty(frozenPerf, "now", {
329
+ value: frozenPerformanceNow,
330
+ configurable: false,
331
+ writable: false
332
+ });
333
+ Object.freeze(frozenPerf);
334
+ try {
335
+ Object.defineProperty(globalThis, "performance", {
336
+ value: frozenPerf,
337
+ configurable: false,
338
+ writable: false
339
+ });
340
+ } catch {
341
+ globalThis.performance = frozenPerf;
342
+ }
343
+ const OrigSAB = globalThis.SharedArrayBuffer;
344
+ if (typeof OrigSAB === "function") {
345
+ try {
346
+ const proto = OrigSAB.prototype;
347
+ if (proto) {
348
+ for (const key of [
349
+ "byteLength",
350
+ "slice",
351
+ "grow",
352
+ "maxByteLength",
353
+ "growable"
354
+ ]) {
355
+ try {
356
+ Object.defineProperty(proto, key, {
357
+ get() {
358
+ throw new TypeError(
359
+ "SharedArrayBuffer is not available in sandbox"
360
+ );
361
+ },
362
+ configurable: false
363
+ });
364
+ } catch {
365
+ }
366
+ }
367
+ }
368
+ } catch {
369
+ }
370
+ }
371
+ try {
372
+ Object.defineProperty(globalThis, "SharedArrayBuffer", {
373
+ value: void 0,
374
+ configurable: false,
375
+ writable: false,
376
+ enumerable: false
377
+ });
378
+ } catch {
379
+ Reflect.deleteProperty(globalThis, "SharedArrayBuffer");
380
+ setGlobalValue("SharedArrayBuffer", void 0);
381
+ }
382
+ }
383
+ delete globalThis.__runtimeApplyConfig;
384
+ };
246
385
  })();
@@ -276,7 +276,7 @@
276
276
  };
277
277
  __requireExposeCustomGlobal("require", __require);
278
278
  function _resolveFrom(moduleName2, fromDir2) {
279
- const resolved2 = _resolveModule.applySyncPromise(void 0, [moduleName2, fromDir2]);
279
+ const resolved2 = _resolveModule(moduleName2, fromDir2);
280
280
  if (resolved2 === null) {
281
281
  const err = new Error("Cannot find module '" + moduleName2 + "'");
282
282
  err.code = "MODULE_NOT_FOUND";
@@ -549,7 +549,7 @@
549
549
  if (_unsupportedCoreModules.has(name)) {
550
550
  throw new Error(name + " is not supported in sandbox");
551
551
  }
552
- const polyfillCode = _loadPolyfill.applySyncPromise(void 0, [name]);
552
+ const polyfillCode = _loadPolyfill(name);
553
553
  if (polyfillCode !== null) {
554
554
  if (__internalModuleCache[name]) return __internalModuleCache[name];
555
555
  const moduleObj = { exports: {} };
@@ -576,7 +576,7 @@
576
576
  _debugRequire("pending-hit", name, cacheKey);
577
577
  return _pendingModules[cacheKey].exports;
578
578
  }
579
- const source = _loadFile.applySyncPromise(void 0, [resolved]);
579
+ const source = _loadFile(resolved);
580
580
  if (source === null) {
581
581
  const err = new Error("Cannot find module '" + resolved + "'");
582
582
  err.code = "MODULE_NOT_FOUND";
@@ -34,11 +34,7 @@
34
34
  const request = String(specifier);
35
35
  const referrer = typeof fromPath === "string" && fromPath.length > 0 ? fromPath : __fallbackReferrer;
36
36
  const allowRequireFallback = request.endsWith(".cjs") || request.endsWith(".json");
37
- const namespace = await globalThis._dynamicImport.apply(
38
- void 0,
39
- [request, referrer],
40
- { result: { promise: true } }
41
- );
37
+ const namespace = await globalThis._dynamicImport(request, referrer);
42
38
  if (namespace !== null) {
43
39
  return namespace;
44
40
  }
@@ -23,26 +23,65 @@
23
23
 
24
24
  // isolate-runtime/src/inject/setup-fs-facade.ts
25
25
  var __runtimeExposeCustomGlobal = getRuntimeExposeCustomGlobal();
26
- var __fsFacade = {
27
- readFile: globalThis._fsReadFile,
28
- writeFile: globalThis._fsWriteFile,
29
- readFileBinary: globalThis._fsReadFileBinary,
30
- writeFileBinary: globalThis._fsWriteFileBinary,
31
- readDir: globalThis._fsReadDir,
32
- mkdir: globalThis._fsMkdir,
33
- rmdir: globalThis._fsRmdir,
34
- exists: globalThis._fsExists,
35
- stat: globalThis._fsStat,
36
- unlink: globalThis._fsUnlink,
37
- rename: globalThis._fsRename,
38
- chmod: globalThis._fsChmod,
39
- chown: globalThis._fsChown,
40
- link: globalThis._fsLink,
41
- symlink: globalThis._fsSymlink,
42
- readlink: globalThis._fsReadlink,
43
- lstat: globalThis._fsLstat,
44
- truncate: globalThis._fsTruncate,
45
- utimes: globalThis._fsUtimes
46
- };
26
+ var __fsFacade = {};
27
+ Object.defineProperties(__fsFacade, {
28
+ readFile: { get() {
29
+ return globalThis._fsReadFile;
30
+ }, enumerable: true },
31
+ writeFile: { get() {
32
+ return globalThis._fsWriteFile;
33
+ }, enumerable: true },
34
+ readFileBinary: { get() {
35
+ return globalThis._fsReadFileBinary;
36
+ }, enumerable: true },
37
+ writeFileBinary: { get() {
38
+ return globalThis._fsWriteFileBinary;
39
+ }, enumerable: true },
40
+ readDir: { get() {
41
+ return globalThis._fsReadDir;
42
+ }, enumerable: true },
43
+ mkdir: { get() {
44
+ return globalThis._fsMkdir;
45
+ }, enumerable: true },
46
+ rmdir: { get() {
47
+ return globalThis._fsRmdir;
48
+ }, enumerable: true },
49
+ exists: { get() {
50
+ return globalThis._fsExists;
51
+ }, enumerable: true },
52
+ stat: { get() {
53
+ return globalThis._fsStat;
54
+ }, enumerable: true },
55
+ unlink: { get() {
56
+ return globalThis._fsUnlink;
57
+ }, enumerable: true },
58
+ rename: { get() {
59
+ return globalThis._fsRename;
60
+ }, enumerable: true },
61
+ chmod: { get() {
62
+ return globalThis._fsChmod;
63
+ }, enumerable: true },
64
+ chown: { get() {
65
+ return globalThis._fsChown;
66
+ }, enumerable: true },
67
+ link: { get() {
68
+ return globalThis._fsLink;
69
+ }, enumerable: true },
70
+ symlink: { get() {
71
+ return globalThis._fsSymlink;
72
+ }, enumerable: true },
73
+ readlink: { get() {
74
+ return globalThis._fsReadlink;
75
+ }, enumerable: true },
76
+ lstat: { get() {
77
+ return globalThis._fsLstat;
78
+ }, enumerable: true },
79
+ truncate: { get() {
80
+ return globalThis._fsTruncate;
81
+ }, enumerable: true },
82
+ utimes: { get() {
83
+ return globalThis._fsUtimes;
84
+ }, enumerable: true }
85
+ });
47
86
  __runtimeExposeCustomGlobal("_fs", __fsFacade);
48
87
  })();
@@ -9,12 +9,58 @@
9
9
  *
10
10
  * Everything else falls through to node-stdlib-browser polyfills or node_modules.
11
11
  */
12
- import stdLibBrowser from "node-stdlib-browser";
12
+ /**
13
+ * Static set of Node.js stdlib module names that have browser polyfills
14
+ * available via node-stdlib-browser. Hardcoded to avoid importing
15
+ * node-stdlib-browser at runtime (its ESM entry crashes on missing
16
+ * mock/empty.js in published builds).
17
+ */
18
+ const STDLIB_BROWSER_MODULES = new Set([
19
+ "assert",
20
+ "buffer",
21
+ "child_process",
22
+ "cluster",
23
+ "console",
24
+ "constants",
25
+ "crypto",
26
+ "dgram",
27
+ "dns",
28
+ "domain",
29
+ "events",
30
+ "fs",
31
+ "http",
32
+ "https",
33
+ "http2",
34
+ "module",
35
+ "net",
36
+ "os",
37
+ "path",
38
+ "punycode",
39
+ "process",
40
+ "querystring",
41
+ "readline",
42
+ "repl",
43
+ "stream",
44
+ "_stream_duplex",
45
+ "_stream_passthrough",
46
+ "_stream_readable",
47
+ "_stream_transform",
48
+ "_stream_writable",
49
+ "string_decoder",
50
+ "sys",
51
+ "timers/promises",
52
+ "timers",
53
+ "tls",
54
+ "tty",
55
+ "url",
56
+ "util",
57
+ "vm",
58
+ "zlib",
59
+ ]);
13
60
  /** Check if a module has a polyfill available via node-stdlib-browser. */
14
61
  function hasPolyfill(moduleName) {
15
62
  const name = moduleName.replace(/^node:/, "");
16
- const polyfill = stdLibBrowser[name];
17
- return polyfill !== undefined && polyfill !== null;
63
+ return STDLIB_BROWSER_MODULES.has(name);
18
64
  }
19
65
  /** Modules with full bridge implementations injected into the isolate. */
20
66
  const BRIDGE_MODULES = [
@@ -23,6 +23,12 @@ export interface ProcessConfig {
23
23
  timingMitigation?: TimingMitigation;
24
24
  /** Internal frozen clock source used when timing mitigation is enabled */
25
25
  frozenTimeMs?: number;
26
+ /** Whether stdin is a TTY (PTY slave attached) */
27
+ stdinIsTTY?: boolean;
28
+ /** Whether stdout is a TTY (PTY slave attached) */
29
+ stdoutIsTTY?: boolean;
30
+ /** Whether stderr is a TTY (PTY slave attached) */
31
+ stderrIsTTY?: boolean;
26
32
  }
27
33
  export interface OSConfig {
28
34
  platform?: string;
@@ -3,10 +3,11 @@
3
3
  * host (Node.js) and the isolate (sandbox V8 context).
4
4
  *
5
5
  * Two categories:
6
- * - Host bridge globals: set by the host before bridge code runs (fs refs, timers, etc.)
6
+ * - Host bridge globals: set by the host before bridge code runs (fs fns, timers, etc.)
7
7
  * - Runtime bridge globals: installed by the bridge bundle itself (active handles, modules, etc.)
8
8
  *
9
- * The typed `Ref` aliases describe the isolated-vm calling convention for each global.
9
+ * Each type alias is a plain function signature. The Rust V8 runtime registers
10
+ * these as real JS functions on the global; bridge code calls them directly.
10
11
  */
11
12
  export type ValueOf<T> = T[keyof T];
12
13
  /** Globals injected by the host before the bridge bundle executes. */
@@ -47,6 +48,7 @@ export declare const HOST_BRIDGE_GLOBAL_KEYS: {
47
48
  readonly networkHttpRequestRaw: "_networkHttpRequestRaw";
48
49
  readonly networkHttpServerListenRaw: "_networkHttpServerListenRaw";
49
50
  readonly networkHttpServerCloseRaw: "_networkHttpServerCloseRaw";
51
+ readonly ptySetRawMode: "_ptySetRawMode";
50
52
  readonly processConfig: "_processConfig";
51
53
  readonly osConfig: "_osConfig";
52
54
  readonly log: "_log";
@@ -112,6 +114,7 @@ export declare const HOST_BRIDGE_GLOBAL_KEY_LIST: ValueOf<{
112
114
  readonly networkHttpRequestRaw: "_networkHttpRequestRaw";
113
115
  readonly networkHttpServerListenRaw: "_networkHttpServerListenRaw";
114
116
  readonly networkHttpServerCloseRaw: "_networkHttpServerCloseRaw";
117
+ readonly ptySetRawMode: "_ptySetRawMode";
115
118
  readonly processConfig: "_processConfig";
116
119
  readonly osConfig: "_osConfig";
117
120
  readonly log: "_log";
@@ -173,6 +176,7 @@ export declare const BRIDGE_GLOBAL_KEY_LIST: readonly (ValueOf<{
173
176
  readonly networkHttpRequestRaw: "_networkHttpRequestRaw";
174
177
  readonly networkHttpServerListenRaw: "_networkHttpServerListenRaw";
175
178
  readonly networkHttpServerCloseRaw: "_networkHttpServerCloseRaw";
179
+ readonly ptySetRawMode: "_ptySetRawMode";
176
180
  readonly processConfig: "_processConfig";
177
181
  readonly osConfig: "_osConfig";
178
182
  readonly log: "_log";
@@ -196,65 +200,52 @@ export declare const BRIDGE_GLOBAL_KEY_LIST: readonly (ValueOf<{
196
200
  readonly moduleCache: "_moduleCache";
197
201
  readonly processExitError: "ProcessExitError";
198
202
  }>)[];
199
- /** An isolated-vm Reference that resolves async via `{ result: { promise: true } }`. */
200
- export interface BridgeApplyRef<TArgs extends unknown[], TResult> {
201
- apply(ctx: undefined, args: TArgs, options: {
202
- result: {
203
- promise: true;
204
- };
205
- }): Promise<TResult>;
206
- }
207
- /** An isolated-vm Reference called synchronously (blocks the isolate). */
208
- export interface BridgeApplySyncRef<TArgs extends unknown[], TResult> {
209
- applySync(ctx: undefined, args: TArgs): TResult;
210
- }
211
- /**
212
- * An isolated-vm Reference that blocks the isolate while the host resolves
213
- * a Promise. Used for sync-looking APIs (require, readFileSync) that need
214
- * async host operations.
215
- */
216
- export interface BridgeApplySyncPromiseRef<TArgs extends unknown[], TResult> {
217
- applySyncPromise(ctx: undefined, args: TArgs): TResult;
218
- }
219
- export type DynamicImportBridgeRef = BridgeApplyRef<[
220
- string,
221
- string
222
- ], Record<string, unknown> | null>;
223
- export type LoadPolyfillBridgeRef = BridgeApplyRef<[string], string | null>;
224
- export type ResolveModuleBridgeRef = BridgeApplySyncPromiseRef<[
225
- string,
226
- string
227
- ], string | null>;
228
- export type LoadFileBridgeRef = BridgeApplySyncPromiseRef<[string], string | null>;
203
+ export type DynamicImportBridgeRef = (specifier: string, fromPath: string) => Promise<Record<string, unknown> | null>;
204
+ export type LoadPolyfillBridgeRef = (moduleName: string) => string | null;
205
+ export type ResolveModuleBridgeRef = (request: string, fromDir: string) => string | null;
206
+ export type LoadFileBridgeRef = (path: string) => string | null;
229
207
  export type RequireFromBridgeFn = (request: string, dirname: string) => unknown;
230
208
  export type ModuleCacheBridgeRecord = Record<string, unknown>;
231
- export type ProcessLogBridgeRef = BridgeApplySyncRef<[string], void>;
232
- export type ProcessErrorBridgeRef = BridgeApplySyncRef<[string], void>;
233
- export type ScheduleTimerBridgeRef = BridgeApplyRef<[number], void>;
234
- export type CryptoRandomFillBridgeRef = BridgeApplySyncRef<[number], string>;
235
- export type CryptoRandomUuidBridgeRef = BridgeApplySyncRef<[], string>;
236
- export type FsReadFileBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
237
- export type FsWriteFileBridgeRef = BridgeApplySyncPromiseRef<[string, string], void>;
238
- export type FsReadFileBinaryBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
239
- export type FsWriteFileBinaryBridgeRef = BridgeApplySyncPromiseRef<[
240
- string,
241
- string
242
- ], void>;
243
- export type FsReadDirBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
244
- export type FsMkdirBridgeRef = BridgeApplySyncPromiseRef<[string, boolean], void>;
245
- export type FsRmdirBridgeRef = BridgeApplySyncPromiseRef<[string], void>;
246
- export type FsExistsBridgeRef = BridgeApplySyncPromiseRef<[string], boolean>;
247
- export type FsStatBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
248
- export type FsUnlinkBridgeRef = BridgeApplySyncPromiseRef<[string], void>;
249
- export type FsRenameBridgeRef = BridgeApplySyncPromiseRef<[string, string], void>;
250
- export type FsChmodBridgeRef = BridgeApplySyncPromiseRef<[string, number], void>;
251
- export type FsChownBridgeRef = BridgeApplySyncPromiseRef<[string, number, number], void>;
252
- export type FsLinkBridgeRef = BridgeApplySyncPromiseRef<[string, string], void>;
253
- export type FsSymlinkBridgeRef = BridgeApplySyncPromiseRef<[string, string], void>;
254
- export type FsReadlinkBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
255
- export type FsLstatBridgeRef = BridgeApplySyncPromiseRef<[string], string>;
256
- export type FsTruncateBridgeRef = BridgeApplySyncPromiseRef<[string, number], void>;
257
- export type FsUtimesBridgeRef = BridgeApplySyncPromiseRef<[string, number, number], void>;
209
+ export type ProcessLogBridgeRef = (msg: string) => void;
210
+ export type ProcessErrorBridgeRef = (msg: string) => void;
211
+ export type ScheduleTimerBridgeRef = (delayMs: number) => Promise<void>;
212
+ export type CryptoRandomFillBridgeRef = (byteLength: number) => Uint8Array;
213
+ export type CryptoRandomUuidBridgeRef = () => string;
214
+ export type FsReadFileBridgeRef = (path: string) => string;
215
+ export type FsWriteFileBridgeRef = (path: string, content: string) => void;
216
+ export type FsReadFileBinaryBridgeRef = (path: string) => Uint8Array;
217
+ export type FsWriteFileBinaryBridgeRef = (path: string, content: Uint8Array) => void;
218
+ export type FsReadDirEntry = {
219
+ name: string;
220
+ isDirectory: boolean;
221
+ };
222
+ export type FsReadDirBridgeRef = (path: string) => FsReadDirEntry[];
223
+ export type FsMkdirBridgeRef = (path: string, recursive: boolean) => void;
224
+ export type FsRmdirBridgeRef = (path: string) => void;
225
+ export type FsExistsBridgeRef = (path: string) => boolean;
226
+ export type FsStatResult = {
227
+ mode: number;
228
+ size: number;
229
+ isDirectory: boolean;
230
+ atimeMs: number;
231
+ mtimeMs: number;
232
+ ctimeMs: number;
233
+ birthtimeMs: number;
234
+ };
235
+ export type FsStatBridgeRef = (path: string) => FsStatResult;
236
+ export type FsUnlinkBridgeRef = (path: string) => void;
237
+ export type FsRenameBridgeRef = (oldPath: string, newPath: string) => void;
238
+ export type FsChmodBridgeRef = (path: string, mode: number) => void;
239
+ export type FsChownBridgeRef = (path: string, uid: number, gid: number) => void;
240
+ export type FsLinkBridgeRef = (existingPath: string, newPath: string) => void;
241
+ export type FsSymlinkBridgeRef = (target: string, path: string) => void;
242
+ export type FsReadlinkBridgeRef = (path: string) => string;
243
+ export type FsLstatResult = FsStatResult & {
244
+ isSymbolicLink: boolean;
245
+ };
246
+ export type FsLstatBridgeRef = (path: string) => FsLstatResult;
247
+ export type FsTruncateBridgeRef = (path: string, length: number) => void;
248
+ export type FsUtimesBridgeRef = (path: string, atime: number, mtime: number) => void;
258
249
  /** Combined filesystem bridge facade installed as `globalThis._fs` in the isolate. */
259
250
  export interface FsFacadeBridge {
260
251
  readFile: FsReadFileBridgeRef;
@@ -277,26 +268,52 @@ export interface FsFacadeBridge {
277
268
  truncate: FsTruncateBridgeRef;
278
269
  utimes: FsUtimesBridgeRef;
279
270
  }
280
- export type ChildProcessSpawnStartBridgeRef = BridgeApplySyncRef<[
281
- string,
282
- string,
283
- string
284
- ], number>;
285
- export type ChildProcessStdinWriteBridgeRef = BridgeApplySyncRef<[
286
- number,
287
- Uint8Array
288
- ], void>;
289
- export type ChildProcessStdinCloseBridgeRef = BridgeApplySyncRef<[number], void>;
290
- export type ChildProcessKillBridgeRef = BridgeApplySyncRef<[number, number], void>;
291
- export type ChildProcessSpawnSyncBridgeRef = BridgeApplySyncPromiseRef<[
292
- string,
293
- string,
294
- string
295
- ], string>;
296
- export type NetworkFetchRawBridgeRef = BridgeApplyRef<[string, string], string>;
297
- export type NetworkDnsLookupRawBridgeRef = BridgeApplyRef<[string], string>;
298
- export type NetworkHttpRequestRawBridgeRef = BridgeApplyRef<[string, string], string>;
299
- export type NetworkHttpServerListenRawBridgeRef = BridgeApplyRef<[string], string>;
300
- export type NetworkHttpServerCloseRawBridgeRef = BridgeApplyRef<[number], void>;
271
+ export type ChildProcessSpawnStartBridgeRef = (command: string, argsJson: string, optionsJson: string) => number;
272
+ export type ChildProcessStdinWriteBridgeRef = (sessionId: number, data: Uint8Array) => void;
273
+ export type ChildProcessStdinCloseBridgeRef = (sessionId: number) => void;
274
+ export type ChildProcessKillBridgeRef = (sessionId: number, signal: number) => void;
275
+ export type SpawnSyncBridgeResult = {
276
+ stdout: string;
277
+ stderr: string;
278
+ code: number;
279
+ maxBufferExceeded?: boolean;
280
+ };
281
+ export type ChildProcessSpawnSyncBridgeRef = (command: string, argsJson: string, optionsJson: string) => SpawnSyncBridgeResult;
282
+ export type NetworkFetchResult = {
283
+ ok: boolean;
284
+ status: number;
285
+ statusText: string;
286
+ headers?: Record<string, string>;
287
+ url?: string;
288
+ redirected?: boolean;
289
+ body?: string;
290
+ };
291
+ export type NetworkFetchRawBridgeRef = (url: string, optionsJson: string) => Promise<NetworkFetchResult>;
292
+ export type NetworkDnsLookupResult = {
293
+ error?: string;
294
+ code?: string;
295
+ address?: string;
296
+ family?: number;
297
+ };
298
+ export type NetworkDnsLookupRawBridgeRef = (hostname: string) => Promise<NetworkDnsLookupResult>;
299
+ export type NetworkHttpRequestResult = {
300
+ headers?: Record<string, string>;
301
+ url?: string;
302
+ status?: number;
303
+ statusText?: string;
304
+ body?: string;
305
+ trailers?: Record<string, string>;
306
+ };
307
+ export type NetworkHttpRequestRawBridgeRef = (url: string, optionsJson: string) => Promise<NetworkHttpRequestResult>;
308
+ export type NetworkHttpServerListenResult = {
309
+ address: {
310
+ address: string;
311
+ family: string;
312
+ port: number;
313
+ } | null;
314
+ };
315
+ export type NetworkHttpServerListenRawBridgeRef = (optionsJson: string) => Promise<NetworkHttpServerListenResult>;
316
+ export type NetworkHttpServerCloseRawBridgeRef = (serverId: number) => Promise<void>;
317
+ export type PtySetRawModeBridgeRef = (mode: boolean) => void;
301
318
  export type RegisterHandleBridgeFn = (id: string, description: string) => void;
302
319
  export type UnregisterHandleBridgeFn = (id: string) => void;
@@ -3,10 +3,11 @@
3
3
  * host (Node.js) and the isolate (sandbox V8 context).
4
4
  *
5
5
  * Two categories:
6
- * - Host bridge globals: set by the host before bridge code runs (fs refs, timers, etc.)
6
+ * - Host bridge globals: set by the host before bridge code runs (fs fns, timers, etc.)
7
7
  * - Runtime bridge globals: installed by the bridge bundle itself (active handles, modules, etc.)
8
8
  *
9
- * The typed `Ref` aliases describe the isolated-vm calling convention for each global.
9
+ * Each type alias is a plain function signature. The Rust V8 runtime registers
10
+ * these as real JS functions on the global; bridge code calls them directly.
10
11
  */
11
12
  function valuesOf(object) {
12
13
  return Object.values(object);
@@ -49,6 +50,7 @@ export const HOST_BRIDGE_GLOBAL_KEYS = {
49
50
  networkHttpRequestRaw: "_networkHttpRequestRaw",
50
51
  networkHttpServerListenRaw: "_networkHttpServerListenRaw",
51
52
  networkHttpServerCloseRaw: "_networkHttpServerCloseRaw",
53
+ ptySetRawMode: "_ptySetRawMode",
52
54
  processConfig: "_processConfig",
53
55
  osConfig: "_osConfig",
54
56
  log: "_log",
@@ -148,10 +148,10 @@ export function getConsoleSetupCode(budget = DEFAULT_CONSOLE_SERIALIZATION_BUDGE
148
148
  const formatConsoleArgs = ${formatConsoleArgs.toString()};
149
149
 
150
150
  globalThis.console = {
151
- log: (...args) => _log.applySync(undefined, [formatConsoleArgs(args, __consoleBudget)]),
152
- error: (...args) => _error.applySync(undefined, [formatConsoleArgs(args, __consoleBudget)]),
153
- warn: (...args) => _error.applySync(undefined, [formatConsoleArgs(args, __consoleBudget)]),
154
- info: (...args) => _log.applySync(undefined, [formatConsoleArgs(args, __consoleBudget)]),
151
+ log: (...args) => _log(formatConsoleArgs(args, __consoleBudget)),
152
+ error: (...args) => _error(formatConsoleArgs(args, __consoleBudget)),
153
+ warn: (...args) => _error(formatConsoleArgs(args, __consoleBudget)),
154
+ info: (...args) => _log(formatConsoleArgs(args, __consoleBudget)),
155
155
  };
156
156
  `;
157
157
  }
@@ -275,6 +275,11 @@ export const NODE_CUSTOM_GLOBAL_INVENTORY = [
275
275
  classification: "hardened",
276
276
  rationale: "Host network bridge reference.",
277
277
  },
278
+ {
279
+ name: "_ptySetRawMode",
280
+ classification: "hardened",
281
+ rationale: "Host PTY bridge reference for stdin.setRawMode().",
282
+ },
278
283
  {
279
284
  name: "require",
280
285
  classification: "hardened",
package/dist/types.d.ts CHANGED
@@ -162,6 +162,7 @@ export interface NetworkAdapter {
162
162
  method?: string;
163
163
  headers?: Record<string, string>;
164
164
  body?: string | null;
165
+ rejectUnauthorized?: boolean;
165
166
  }): Promise<{
166
167
  status: number;
167
168
  statusText: string;