sandboxedjs 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -11
- package/dist/index.cjs +821 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -10
- package/dist/index.d.ts +45 -10
- package/dist/index.js +821 -55
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.cts
CHANGED
|
@@ -9,6 +9,14 @@ interface ChildHandle {
|
|
|
9
9
|
on(event: "stdout" | "stderr" | "exit", listener: (...args: any[]) => void): unknown;
|
|
10
10
|
exec(): void;
|
|
11
11
|
sendStdin(data: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* Close the child's input.
|
|
14
|
+
*
|
|
15
|
+
* Without this a child that reads stdin to EOF — every filter, and every
|
|
16
|
+
* tool a library pipes into, `xsel` and `base64` alike — waits forever for
|
|
17
|
+
* an end that never comes, and the parent waits on its exit.
|
|
18
|
+
*/
|
|
19
|
+
endStdin?(): void;
|
|
12
20
|
kill(signal?: string): void;
|
|
13
21
|
}
|
|
14
22
|
interface ChildSpawnConfig {
|
|
@@ -196,7 +204,7 @@ interface DirEntry {
|
|
|
196
204
|
/**
|
|
197
205
|
* The container's virtual filesystem.
|
|
198
206
|
*
|
|
199
|
-
* Real file content lives in
|
|
207
|
+
* Real file content lives in the RuntimePod's `MemoryVolume`, deliberately the
|
|
200
208
|
* *same* volume the Node.js worker processes see — so a file written by `echo`
|
|
201
209
|
* is readable by `require('fs')` inside a spawned script, and vice versa.
|
|
202
210
|
*
|
|
@@ -746,7 +754,7 @@ declare function createContext(init: ContextInit): ExecContext;
|
|
|
746
754
|
* The container's network stack.
|
|
747
755
|
*
|
|
748
756
|
* There is no real socket layer: HTTP servers started inside the container are
|
|
749
|
-
* registered with
|
|
757
|
+
* registered with the RuntimePod's request proxy, and this module is the routing and
|
|
750
758
|
* name-resolution layer on top — interfaces for `ip`/`ifconfig`, a hosts file
|
|
751
759
|
* resolver, a listening-port table for `ss`/`netstat`, and an outbound policy
|
|
752
760
|
* that decides whether `curl https://example.com` is allowed to touch the real
|
|
@@ -805,7 +813,7 @@ declare class NetworkStack {
|
|
|
805
813
|
registerListener(port: number, info: Omit<ListeningPort, "port" | "since">): void;
|
|
806
814
|
unregisterListener(port: number): void;
|
|
807
815
|
listening(): ListeningPort[];
|
|
808
|
-
/** Ports
|
|
816
|
+
/** Ports the pod's proxy has registered for this instance. */
|
|
809
817
|
private knownPodPorts;
|
|
810
818
|
/** True when something inside the container answers on `port`. */
|
|
811
819
|
isPortOpen(port: number, timeoutMs?: number): Promise<boolean>;
|
|
@@ -1732,7 +1740,7 @@ declare class Container {
|
|
|
1732
1740
|
/**
|
|
1733
1741
|
* Deliver a request whose body is bytes, without letting them become text.
|
|
1734
1742
|
*
|
|
1735
|
-
*
|
|
1743
|
+
* A RuntimePod's public `request()` may run the body through `toString("utf8")` on
|
|
1736
1744
|
* its way in, so anything above `0x7f` is replaced: a five-byte payload
|
|
1737
1745
|
* containing `0x89` and `0xff` arrives as nine. That silently destroys every
|
|
1738
1746
|
* upload — an image or a video reaches the server the wrong size and no
|
|
@@ -1772,7 +1780,7 @@ declare class Container {
|
|
|
1772
1780
|
get cwd(): string;
|
|
1773
1781
|
get env(): Record<string, string>;
|
|
1774
1782
|
private assertActive;
|
|
1775
|
-
/** Tear down every process and release the
|
|
1783
|
+
/** Tear down every process and release the runtime pod. */
|
|
1776
1784
|
dispose(): void;
|
|
1777
1785
|
get isDisposed(): boolean;
|
|
1778
1786
|
}
|
|
@@ -2114,17 +2122,16 @@ interface RootfsOptions {
|
|
|
2114
2122
|
declare function buildRootfs(vfs: Vfs, opts?: RootfsOptions): void;
|
|
2115
2123
|
|
|
2116
2124
|
/**
|
|
2117
|
-
* The Node.js
|
|
2125
|
+
* The Node.js command adapter, backed by the clean-room RuntimePod.
|
|
2118
2126
|
*
|
|
2119
|
-
*
|
|
2127
|
+
* The pod runs the script over the *same* memory volume
|
|
2120
2128
|
* the container's filesystem uses, so `require('fs')` inside a script sees the
|
|
2121
2129
|
* files `echo` and `tar` created, and anything the script writes is visible to
|
|
2122
2130
|
* the shell afterwards.
|
|
2123
2131
|
*
|
|
2124
|
-
* Two
|
|
2132
|
+
* Two details of the underlying `spawn` are handled here:
|
|
2125
2133
|
* - only `node` resolves as a command, so everything else is dispatched by our
|
|
2126
|
-
* own kernel rather than being handed to
|
|
2127
|
-
* unknown command);
|
|
2134
|
+
* own kernel rather than being handed to the Node process runner;
|
|
2128
2135
|
* - the worker's stdin has no end-of-stream signal, so when a pipeline feeds
|
|
2129
2136
|
* a script we materialise stdin as a file and install a real stdin stream
|
|
2130
2137
|
* over it before the script loads.
|
|
@@ -2427,6 +2434,8 @@ declare class VirtualHttpRouter {
|
|
|
2427
2434
|
onListen: ((port: number) => void) | undefined;
|
|
2428
2435
|
register(port: number, server: VirtualHttpServer, owner: string): void;
|
|
2429
2436
|
unregister(port: number, server: VirtualHttpServer): void;
|
|
2437
|
+
/** Whether anything in this container is listening on `port`. */
|
|
2438
|
+
activePortsIncludes(port: number): boolean;
|
|
2430
2439
|
activePorts(owner?: string): number[];
|
|
2431
2440
|
closeOwner(owner: string): void;
|
|
2432
2441
|
closeAll(): void;
|
|
@@ -2444,6 +2453,7 @@ interface CoreModulesOptions {
|
|
|
2444
2453
|
http?: {
|
|
2445
2454
|
router: VirtualHttpRouter;
|
|
2446
2455
|
owner: string;
|
|
2456
|
+
fetch?: typeof globalThis.fetch;
|
|
2447
2457
|
};
|
|
2448
2458
|
/** Backs `child_process`; without it the module reports as unavailable. */
|
|
2449
2459
|
spawnChild?: SpawnChild;
|
|
@@ -2484,6 +2494,16 @@ declare function createCoreModules(options: CoreModulesOptions): {
|
|
|
2484
2494
|
* script that has simply finished.
|
|
2485
2495
|
*/
|
|
2486
2496
|
pendingHandles(): number;
|
|
2497
|
+
/** Active timers which called `unref()` and therefore only merit startup grace. */
|
|
2498
|
+
pendingUnrefed(): number;
|
|
2499
|
+
/**
|
|
2500
|
+
* Client requests sent but not yet read to completion.
|
|
2501
|
+
*
|
|
2502
|
+
* An outbound request is event-loop work in exactly the way a timer is, and
|
|
2503
|
+
* it schedules no timer of its own. Counting it is what stops a program from
|
|
2504
|
+
* exiting in the gap between `http.get` and its response callback.
|
|
2505
|
+
*/
|
|
2506
|
+
pendingRequests(): number;
|
|
2487
2507
|
};
|
|
2488
2508
|
|
|
2489
2509
|
interface EsmTransformResult {
|
|
@@ -2570,9 +2590,20 @@ declare class LocalRuntimePod implements RuntimePod {
|
|
|
2570
2590
|
private readonly aliases;
|
|
2571
2591
|
private readonly modules;
|
|
2572
2592
|
private readonly esbuild;
|
|
2593
|
+
private rolldownBinding;
|
|
2594
|
+
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
2595
|
+
private readonly fetch;
|
|
2573
2596
|
private constructor();
|
|
2574
2597
|
static boot(options?: LocalRuntimeOptions): Promise<LocalRuntimePod>;
|
|
2575
2598
|
spawn(command: string, args?: string[], options?: Record<string, unknown>): Promise<RuntimeProcess>;
|
|
2599
|
+
/**
|
|
2600
|
+
* Rolldown's JavaScript API synchronously requires its compiled binding.
|
|
2601
|
+
* When a project contains Rolldown, preload the official WASI build in the
|
|
2602
|
+
* host and expose it through the module override table before evaluation.
|
|
2603
|
+
* Keeping this demand-driven avoids adding WASM startup cost to ordinary
|
|
2604
|
+
* shells and Node programs.
|
|
2605
|
+
*/
|
|
2606
|
+
private prepareRolldown;
|
|
2576
2607
|
/**
|
|
2577
2608
|
* Wait until the process has either started serving or genuinely run out of
|
|
2578
2609
|
* work.
|
|
@@ -2607,6 +2638,10 @@ interface RegistryManifest {
|
|
|
2607
2638
|
};
|
|
2608
2639
|
dependencies?: Record<string, string>;
|
|
2609
2640
|
optionalDependencies?: Record<string, string>;
|
|
2641
|
+
os?: string[];
|
|
2642
|
+
cpu?: string[];
|
|
2643
|
+
libc?: string[];
|
|
2644
|
+
main?: string;
|
|
2610
2645
|
bin?: string | Record<string, string>;
|
|
2611
2646
|
}
|
|
2612
2647
|
interface CleanInstallerOptions {
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,14 @@ interface ChildHandle {
|
|
|
9
9
|
on(event: "stdout" | "stderr" | "exit", listener: (...args: any[]) => void): unknown;
|
|
10
10
|
exec(): void;
|
|
11
11
|
sendStdin(data: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* Close the child's input.
|
|
14
|
+
*
|
|
15
|
+
* Without this a child that reads stdin to EOF — every filter, and every
|
|
16
|
+
* tool a library pipes into, `xsel` and `base64` alike — waits forever for
|
|
17
|
+
* an end that never comes, and the parent waits on its exit.
|
|
18
|
+
*/
|
|
19
|
+
endStdin?(): void;
|
|
12
20
|
kill(signal?: string): void;
|
|
13
21
|
}
|
|
14
22
|
interface ChildSpawnConfig {
|
|
@@ -196,7 +204,7 @@ interface DirEntry {
|
|
|
196
204
|
/**
|
|
197
205
|
* The container's virtual filesystem.
|
|
198
206
|
*
|
|
199
|
-
* Real file content lives in
|
|
207
|
+
* Real file content lives in the RuntimePod's `MemoryVolume`, deliberately the
|
|
200
208
|
* *same* volume the Node.js worker processes see — so a file written by `echo`
|
|
201
209
|
* is readable by `require('fs')` inside a spawned script, and vice versa.
|
|
202
210
|
*
|
|
@@ -746,7 +754,7 @@ declare function createContext(init: ContextInit): ExecContext;
|
|
|
746
754
|
* The container's network stack.
|
|
747
755
|
*
|
|
748
756
|
* There is no real socket layer: HTTP servers started inside the container are
|
|
749
|
-
* registered with
|
|
757
|
+
* registered with the RuntimePod's request proxy, and this module is the routing and
|
|
750
758
|
* name-resolution layer on top — interfaces for `ip`/`ifconfig`, a hosts file
|
|
751
759
|
* resolver, a listening-port table for `ss`/`netstat`, and an outbound policy
|
|
752
760
|
* that decides whether `curl https://example.com` is allowed to touch the real
|
|
@@ -805,7 +813,7 @@ declare class NetworkStack {
|
|
|
805
813
|
registerListener(port: number, info: Omit<ListeningPort, "port" | "since">): void;
|
|
806
814
|
unregisterListener(port: number): void;
|
|
807
815
|
listening(): ListeningPort[];
|
|
808
|
-
/** Ports
|
|
816
|
+
/** Ports the pod's proxy has registered for this instance. */
|
|
809
817
|
private knownPodPorts;
|
|
810
818
|
/** True when something inside the container answers on `port`. */
|
|
811
819
|
isPortOpen(port: number, timeoutMs?: number): Promise<boolean>;
|
|
@@ -1732,7 +1740,7 @@ declare class Container {
|
|
|
1732
1740
|
/**
|
|
1733
1741
|
* Deliver a request whose body is bytes, without letting them become text.
|
|
1734
1742
|
*
|
|
1735
|
-
*
|
|
1743
|
+
* A RuntimePod's public `request()` may run the body through `toString("utf8")` on
|
|
1736
1744
|
* its way in, so anything above `0x7f` is replaced: a five-byte payload
|
|
1737
1745
|
* containing `0x89` and `0xff` arrives as nine. That silently destroys every
|
|
1738
1746
|
* upload — an image or a video reaches the server the wrong size and no
|
|
@@ -1772,7 +1780,7 @@ declare class Container {
|
|
|
1772
1780
|
get cwd(): string;
|
|
1773
1781
|
get env(): Record<string, string>;
|
|
1774
1782
|
private assertActive;
|
|
1775
|
-
/** Tear down every process and release the
|
|
1783
|
+
/** Tear down every process and release the runtime pod. */
|
|
1776
1784
|
dispose(): void;
|
|
1777
1785
|
get isDisposed(): boolean;
|
|
1778
1786
|
}
|
|
@@ -2114,17 +2122,16 @@ interface RootfsOptions {
|
|
|
2114
2122
|
declare function buildRootfs(vfs: Vfs, opts?: RootfsOptions): void;
|
|
2115
2123
|
|
|
2116
2124
|
/**
|
|
2117
|
-
* The Node.js
|
|
2125
|
+
* The Node.js command adapter, backed by the clean-room RuntimePod.
|
|
2118
2126
|
*
|
|
2119
|
-
*
|
|
2127
|
+
* The pod runs the script over the *same* memory volume
|
|
2120
2128
|
* the container's filesystem uses, so `require('fs')` inside a script sees the
|
|
2121
2129
|
* files `echo` and `tar` created, and anything the script writes is visible to
|
|
2122
2130
|
* the shell afterwards.
|
|
2123
2131
|
*
|
|
2124
|
-
* Two
|
|
2132
|
+
* Two details of the underlying `spawn` are handled here:
|
|
2125
2133
|
* - only `node` resolves as a command, so everything else is dispatched by our
|
|
2126
|
-
* own kernel rather than being handed to
|
|
2127
|
-
* unknown command);
|
|
2134
|
+
* own kernel rather than being handed to the Node process runner;
|
|
2128
2135
|
* - the worker's stdin has no end-of-stream signal, so when a pipeline feeds
|
|
2129
2136
|
* a script we materialise stdin as a file and install a real stdin stream
|
|
2130
2137
|
* over it before the script loads.
|
|
@@ -2427,6 +2434,8 @@ declare class VirtualHttpRouter {
|
|
|
2427
2434
|
onListen: ((port: number) => void) | undefined;
|
|
2428
2435
|
register(port: number, server: VirtualHttpServer, owner: string): void;
|
|
2429
2436
|
unregister(port: number, server: VirtualHttpServer): void;
|
|
2437
|
+
/** Whether anything in this container is listening on `port`. */
|
|
2438
|
+
activePortsIncludes(port: number): boolean;
|
|
2430
2439
|
activePorts(owner?: string): number[];
|
|
2431
2440
|
closeOwner(owner: string): void;
|
|
2432
2441
|
closeAll(): void;
|
|
@@ -2444,6 +2453,7 @@ interface CoreModulesOptions {
|
|
|
2444
2453
|
http?: {
|
|
2445
2454
|
router: VirtualHttpRouter;
|
|
2446
2455
|
owner: string;
|
|
2456
|
+
fetch?: typeof globalThis.fetch;
|
|
2447
2457
|
};
|
|
2448
2458
|
/** Backs `child_process`; without it the module reports as unavailable. */
|
|
2449
2459
|
spawnChild?: SpawnChild;
|
|
@@ -2484,6 +2494,16 @@ declare function createCoreModules(options: CoreModulesOptions): {
|
|
|
2484
2494
|
* script that has simply finished.
|
|
2485
2495
|
*/
|
|
2486
2496
|
pendingHandles(): number;
|
|
2497
|
+
/** Active timers which called `unref()` and therefore only merit startup grace. */
|
|
2498
|
+
pendingUnrefed(): number;
|
|
2499
|
+
/**
|
|
2500
|
+
* Client requests sent but not yet read to completion.
|
|
2501
|
+
*
|
|
2502
|
+
* An outbound request is event-loop work in exactly the way a timer is, and
|
|
2503
|
+
* it schedules no timer of its own. Counting it is what stops a program from
|
|
2504
|
+
* exiting in the gap between `http.get` and its response callback.
|
|
2505
|
+
*/
|
|
2506
|
+
pendingRequests(): number;
|
|
2487
2507
|
};
|
|
2488
2508
|
|
|
2489
2509
|
interface EsmTransformResult {
|
|
@@ -2570,9 +2590,20 @@ declare class LocalRuntimePod implements RuntimePod {
|
|
|
2570
2590
|
private readonly aliases;
|
|
2571
2591
|
private readonly modules;
|
|
2572
2592
|
private readonly esbuild;
|
|
2593
|
+
private rolldownBinding;
|
|
2594
|
+
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
2595
|
+
private readonly fetch;
|
|
2573
2596
|
private constructor();
|
|
2574
2597
|
static boot(options?: LocalRuntimeOptions): Promise<LocalRuntimePod>;
|
|
2575
2598
|
spawn(command: string, args?: string[], options?: Record<string, unknown>): Promise<RuntimeProcess>;
|
|
2599
|
+
/**
|
|
2600
|
+
* Rolldown's JavaScript API synchronously requires its compiled binding.
|
|
2601
|
+
* When a project contains Rolldown, preload the official WASI build in the
|
|
2602
|
+
* host and expose it through the module override table before evaluation.
|
|
2603
|
+
* Keeping this demand-driven avoids adding WASM startup cost to ordinary
|
|
2604
|
+
* shells and Node programs.
|
|
2605
|
+
*/
|
|
2606
|
+
private prepareRolldown;
|
|
2576
2607
|
/**
|
|
2577
2608
|
* Wait until the process has either started serving or genuinely run out of
|
|
2578
2609
|
* work.
|
|
@@ -2607,6 +2638,10 @@ interface RegistryManifest {
|
|
|
2607
2638
|
};
|
|
2608
2639
|
dependencies?: Record<string, string>;
|
|
2609
2640
|
optionalDependencies?: Record<string, string>;
|
|
2641
|
+
os?: string[];
|
|
2642
|
+
cpu?: string[];
|
|
2643
|
+
libc?: string[];
|
|
2644
|
+
main?: string;
|
|
2610
2645
|
bin?: string | Record<string, string>;
|
|
2611
2646
|
}
|
|
2612
2647
|
interface CleanInstallerOptions {
|