sandboxedjs 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +143 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1509,6 +1509,7 @@ declare class Container {
|
|
|
1509
1509
|
private readonly hooks;
|
|
1510
1510
|
private disposed;
|
|
1511
1511
|
private defaultSession;
|
|
1512
|
+
private readonly restoreNodeChildProcessBridge;
|
|
1512
1513
|
private constructor();
|
|
1513
1514
|
static create(opts?: ContainerOptions): Promise<Container>;
|
|
1514
1515
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1509,6 +1509,7 @@ declare class Container {
|
|
|
1509
1509
|
private readonly hooks;
|
|
1510
1510
|
private disposed;
|
|
1511
1511
|
private defaultSession;
|
|
1512
|
+
private readonly restoreNodeChildProcessBridge;
|
|
1512
1513
|
private constructor();
|
|
1513
1514
|
static create(opts?: ContainerOptions): Promise<Container>;
|
|
1514
1515
|
/**
|
package/dist/index.js
CHANGED
|
@@ -23670,6 +23670,146 @@ var Session = class {
|
|
|
23670
23670
|
}
|
|
23671
23671
|
};
|
|
23672
23672
|
|
|
23673
|
+
// src/runtime/node-child-process-bridge.ts
|
|
23674
|
+
var KernelChildProcess = class {
|
|
23675
|
+
pid;
|
|
23676
|
+
command;
|
|
23677
|
+
args;
|
|
23678
|
+
parentPid;
|
|
23679
|
+
state = "running";
|
|
23680
|
+
exitCode;
|
|
23681
|
+
stdout = "";
|
|
23682
|
+
stderr = "";
|
|
23683
|
+
listeners = /* @__PURE__ */ new Map();
|
|
23684
|
+
kernel;
|
|
23685
|
+
cred;
|
|
23686
|
+
cwd;
|
|
23687
|
+
env;
|
|
23688
|
+
stdin = new Pipe();
|
|
23689
|
+
process;
|
|
23690
|
+
started = false;
|
|
23691
|
+
cancelled = false;
|
|
23692
|
+
constructor(kernel, cred, config, pid) {
|
|
23693
|
+
this.kernel = kernel;
|
|
23694
|
+
this.cred = cred;
|
|
23695
|
+
this.pid = pid;
|
|
23696
|
+
this.command = config.command;
|
|
23697
|
+
this.args = config.args?.slice() ?? [];
|
|
23698
|
+
this.parentPid = config.parentPid;
|
|
23699
|
+
this.cwd = config.cwd ?? "/";
|
|
23700
|
+
this.env = { ...config.env };
|
|
23701
|
+
}
|
|
23702
|
+
on(event, listener) {
|
|
23703
|
+
let listeners = this.listeners.get(event);
|
|
23704
|
+
if (!listeners) {
|
|
23705
|
+
listeners = /* @__PURE__ */ new Set();
|
|
23706
|
+
this.listeners.set(event, listeners);
|
|
23707
|
+
}
|
|
23708
|
+
listeners.add(listener);
|
|
23709
|
+
return this;
|
|
23710
|
+
}
|
|
23711
|
+
emit(event, ...args) {
|
|
23712
|
+
for (const listener of this.listeners.get(event) ?? []) listener(...args);
|
|
23713
|
+
}
|
|
23714
|
+
exec() {
|
|
23715
|
+
if (this.started) return;
|
|
23716
|
+
this.started = true;
|
|
23717
|
+
queueMicrotask(() => {
|
|
23718
|
+
if (this.cancelled) {
|
|
23719
|
+
this.finish(143);
|
|
23720
|
+
return;
|
|
23721
|
+
}
|
|
23722
|
+
const stdout = new ChildOutput(this, "stdout");
|
|
23723
|
+
const stderr = new ChildOutput(this, "stderr");
|
|
23724
|
+
try {
|
|
23725
|
+
this.process = this.kernel.spawn([this.command, ...this.args], {
|
|
23726
|
+
cwd: this.cwd,
|
|
23727
|
+
env: this.env,
|
|
23728
|
+
cred: this.cred,
|
|
23729
|
+
stdin: this.stdin,
|
|
23730
|
+
stdout,
|
|
23731
|
+
stderr,
|
|
23732
|
+
ppid: 1
|
|
23733
|
+
});
|
|
23734
|
+
void this.process.wait().then((code) => {
|
|
23735
|
+
stdout.end();
|
|
23736
|
+
stderr.end();
|
|
23737
|
+
this.finish(code);
|
|
23738
|
+
});
|
|
23739
|
+
} catch (error) {
|
|
23740
|
+
stderr.write(error instanceof Error ? error.message : String(error));
|
|
23741
|
+
stderr.end();
|
|
23742
|
+
stdout.end();
|
|
23743
|
+
this.finish(1);
|
|
23744
|
+
}
|
|
23745
|
+
});
|
|
23746
|
+
}
|
|
23747
|
+
sendStdin(data) {
|
|
23748
|
+
try {
|
|
23749
|
+
this.stdin.write(data);
|
|
23750
|
+
} catch {
|
|
23751
|
+
}
|
|
23752
|
+
}
|
|
23753
|
+
kill(signal = "SIGTERM") {
|
|
23754
|
+
if (this.process) {
|
|
23755
|
+
this.process.deliver(signal);
|
|
23756
|
+
return;
|
|
23757
|
+
}
|
|
23758
|
+
this.cancelled = true;
|
|
23759
|
+
}
|
|
23760
|
+
finish(code) {
|
|
23761
|
+
if (this.state === "exited") return;
|
|
23762
|
+
this.state = "exited";
|
|
23763
|
+
this.exitCode = code;
|
|
23764
|
+
this.emit("exit", code);
|
|
23765
|
+
}
|
|
23766
|
+
append(stream, text) {
|
|
23767
|
+
this[stream] += text;
|
|
23768
|
+
this.emit(stream, text);
|
|
23769
|
+
}
|
|
23770
|
+
};
|
|
23771
|
+
var ChildOutput = class {
|
|
23772
|
+
constructor(child, stream) {
|
|
23773
|
+
this.child = child;
|
|
23774
|
+
this.stream = stream;
|
|
23775
|
+
}
|
|
23776
|
+
child;
|
|
23777
|
+
stream;
|
|
23778
|
+
isTTY = false;
|
|
23779
|
+
closedState = false;
|
|
23780
|
+
decoder = new TextDecoder();
|
|
23781
|
+
get closed() {
|
|
23782
|
+
return this.closedState;
|
|
23783
|
+
}
|
|
23784
|
+
write(data) {
|
|
23785
|
+
if (this.closedState) return;
|
|
23786
|
+
const text = typeof data === "string" ? data : this.decoder.decode(data, { stream: true });
|
|
23787
|
+
if (text) this.child.append(this.stream, text);
|
|
23788
|
+
}
|
|
23789
|
+
end() {
|
|
23790
|
+
if (this.closedState) return;
|
|
23791
|
+
this.closedState = true;
|
|
23792
|
+
const tail2 = this.decoder.decode();
|
|
23793
|
+
if (tail2) this.child.append(this.stream, tail2);
|
|
23794
|
+
}
|
|
23795
|
+
};
|
|
23796
|
+
var nextBridgePid = 1073741824;
|
|
23797
|
+
function installNodeChildProcessBridge(pod, kernel, cred) {
|
|
23798
|
+
const manager = pod.processManager;
|
|
23799
|
+
const originalSpawn = manager.spawn;
|
|
23800
|
+
manager.spawn = (config) => {
|
|
23801
|
+
const resolved = kernel.resolveExecutable(config.command, config.cwd ?? "/", config.env ?? {}, cred);
|
|
23802
|
+
if (resolved?.kind === "builtin" && resolved.command?.name !== "node" && resolved.command?.name !== "nodejs") {
|
|
23803
|
+
return new KernelChildProcess(kernel, cred, config, nextBridgePid++);
|
|
23804
|
+
}
|
|
23805
|
+
return originalSpawn.call(manager, config);
|
|
23806
|
+
};
|
|
23807
|
+
return () => {
|
|
23808
|
+
if (manager.spawn === originalSpawn) return;
|
|
23809
|
+
manager.spawn = originalSpawn;
|
|
23810
|
+
};
|
|
23811
|
+
}
|
|
23812
|
+
|
|
23673
23813
|
// src/container/container.ts
|
|
23674
23814
|
var Container = class _Container {
|
|
23675
23815
|
kernel;
|
|
@@ -23680,6 +23820,7 @@ var Container = class _Container {
|
|
|
23680
23820
|
hooks;
|
|
23681
23821
|
disposed = false;
|
|
23682
23822
|
defaultSession = null;
|
|
23823
|
+
restoreNodeChildProcessBridge;
|
|
23683
23824
|
constructor(kernel, pod, opts) {
|
|
23684
23825
|
this.kernel = kernel;
|
|
23685
23826
|
this.pod = pod;
|
|
@@ -23708,6 +23849,7 @@ var Container = class _Container {
|
|
|
23708
23849
|
};
|
|
23709
23850
|
if (opts.timeoutMs !== void 0) this.defaults.timeoutMs = opts.timeoutMs;
|
|
23710
23851
|
this.hooks = { onStdout: opts.onStdout, onStderr: opts.onStderr };
|
|
23852
|
+
this.restoreNodeChildProcessBridge = installNodeChildProcessBridge(pod, kernel, cred);
|
|
23711
23853
|
}
|
|
23712
23854
|
// ── boot ──────────────────────────────────────────────────────────────────
|
|
23713
23855
|
static async create(opts = {}) {
|
|
@@ -24118,6 +24260,7 @@ var Container = class _Container {
|
|
|
24118
24260
|
dispose() {
|
|
24119
24261
|
if (this.disposed) return;
|
|
24120
24262
|
this.disposed = true;
|
|
24263
|
+
this.restoreNodeChildProcessBridge();
|
|
24121
24264
|
this.kernel.dispose();
|
|
24122
24265
|
try {
|
|
24123
24266
|
this.pod.teardown();
|