sandboxedjs 0.1.27 → 0.1.29
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 +52 -7
- package/dist/index.cjs +1540 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +219 -8
- package/dist/index.d.ts +219 -8
- package/dist/index.js +1539 -108
- package/dist/index.js.map +1 -1
- package/dist/worker-entry.js +30822 -0
- package/dist/worker-entry.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7332,15 +7332,15 @@ var Parser = class {
|
|
|
7332
7332
|
if (this.isWord("-p")) this.next();
|
|
7333
7333
|
}
|
|
7334
7334
|
}
|
|
7335
|
-
const
|
|
7335
|
+
const commands12 = [this.parseCommand()];
|
|
7336
7336
|
const stderrToo = [];
|
|
7337
7337
|
while (this.isOp("|") || this.isOp("|&")) {
|
|
7338
7338
|
stderrToo.push(this.next().value === "|&");
|
|
7339
7339
|
this.skipNewlines();
|
|
7340
|
-
|
|
7340
|
+
commands12.push(this.parseCommand());
|
|
7341
7341
|
}
|
|
7342
|
-
if (
|
|
7343
|
-
return { type: "pipeline", commands:
|
|
7342
|
+
if (commands12.length === 1 && !negated && !timed) return commands12[0];
|
|
7343
|
+
return { type: "pipeline", commands: commands12, negated, stderrToo, timed };
|
|
7344
7344
|
}
|
|
7345
7345
|
// ── commands ─────────────────────────────────────────────────────────────
|
|
7346
7346
|
parseCommand() {
|
|
@@ -16963,6 +16963,145 @@ var helpCmd = defineCommand({
|
|
|
16963
16963
|
});
|
|
16964
16964
|
var commands10 = [man, whatis, apropos, less, helpCmd];
|
|
16965
16965
|
|
|
16966
|
+
// src/bin/clipboard.ts
|
|
16967
|
+
init_path();
|
|
16968
|
+
var CLIPBOARD_DIR = "/run/clipboard";
|
|
16969
|
+
function selectionPath(selection) {
|
|
16970
|
+
return join(CLIPBOARD_DIR, selection);
|
|
16971
|
+
}
|
|
16972
|
+
function readSelection(ctx, selection) {
|
|
16973
|
+
try {
|
|
16974
|
+
return ctx.vfs.readFile(selectionPath(selection), ctx.cred);
|
|
16975
|
+
} catch {
|
|
16976
|
+
return new Uint8Array();
|
|
16977
|
+
}
|
|
16978
|
+
}
|
|
16979
|
+
function writeSelection(ctx, selection, bytes2) {
|
|
16980
|
+
try {
|
|
16981
|
+
ctx.vfs.mkdir(CLIPBOARD_DIR, { recursive: true, mode: 511 });
|
|
16982
|
+
} catch {
|
|
16983
|
+
}
|
|
16984
|
+
ctx.vfs.writeFile(selectionPath(selection), bytes2, { privileged: true, mode: 438 });
|
|
16985
|
+
}
|
|
16986
|
+
var xsel = defineCommand({
|
|
16987
|
+
name: "xsel",
|
|
16988
|
+
summary: "access an X selection",
|
|
16989
|
+
usage: "xsel [--clipboard|--primary|--secondary] [--input|--output|--clear]",
|
|
16990
|
+
async run(ctx) {
|
|
16991
|
+
let selection = "primary";
|
|
16992
|
+
let mode = "output";
|
|
16993
|
+
for (const arg of ctx.args) {
|
|
16994
|
+
switch (arg) {
|
|
16995
|
+
case "-b":
|
|
16996
|
+
case "--clipboard":
|
|
16997
|
+
selection = "clipboard";
|
|
16998
|
+
break;
|
|
16999
|
+
case "-p":
|
|
17000
|
+
case "--primary":
|
|
17001
|
+
selection = "primary";
|
|
17002
|
+
break;
|
|
17003
|
+
case "-s":
|
|
17004
|
+
case "--secondary":
|
|
17005
|
+
selection = "secondary";
|
|
17006
|
+
break;
|
|
17007
|
+
case "-i":
|
|
17008
|
+
case "--input":
|
|
17009
|
+
case "-a":
|
|
17010
|
+
case "--append":
|
|
17011
|
+
mode = "input";
|
|
17012
|
+
break;
|
|
17013
|
+
case "-o":
|
|
17014
|
+
case "--output":
|
|
17015
|
+
mode = "output";
|
|
17016
|
+
break;
|
|
17017
|
+
case "-c":
|
|
17018
|
+
case "--clear":
|
|
17019
|
+
mode = "clear";
|
|
17020
|
+
break;
|
|
17021
|
+
}
|
|
17022
|
+
}
|
|
17023
|
+
if (mode === "clear") {
|
|
17024
|
+
writeSelection(ctx, selection, new Uint8Array());
|
|
17025
|
+
return 0;
|
|
17026
|
+
}
|
|
17027
|
+
if (mode === "input") {
|
|
17028
|
+
writeSelection(ctx, selection, await ctx.stdin.readAll());
|
|
17029
|
+
return 0;
|
|
17030
|
+
}
|
|
17031
|
+
ctx.write(readSelection(ctx, selection));
|
|
17032
|
+
return 0;
|
|
17033
|
+
}
|
|
17034
|
+
});
|
|
17035
|
+
var xclip = defineCommand({
|
|
17036
|
+
name: "xclip",
|
|
17037
|
+
summary: "access an X selection",
|
|
17038
|
+
usage: "xclip [-selection clipboard|primary|secondary] [-i|-o]",
|
|
17039
|
+
async run(ctx) {
|
|
17040
|
+
let selection = "primary";
|
|
17041
|
+
let mode = "input";
|
|
17042
|
+
const args = ctx.args;
|
|
17043
|
+
for (let index = 0; index < args.length; index++) {
|
|
17044
|
+
const arg = args[index];
|
|
17045
|
+
if (arg === "-selection" || arg === "-sel" || arg === "--selection") {
|
|
17046
|
+
const value = args[++index];
|
|
17047
|
+
if (value === "clipboard" || value === "primary" || value === "secondary") selection = value;
|
|
17048
|
+
continue;
|
|
17049
|
+
}
|
|
17050
|
+
if (arg === "-i" || arg === "-in") mode = "input";
|
|
17051
|
+
else if (arg === "-o" || arg === "-out") mode = "output";
|
|
17052
|
+
}
|
|
17053
|
+
if (mode === "input") {
|
|
17054
|
+
writeSelection(ctx, selection, await ctx.stdin.readAll());
|
|
17055
|
+
return 0;
|
|
17056
|
+
}
|
|
17057
|
+
ctx.write(readSelection(ctx, selection));
|
|
17058
|
+
return 0;
|
|
17059
|
+
}
|
|
17060
|
+
});
|
|
17061
|
+
var pbcopy = defineCommand({
|
|
17062
|
+
name: "pbcopy",
|
|
17063
|
+
summary: "copy standard input to the clipboard",
|
|
17064
|
+
usage: "pbcopy",
|
|
17065
|
+
async run(ctx) {
|
|
17066
|
+
writeSelection(ctx, "clipboard", await ctx.stdin.readAll());
|
|
17067
|
+
return 0;
|
|
17068
|
+
}
|
|
17069
|
+
});
|
|
17070
|
+
var pbpaste = defineCommand({
|
|
17071
|
+
name: "pbpaste",
|
|
17072
|
+
summary: "write the clipboard to standard output",
|
|
17073
|
+
usage: "pbpaste",
|
|
17074
|
+
run(ctx) {
|
|
17075
|
+
ctx.write(readSelection(ctx, "clipboard"));
|
|
17076
|
+
return 0;
|
|
17077
|
+
}
|
|
17078
|
+
});
|
|
17079
|
+
var wlCopy = defineCommand({
|
|
17080
|
+
name: "wl-copy",
|
|
17081
|
+
summary: "copy standard input to the Wayland clipboard",
|
|
17082
|
+
usage: "wl-copy [--primary] [text...]",
|
|
17083
|
+
async run(ctx) {
|
|
17084
|
+
const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
|
|
17085
|
+
const operands = ctx.args.filter((arg) => !arg.startsWith("-"));
|
|
17086
|
+
const bytes2 = operands.length ? new TextEncoder().encode(operands.join(" ")) : await ctx.stdin.readAll();
|
|
17087
|
+
writeSelection(ctx, selection, bytes2);
|
|
17088
|
+
return 0;
|
|
17089
|
+
}
|
|
17090
|
+
});
|
|
17091
|
+
var wlPaste = defineCommand({
|
|
17092
|
+
name: "wl-paste",
|
|
17093
|
+
summary: "write the Wayland clipboard to standard output",
|
|
17094
|
+
usage: "wl-paste [--primary] [-n]",
|
|
17095
|
+
run(ctx) {
|
|
17096
|
+
const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
|
|
17097
|
+
const bytes2 = readSelection(ctx, selection);
|
|
17098
|
+
ctx.write(bytes2);
|
|
17099
|
+
if (!ctx.args.includes("-n") && !ctx.args.includes("--no-newline")) ctx.write("\n");
|
|
17100
|
+
return 0;
|
|
17101
|
+
}
|
|
17102
|
+
});
|
|
17103
|
+
var commands11 = [xsel, xclip, pbcopy, pbpaste, wlCopy, wlPaste];
|
|
17104
|
+
|
|
16966
17105
|
// src/runtime/node.ts
|
|
16967
17106
|
init_path();
|
|
16968
17107
|
var NODE_VERSION = "v22.12.0";
|
|
@@ -17803,22 +17942,22 @@ async function runCPythonProgram(ctx, source, argv, scriptDir, stdinText) {
|
|
|
17803
17942
|
});
|
|
17804
17943
|
} catch {
|
|
17805
17944
|
}
|
|
17806
|
-
const
|
|
17807
|
-
const
|
|
17945
|
+
const encoder8 = new TextEncoder();
|
|
17946
|
+
const decoder8 = new TextDecoder();
|
|
17808
17947
|
py.setStdout({
|
|
17809
17948
|
write: (buffer) => {
|
|
17810
|
-
ctx.write(
|
|
17949
|
+
ctx.write(decoder8.decode(buffer));
|
|
17811
17950
|
return buffer.length;
|
|
17812
17951
|
}
|
|
17813
17952
|
});
|
|
17814
17953
|
py.setStderr({
|
|
17815
17954
|
write: (buffer) => {
|
|
17816
|
-
ctx.stderr.write(
|
|
17955
|
+
ctx.stderr.write(decoder8.decode(buffer));
|
|
17817
17956
|
return buffer.length;
|
|
17818
17957
|
}
|
|
17819
17958
|
});
|
|
17820
17959
|
if (stdinText !== null) {
|
|
17821
|
-
const bytes2 =
|
|
17960
|
+
const bytes2 = encoder8.encode(stdinText);
|
|
17822
17961
|
let offset = 0;
|
|
17823
17962
|
py.setStdin({
|
|
17824
17963
|
read: (buffer) => {
|
|
@@ -17869,9 +18008,9 @@ async function runCPythonRepl(ctx) {
|
|
|
17869
18008
|
}
|
|
17870
18009
|
mountContainerDirs(py, ctx);
|
|
17871
18010
|
bootstrap(py, ctx, [""], null);
|
|
17872
|
-
const
|
|
17873
|
-
py.setStdout({ write: (data) => (ctx.write(
|
|
17874
|
-
py.setStderr({ write: (data) => (ctx.stderr.write(
|
|
18011
|
+
const decoder8 = new TextDecoder();
|
|
18012
|
+
py.setStdout({ write: (data) => (ctx.write(decoder8.decode(data)), data.length) });
|
|
18013
|
+
py.setStderr({ write: (data) => (ctx.stderr.write(decoder8.decode(data)), data.length) });
|
|
17875
18014
|
ctx.line(`Python ${String(py.runPython("import sys; sys.version.split()[0]"))} (Pyodide)`);
|
|
17876
18015
|
ctx.line('Type "help()" for more information.');
|
|
17877
18016
|
let source = "";
|
|
@@ -19319,6 +19458,7 @@ function allCommands() {
|
|
|
19319
19458
|
...commands8,
|
|
19320
19459
|
...commands9,
|
|
19321
19460
|
...commands10,
|
|
19461
|
+
...commands11,
|
|
19322
19462
|
...nodeCommands(),
|
|
19323
19463
|
...pythonCommands(),
|
|
19324
19464
|
...ffmpegCommands(),
|
|
@@ -19481,15 +19621,15 @@ var Session = class {
|
|
|
19481
19621
|
async run(command, opts = {}) {
|
|
19482
19622
|
if (this.closed) throw new Error("session is closed");
|
|
19483
19623
|
const combined = [];
|
|
19484
|
-
const
|
|
19624
|
+
const decoder8 = new TextDecoder();
|
|
19485
19625
|
const stdout = new BufferSink((chunk) => {
|
|
19486
|
-
const text2 =
|
|
19626
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
19487
19627
|
combined.push(text2);
|
|
19488
19628
|
opts.onStdout?.(text2);
|
|
19489
19629
|
this.hooks.onStdout?.(text2);
|
|
19490
19630
|
});
|
|
19491
19631
|
const stderr = new BufferSink((chunk) => {
|
|
19492
|
-
const text2 =
|
|
19632
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
19493
19633
|
combined.push(text2);
|
|
19494
19634
|
opts.onStderr?.(text2);
|
|
19495
19635
|
this.hooks.onStderr?.(text2);
|
|
@@ -19615,6 +19755,13 @@ var KernelChildProcess = class {
|
|
|
19615
19755
|
} catch {
|
|
19616
19756
|
}
|
|
19617
19757
|
}
|
|
19758
|
+
/** Signal EOF, so a child reading stdin to the end can finish. */
|
|
19759
|
+
endStdin() {
|
|
19760
|
+
try {
|
|
19761
|
+
this.stdin.end();
|
|
19762
|
+
} catch {
|
|
19763
|
+
}
|
|
19764
|
+
}
|
|
19618
19765
|
kill(signal = "SIGTERM") {
|
|
19619
19766
|
if (this.process) {
|
|
19620
19767
|
this.process.deliver(signal);
|
|
@@ -20526,6 +20673,55 @@ function splitSpecifier(specifier) {
|
|
|
20526
20673
|
return { name: parts.slice(0, size).join("/"), subpath: parts.slice(size).join("/") };
|
|
20527
20674
|
}
|
|
20528
20675
|
|
|
20676
|
+
// src/runtime/readable-from.ts
|
|
20677
|
+
function createReadableFrom(Readable) {
|
|
20678
|
+
return function from(source, options = {}) {
|
|
20679
|
+
if (source && typeof source.pipe === "function") return source;
|
|
20680
|
+
const iterator = source && typeof source[Symbol.asyncIterator] === "function" ? source[Symbol.asyncIterator]() : source && typeof source[Symbol.iterator] === "function" ? source[Symbol.iterator]() : (function* () {
|
|
20681
|
+
yield source;
|
|
20682
|
+
})();
|
|
20683
|
+
let reading = false;
|
|
20684
|
+
const stream = new Readable({
|
|
20685
|
+
...options,
|
|
20686
|
+
objectMode: options.objectMode ?? false,
|
|
20687
|
+
read() {
|
|
20688
|
+
if (reading) return;
|
|
20689
|
+
reading = true;
|
|
20690
|
+
void (async () => {
|
|
20691
|
+
try {
|
|
20692
|
+
for (; ; ) {
|
|
20693
|
+
const next = await iterator.next();
|
|
20694
|
+
if (next.done) {
|
|
20695
|
+
stream.push(null);
|
|
20696
|
+
return;
|
|
20697
|
+
}
|
|
20698
|
+
const value = next.value;
|
|
20699
|
+
if (!stream.push(value === void 0 ? null : value)) return;
|
|
20700
|
+
}
|
|
20701
|
+
} catch (error) {
|
|
20702
|
+
stream.destroy(error);
|
|
20703
|
+
} finally {
|
|
20704
|
+
reading = false;
|
|
20705
|
+
}
|
|
20706
|
+
})();
|
|
20707
|
+
},
|
|
20708
|
+
destroy(error, callback) {
|
|
20709
|
+
void (async () => {
|
|
20710
|
+
try {
|
|
20711
|
+
await iterator.return?.();
|
|
20712
|
+
} catch {
|
|
20713
|
+
}
|
|
20714
|
+
callback(error);
|
|
20715
|
+
})();
|
|
20716
|
+
}
|
|
20717
|
+
});
|
|
20718
|
+
return stream;
|
|
20719
|
+
};
|
|
20720
|
+
}
|
|
20721
|
+
function installReadableFrom(streamModule5) {
|
|
20722
|
+
streamModule5.Readable.from = createReadableFrom(streamModule5.Readable);
|
|
20723
|
+
}
|
|
20724
|
+
|
|
20529
20725
|
// src/runtime/util-module.ts
|
|
20530
20726
|
var customInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
20531
20727
|
var promisifyCustom = /* @__PURE__ */ Symbol.for("nodejs.util.promisify.custom");
|
|
@@ -21413,6 +21609,10 @@ var VirtualHttpRouter = class {
|
|
|
21413
21609
|
unregister(port, server) {
|
|
21414
21610
|
if (this.servers.get(port)?.server === server) this.servers.delete(port);
|
|
21415
21611
|
}
|
|
21612
|
+
/** Whether anything in this container is listening on `port`. */
|
|
21613
|
+
activePortsIncludes(port) {
|
|
21614
|
+
return this.servers.has(port);
|
|
21615
|
+
}
|
|
21416
21616
|
activePorts(owner) {
|
|
21417
21617
|
return [...this.servers].filter(([, item]) => owner === void 0 || item.owner === owner).map(([port]) => port).sort((a, b) => a - b);
|
|
21418
21618
|
}
|
|
@@ -21436,13 +21636,275 @@ var VirtualHttpRouter = class {
|
|
|
21436
21636
|
}
|
|
21437
21637
|
}
|
|
21438
21638
|
};
|
|
21439
|
-
|
|
21639
|
+
var VirtualClientResponse = class extends streamModule4.Readable {
|
|
21640
|
+
constructor(statusCode, statusMessage, headers, body) {
|
|
21641
|
+
super();
|
|
21642
|
+
this.statusCode = statusCode;
|
|
21643
|
+
this.statusMessage = statusMessage;
|
|
21644
|
+
this.headers = headers;
|
|
21645
|
+
this.rawHeaders = Object.entries(headers).flatMap(([key, value]) => [key, value]);
|
|
21646
|
+
if (body.length) this.push(Buffer2.from(body));
|
|
21647
|
+
this.push(null);
|
|
21648
|
+
this.complete = true;
|
|
21649
|
+
}
|
|
21650
|
+
statusCode;
|
|
21651
|
+
statusMessage;
|
|
21652
|
+
headers;
|
|
21653
|
+
httpVersion = "1.1";
|
|
21654
|
+
httpVersionMajor = 1;
|
|
21655
|
+
httpVersionMinor = 1;
|
|
21656
|
+
socket = socketStub();
|
|
21657
|
+
connection = this.socket;
|
|
21658
|
+
rawHeaders;
|
|
21659
|
+
complete = false;
|
|
21660
|
+
_read() {
|
|
21661
|
+
}
|
|
21662
|
+
setTimeout(_milliseconds, callback) {
|
|
21663
|
+
if (callback) this.once("timeout", callback);
|
|
21664
|
+
return this;
|
|
21665
|
+
}
|
|
21666
|
+
};
|
|
21667
|
+
function resolveTarget(input, overrides, defaultProtocol) {
|
|
21668
|
+
const options = {};
|
|
21669
|
+
if (typeof input === "string" || input instanceof URL) {
|
|
21670
|
+
const url = new URL(String(input));
|
|
21671
|
+
options.protocol = url.protocol;
|
|
21672
|
+
options.hostname = url.hostname;
|
|
21673
|
+
if (url.port) options.port = Number(url.port);
|
|
21674
|
+
options.path = `${url.pathname}${url.search}`;
|
|
21675
|
+
if (url.username || url.password) options.auth = `${url.username}:${url.password}`;
|
|
21676
|
+
} else if (input && typeof input === "object") {
|
|
21677
|
+
Object.assign(options, input);
|
|
21678
|
+
}
|
|
21679
|
+
if (overrides) Object.assign(options, overrides);
|
|
21680
|
+
const protocol = String(options.protocol ?? defaultProtocol).replace(/:?$/, ":");
|
|
21681
|
+
const headers = {};
|
|
21682
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
21683
|
+
if (value === void 0 || value === null) continue;
|
|
21684
|
+
headers[String(name)] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
21685
|
+
}
|
|
21686
|
+
if (options.auth && headers.authorization === void 0) {
|
|
21687
|
+
headers.authorization = `Basic ${Buffer2.from(String(options.auth)).toString("base64")}`;
|
|
21688
|
+
}
|
|
21689
|
+
const rawHost = String(options.hostname ?? options.host ?? "localhost");
|
|
21690
|
+
const hostMatch = /^(\[[^\]]*\]|[^:]*)(?::(\d+))?$/.exec(rawHost);
|
|
21691
|
+
const hostname = (hostMatch?.[1] ?? rawHost).replace(/^\[|\]$/g, "");
|
|
21692
|
+
const explicitPort = options.port ?? hostMatch?.[2];
|
|
21693
|
+
const port = explicitPort === void 0 || explicitPort === null || explicitPort === "" || Number.isNaN(Number(explicitPort)) ? protocol === "https:" ? 443 : 80 : Number(explicitPort);
|
|
21694
|
+
return {
|
|
21695
|
+
protocol,
|
|
21696
|
+
hostname,
|
|
21697
|
+
port,
|
|
21698
|
+
path: String(options.path ?? "/"),
|
|
21699
|
+
method: String(options.method ?? "GET").toUpperCase(),
|
|
21700
|
+
headers
|
|
21701
|
+
};
|
|
21702
|
+
}
|
|
21703
|
+
function isLoopback(hostname) {
|
|
21704
|
+
return hostname === "localhost" || hostname === "0.0.0.0" || hostname === "::1" || hostname === "::" || hostname.startsWith("127.") || hostname.endsWith(".localhost");
|
|
21705
|
+
}
|
|
21706
|
+
var VirtualClientRequest = class extends streamModule4.Writable {
|
|
21707
|
+
constructor(target, router, fetchImpl, trackRequest) {
|
|
21708
|
+
super();
|
|
21709
|
+
this.target = target;
|
|
21710
|
+
this.router = router;
|
|
21711
|
+
this.fetchImpl = fetchImpl;
|
|
21712
|
+
this.trackRequest = trackRequest;
|
|
21713
|
+
for (const [name, value] of Object.entries(target.headers)) this.setHeader(name, value);
|
|
21714
|
+
}
|
|
21715
|
+
target;
|
|
21716
|
+
router;
|
|
21717
|
+
fetchImpl;
|
|
21718
|
+
trackRequest;
|
|
21719
|
+
socket = socketStub();
|
|
21720
|
+
connection = this.socket;
|
|
21721
|
+
chunks = [];
|
|
21722
|
+
headerMap = /* @__PURE__ */ new Map();
|
|
21723
|
+
dispatched = false;
|
|
21724
|
+
destroyedByUser = false;
|
|
21725
|
+
timer;
|
|
21726
|
+
aborted = false;
|
|
21727
|
+
finished = false;
|
|
21728
|
+
reusedSocket = false;
|
|
21729
|
+
get method() {
|
|
21730
|
+
return this.target.method;
|
|
21731
|
+
}
|
|
21732
|
+
get path() {
|
|
21733
|
+
return this.target.path;
|
|
21734
|
+
}
|
|
21735
|
+
get host() {
|
|
21736
|
+
return this.target.hostname;
|
|
21737
|
+
}
|
|
21738
|
+
get protocol() {
|
|
21739
|
+
return this.target.protocol;
|
|
21740
|
+
}
|
|
21741
|
+
setHeader(name, value) {
|
|
21742
|
+
validateHeaderName(name);
|
|
21743
|
+
validateHeaderValue(name, value);
|
|
21744
|
+
this.headerMap.set(name.toLowerCase(), { name, value: Array.isArray(value) ? [...value].map(String).join(", ") : String(value) });
|
|
21745
|
+
return this;
|
|
21746
|
+
}
|
|
21747
|
+
getHeader(name) {
|
|
21748
|
+
return this.headerMap.get(name.toLowerCase())?.value;
|
|
21749
|
+
}
|
|
21750
|
+
getHeaders() {
|
|
21751
|
+
return Object.fromEntries([...this.headerMap].map(([key, entry]) => [key, entry.value]));
|
|
21752
|
+
}
|
|
21753
|
+
getHeaderNames() {
|
|
21754
|
+
return [...this.headerMap.keys()];
|
|
21755
|
+
}
|
|
21756
|
+
hasHeader(name) {
|
|
21757
|
+
return this.headerMap.has(name.toLowerCase());
|
|
21758
|
+
}
|
|
21759
|
+
removeHeader(name) {
|
|
21760
|
+
this.headerMap.delete(name.toLowerCase());
|
|
21761
|
+
}
|
|
21762
|
+
flushHeaders() {
|
|
21763
|
+
}
|
|
21764
|
+
setNoDelay() {
|
|
21765
|
+
}
|
|
21766
|
+
setSocketKeepAlive() {
|
|
21767
|
+
}
|
|
21768
|
+
ref() {
|
|
21769
|
+
return this;
|
|
21770
|
+
}
|
|
21771
|
+
unref() {
|
|
21772
|
+
return this;
|
|
21773
|
+
}
|
|
21774
|
+
setTimeout(milliseconds, callback) {
|
|
21775
|
+
if (callback) this.once("timeout", callback);
|
|
21776
|
+
clearTimeout(this.timer);
|
|
21777
|
+
this.timer = setTimeout(() => this.emit("timeout"), milliseconds);
|
|
21778
|
+
return this;
|
|
21779
|
+
}
|
|
21780
|
+
abort() {
|
|
21781
|
+
this.destroyRequest();
|
|
21782
|
+
}
|
|
21783
|
+
destroy(error) {
|
|
21784
|
+
this.destroyRequest(error);
|
|
21785
|
+
return this;
|
|
21786
|
+
}
|
|
21787
|
+
destroyRequest(error) {
|
|
21788
|
+
if (this.destroyedByUser) return;
|
|
21789
|
+
this.destroyedByUser = true;
|
|
21790
|
+
this.aborted = true;
|
|
21791
|
+
clearTimeout(this.timer);
|
|
21792
|
+
this.emit("abort");
|
|
21793
|
+
if (error) this.emit("error", error);
|
|
21794
|
+
this.emit("close");
|
|
21795
|
+
}
|
|
21796
|
+
_write(chunk, encoding, callback) {
|
|
21797
|
+
this.chunks.push(Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk, encoding));
|
|
21798
|
+
callback();
|
|
21799
|
+
}
|
|
21800
|
+
_final(callback) {
|
|
21801
|
+
this.finished = true;
|
|
21802
|
+
callback();
|
|
21803
|
+
void this.dispatch();
|
|
21804
|
+
}
|
|
21805
|
+
async dispatch() {
|
|
21806
|
+
if (this.dispatched || this.destroyedByUser) return;
|
|
21807
|
+
this.dispatched = true;
|
|
21808
|
+
const body = Buffer2.concat(this.chunks);
|
|
21809
|
+
const release = this.trackRequest?.();
|
|
21810
|
+
let released = false;
|
|
21811
|
+
const untrack = () => {
|
|
21812
|
+
if (released || !release) return;
|
|
21813
|
+
released = true;
|
|
21814
|
+
release();
|
|
21815
|
+
};
|
|
21816
|
+
let settled = false;
|
|
21817
|
+
try {
|
|
21818
|
+
const response = isLoopback(this.target.hostname) ? await this.viaRouter(body) : await this.viaFetch(body);
|
|
21819
|
+
if (this.destroyedByUser) return;
|
|
21820
|
+
clearTimeout(this.timer);
|
|
21821
|
+
settled = true;
|
|
21822
|
+
response.once("end", untrack);
|
|
21823
|
+
response.once("close", untrack);
|
|
21824
|
+
response.once("error", untrack);
|
|
21825
|
+
this.emit("response", response);
|
|
21826
|
+
queueMicrotask(() => {
|
|
21827
|
+
if (this.listenerCount("response") === 0) response.resume();
|
|
21828
|
+
});
|
|
21829
|
+
} catch (error) {
|
|
21830
|
+
clearTimeout(this.timer);
|
|
21831
|
+
if (this.destroyedByUser) return;
|
|
21832
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
21833
|
+
if (!("code" in failure)) Object.assign(failure, { code: "ECONNREFUSED" });
|
|
21834
|
+
this.emit("error", failure);
|
|
21835
|
+
} finally {
|
|
21836
|
+
if (!settled) untrack();
|
|
21837
|
+
}
|
|
21838
|
+
}
|
|
21839
|
+
async viaRouter(body) {
|
|
21840
|
+
if (!this.router.activePortsIncludes(this.target.port)) {
|
|
21841
|
+
throw Object.assign(
|
|
21842
|
+
new Error(`connect ECONNREFUSED ${this.target.hostname}:${this.target.port}`),
|
|
21843
|
+
{ code: "ECONNREFUSED", errno: -61, syscall: "connect", address: this.target.hostname, port: this.target.port }
|
|
21844
|
+
);
|
|
21845
|
+
}
|
|
21846
|
+
const result = await this.router.request(this.target.port, {
|
|
21847
|
+
method: this.target.method,
|
|
21848
|
+
path: this.target.path,
|
|
21849
|
+
headers: this.getHeaders(),
|
|
21850
|
+
body: body.length ? new Uint8Array(body) : null
|
|
21851
|
+
});
|
|
21852
|
+
const body_ = result.body;
|
|
21853
|
+
const bytes2 = typeof body_ === "string" ? new TextEncoder().encode(body_) : body_ instanceof ArrayBuffer ? new Uint8Array(body_) : body_ ?? new Uint8Array();
|
|
21854
|
+
const status = result.statusCode ?? 200;
|
|
21855
|
+
return new VirtualClientResponse(status, result.statusMessage ?? STATUS_CODES[status] ?? "", lowercaseHeaders(result.headers), bytes2);
|
|
21856
|
+
}
|
|
21857
|
+
async viaFetch(body) {
|
|
21858
|
+
const fetchImpl = this.fetchImpl ?? globalThis.fetch;
|
|
21859
|
+
if (typeof fetchImpl !== "function") {
|
|
21860
|
+
throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${this.target.hostname}`), { code: "ENOTFOUND" });
|
|
21861
|
+
}
|
|
21862
|
+
const portSuffix = this.target.protocol === "https:" && this.target.port === 443 || this.target.protocol === "http:" && this.target.port === 80 ? "" : `:${this.target.port}`;
|
|
21863
|
+
const url = `${this.target.protocol}//${this.target.hostname}${portSuffix}${this.target.path}`;
|
|
21864
|
+
const bodyless = this.target.method === "GET" || this.target.method === "HEAD";
|
|
21865
|
+
const headers = this.getHeaders();
|
|
21866
|
+
delete headers.host;
|
|
21867
|
+
delete headers.connection;
|
|
21868
|
+
delete headers["content-length"];
|
|
21869
|
+
const response = await fetchImpl(url, {
|
|
21870
|
+
method: this.target.method,
|
|
21871
|
+
headers,
|
|
21872
|
+
...bodyless || body.length === 0 ? {} : { body: new Uint8Array(body) },
|
|
21873
|
+
redirect: "follow"
|
|
21874
|
+
});
|
|
21875
|
+
const received = {};
|
|
21876
|
+
response.headers.forEach((value, key) => {
|
|
21877
|
+
received[key.toLowerCase()] = value;
|
|
21878
|
+
});
|
|
21879
|
+
const bytes2 = new Uint8Array(await response.arrayBuffer());
|
|
21880
|
+
return new VirtualClientResponse(response.status, response.statusText, received, bytes2);
|
|
21881
|
+
}
|
|
21882
|
+
};
|
|
21883
|
+
function lowercaseHeaders(headers) {
|
|
21884
|
+
return Object.fromEntries(Object.entries(headers ?? {}).map(([key, value]) => [key.toLowerCase(), String(value)]));
|
|
21885
|
+
}
|
|
21886
|
+
function createHttpModule(router, owner, options = {}, defaultProtocol = "http:") {
|
|
21440
21887
|
const createServer = (listener) => new VirtualHttpServer(router, owner, listener);
|
|
21441
|
-
const
|
|
21888
|
+
const request = (input, second, third) => {
|
|
21889
|
+
const overrides = second && typeof second === "object" && !(second instanceof Function) ? second : void 0;
|
|
21890
|
+
const callback = [second, third].find((value) => typeof value === "function");
|
|
21891
|
+
const req = new VirtualClientRequest(resolveTarget(input, overrides, defaultProtocol), router, options.fetch, options.trackRequest);
|
|
21892
|
+
if (callback) req.on("response", callback);
|
|
21893
|
+
return req;
|
|
21894
|
+
};
|
|
21895
|
+
const get = (input, second, third) => {
|
|
21896
|
+
const req = request(input, second, third);
|
|
21897
|
+
req.end();
|
|
21898
|
+
return req;
|
|
21899
|
+
};
|
|
21900
|
+
return {
|
|
21442
21901
|
createServer,
|
|
21902
|
+
request,
|
|
21903
|
+
get,
|
|
21443
21904
|
Server: VirtualHttpServer,
|
|
21444
21905
|
ServerResponse: VirtualServerResponse,
|
|
21445
21906
|
IncomingMessage: VirtualIncomingMessage,
|
|
21907
|
+
ClientRequest: VirtualClientRequest,
|
|
21446
21908
|
METHODS,
|
|
21447
21909
|
STATUS_CODES,
|
|
21448
21910
|
maxHeaderSize: 16 * 1024,
|
|
@@ -21452,10 +21914,6 @@ function createHttpModule(router, owner) {
|
|
|
21452
21914
|
Agent: class Agent {
|
|
21453
21915
|
}
|
|
21454
21916
|
};
|
|
21455
|
-
return { ...module, request: unsupportedClient, get: unsupportedClient };
|
|
21456
|
-
}
|
|
21457
|
-
function unsupportedClient() {
|
|
21458
|
-
throw Object.assign(new Error("http client requests are not implemented yet"), { code: "ERR_NOT_IMPLEMENTED" });
|
|
21459
21917
|
}
|
|
21460
21918
|
function validateHeaderName(name) {
|
|
21461
21919
|
if (!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(name)) throw Object.assign(new TypeError(`Header name must be a valid HTTP token [${name}]`), { code: "ERR_INVALID_HTTP_TOKEN" });
|
|
@@ -21595,6 +22053,13 @@ var ChildProcess = class extends EventEmitter4 {
|
|
|
21595
22053
|
} catch {
|
|
21596
22054
|
}
|
|
21597
22055
|
done();
|
|
22056
|
+
},
|
|
22057
|
+
final: (done) => {
|
|
22058
|
+
try {
|
|
22059
|
+
handle.endStdin?.();
|
|
22060
|
+
} catch {
|
|
22061
|
+
}
|
|
22062
|
+
done();
|
|
21598
22063
|
}
|
|
21599
22064
|
});
|
|
21600
22065
|
this.stdio = [this.stdin, this.stdout, this.stderr];
|
|
@@ -21634,7 +22099,7 @@ var ChildProcess = class extends EventEmitter4 {
|
|
|
21634
22099
|
queueMicrotask(() => this.emit("close", code, null));
|
|
21635
22100
|
}
|
|
21636
22101
|
};
|
|
21637
|
-
function createChildProcessModule(spawnChild, defaultCwd) {
|
|
22102
|
+
function createChildProcessModule(spawnChild, defaultCwd, syncSpawn) {
|
|
21638
22103
|
const throughShell = (command, options) => {
|
|
21639
22104
|
const shell = typeof options.shell === "string" ? options.shell : "/bin/sh";
|
|
21640
22105
|
return { file: shell, args: ["-c", command] };
|
|
@@ -21691,20 +22156,79 @@ ${err.join("")}`),
|
|
|
21691
22156
|
exec,
|
|
21692
22157
|
execFile,
|
|
21693
22158
|
fork: (modulePath, args = [], options = {}) => spawn("node", [modulePath, ...args], options),
|
|
21694
|
-
|
|
21695
|
-
execFileSync: unavailable("execFileSync"),
|
|
21696
|
-
spawnSync: unavailable("spawnSync"),
|
|
22159
|
+
...buildSyncFamily(syncSpawn, throughShell, defaultCwd),
|
|
21697
22160
|
ChildProcess
|
|
21698
22161
|
};
|
|
21699
22162
|
}
|
|
22163
|
+
function buildSyncFamily(syncSpawn, throughShell, defaultCwd) {
|
|
22164
|
+
if (!syncSpawn) {
|
|
22165
|
+
return {
|
|
22166
|
+
execSync: unavailable("execSync"),
|
|
22167
|
+
execFileSync: unavailable("execFileSync"),
|
|
22168
|
+
spawnSync: unavailable("spawnSync")
|
|
22169
|
+
};
|
|
22170
|
+
}
|
|
22171
|
+
const run = (file3, args, options) => {
|
|
22172
|
+
const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
|
|
22173
|
+
const input = options.input === void 0 ? void 0 : typeof options.input === "string" ? options.input : new TextDecoder().decode(options.input);
|
|
22174
|
+
return syncSpawn({
|
|
22175
|
+
command: resolved.file,
|
|
22176
|
+
args: resolved.args,
|
|
22177
|
+
cwd: options.cwd ?? defaultCwd(),
|
|
22178
|
+
...options.env ? { env: options.env } : {},
|
|
22179
|
+
...input === void 0 ? {} : { input }
|
|
22180
|
+
});
|
|
22181
|
+
};
|
|
22182
|
+
const asOutput = (text2, options) => options.encoding === "buffer" || options.encoding === void 0 ? Buffer2.from(text2) : text2;
|
|
22183
|
+
const orThrow = (result, command, options) => {
|
|
22184
|
+
if (result.error) {
|
|
22185
|
+
throw Object.assign(new Error(result.error.message), {
|
|
22186
|
+
...result.error.code ? { code: result.error.code } : {},
|
|
22187
|
+
stdout: asOutput(result.stdout, options),
|
|
22188
|
+
stderr: asOutput(result.stderr, options)
|
|
22189
|
+
});
|
|
22190
|
+
}
|
|
22191
|
+
if (result.status !== 0) {
|
|
22192
|
+
throw Object.assign(new Error(`Command failed: ${command}
|
|
22193
|
+
${result.stderr}`), {
|
|
22194
|
+
status: result.status,
|
|
22195
|
+
stdout: asOutput(result.stdout, options),
|
|
22196
|
+
stderr: asOutput(result.stderr, options)
|
|
22197
|
+
});
|
|
22198
|
+
}
|
|
22199
|
+
return asOutput(result.stdout, options);
|
|
22200
|
+
};
|
|
22201
|
+
const spawnSync = (file3, args = [], options = {}) => {
|
|
22202
|
+
const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
|
|
22203
|
+
const result = run(file3, list, opts);
|
|
22204
|
+
return {
|
|
22205
|
+
pid: 0,
|
|
22206
|
+
status: result.status,
|
|
22207
|
+
signal: result.signal,
|
|
22208
|
+
stdout: asOutput(result.stdout, opts),
|
|
22209
|
+
stderr: asOutput(result.stderr, opts),
|
|
22210
|
+
output: [null, asOutput(result.stdout, opts), asOutput(result.stderr, opts)],
|
|
22211
|
+
...result.error ? { error: Object.assign(new Error(result.error.message), result.error.code ? { code: result.error.code } : {}) } : {}
|
|
22212
|
+
};
|
|
22213
|
+
};
|
|
22214
|
+
const execFileSync = (file3, args = [], options = {}) => {
|
|
22215
|
+
const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
|
|
22216
|
+
return orThrow(run(file3, list, opts), [file3, ...list].join(" "), opts);
|
|
22217
|
+
};
|
|
22218
|
+
const execSync = (command, options = {}) => orThrow(run(command, [], { ...options, shell: options.shell ?? true }), command, options);
|
|
22219
|
+
return { spawnSync, execFileSync, execSync };
|
|
22220
|
+
}
|
|
21700
22221
|
function normalize2(options, callback) {
|
|
21701
22222
|
if (typeof options === "function") return [{}, options];
|
|
21702
22223
|
return [options ?? {}, callback];
|
|
21703
22224
|
}
|
|
21704
22225
|
function unavailable(name) {
|
|
21705
|
-
return () => {
|
|
22226
|
+
return (...args) => {
|
|
22227
|
+
const file3 = typeof args[0] === "string" ? args[0] : void 0;
|
|
22228
|
+
const list = Array.isArray(args[1]) ? args[1].map(String) : [];
|
|
22229
|
+
const command = file3 ? [file3, ...list].join(" ") : void 0;
|
|
21706
22230
|
const error = new Error(
|
|
21707
|
-
`child_process.${name} is not supported in the sandboxed runtime
|
|
22231
|
+
`child_process.${name} is not supported in the sandboxed runtime` + (command ? ` (tried to run: ${command})` : "") + `: the caller, the child and the event loop share one thread, so blocking the caller would also stop the child. Run it with the asynchronous form (spawn/exec/execFile), or run the command from the container shell.`
|
|
21708
22232
|
);
|
|
21709
22233
|
error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
|
|
21710
22234
|
throw error;
|
|
@@ -21768,7 +22292,11 @@ function parseKeys(input) {
|
|
|
21768
22292
|
const name = CSI_KEYS[sequence];
|
|
21769
22293
|
keys.push({
|
|
21770
22294
|
sequence: `\x1B${sequence}`,
|
|
21771
|
-
|
|
22295
|
+
/* Node leaves this undefined for a sequence it does not recognise.
|
|
22296
|
+
* The string "undefined" is not the same thing: a caller testing
|
|
22297
|
+
* `key.name === undefined` would take an unknown key for a known
|
|
22298
|
+
* one. */
|
|
22299
|
+
name,
|
|
21772
22300
|
ctrl: false,
|
|
21773
22301
|
/* xterm reports modifiers as `;5` (control) and `;2` (shift) before
|
|
21774
22302
|
* the final letter. */
|
|
@@ -21833,7 +22361,7 @@ function emitKeypressEvents(stream) {
|
|
|
21833
22361
|
}
|
|
21834
22362
|
});
|
|
21835
22363
|
}
|
|
21836
|
-
function createReadlineModule(defaultInput) {
|
|
22364
|
+
function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
21837
22365
|
class Interface extends EventEmitter4 {
|
|
21838
22366
|
constructor(input, output, terminal = false) {
|
|
21839
22367
|
super();
|
|
@@ -21844,6 +22372,14 @@ function createReadlineModule(defaultInput) {
|
|
|
21844
22372
|
if (terminal) {
|
|
21845
22373
|
emitKeypressEvents(input);
|
|
21846
22374
|
input?.on?.("keypress", this.onTerminalKeypress);
|
|
22375
|
+
if (typeof input?.setRawMode === "function") {
|
|
22376
|
+
try {
|
|
22377
|
+
input.setRawMode(true);
|
|
22378
|
+
this.ownsRawMode = true;
|
|
22379
|
+
} catch {
|
|
22380
|
+
}
|
|
22381
|
+
}
|
|
22382
|
+
input?.resume?.();
|
|
21847
22383
|
} else {
|
|
21848
22384
|
input?.on?.("data", (chunk) => this.receive(String(chunk)));
|
|
21849
22385
|
}
|
|
@@ -21855,6 +22391,10 @@ function createReadlineModule(defaultInput) {
|
|
|
21855
22391
|
buffer = "";
|
|
21856
22392
|
pending = [];
|
|
21857
22393
|
lines = [];
|
|
22394
|
+
/** Set while `question` is waiting, so the echoed line carries the query. */
|
|
22395
|
+
questionPrompt = null;
|
|
22396
|
+
/** Raw mode is only ours to restore if we were the one to enable it. */
|
|
22397
|
+
ownsRawMode = false;
|
|
21858
22398
|
line = "";
|
|
21859
22399
|
cursor = 0;
|
|
21860
22400
|
terminal;
|
|
@@ -21862,20 +22402,31 @@ function createReadlineModule(defaultInput) {
|
|
|
21862
22402
|
/** Split incoming data into lines, answering any waiting `question`. */
|
|
21863
22403
|
receive(text2) {
|
|
21864
22404
|
this.buffer += text2;
|
|
21865
|
-
let
|
|
21866
|
-
while (
|
|
21867
|
-
const line = this.buffer.slice(0,
|
|
21868
|
-
this.buffer = this.buffer.slice(
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
|
|
21873
|
-
|
|
21874
|
-
|
|
21875
|
-
|
|
22405
|
+
let match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22406
|
+
while (match2) {
|
|
22407
|
+
const line = this.buffer.slice(0, match2.index);
|
|
22408
|
+
this.buffer = this.buffer.slice(match2.index + match2[0].length);
|
|
22409
|
+
this.deliver(line);
|
|
22410
|
+
match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22411
|
+
}
|
|
22412
|
+
}
|
|
22413
|
+
/** Hand a completed line to whoever is waiting for it. */
|
|
22414
|
+
deliver(line) {
|
|
22415
|
+
const waiting = this.pending.shift();
|
|
22416
|
+
if (waiting) {
|
|
22417
|
+
this.questionPrompt = null;
|
|
22418
|
+
waiting(line);
|
|
22419
|
+
return;
|
|
21876
22420
|
}
|
|
22421
|
+
this.lines.push(line);
|
|
22422
|
+
this.emit("line", line);
|
|
21877
22423
|
}
|
|
21878
22424
|
question(query, callback) {
|
|
22425
|
+
if (this.terminal) {
|
|
22426
|
+
this.questionPrompt = query;
|
|
22427
|
+
this.line = "";
|
|
22428
|
+
this.cursor = 0;
|
|
22429
|
+
}
|
|
21879
22430
|
this.output?.write?.(query);
|
|
21880
22431
|
if (callback) {
|
|
21881
22432
|
this.pending.push(callback);
|
|
@@ -21890,6 +22441,9 @@ function createReadlineModule(defaultInput) {
|
|
|
21890
22441
|
setPrompt(text2) {
|
|
21891
22442
|
this.promptText = text2;
|
|
21892
22443
|
}
|
|
22444
|
+
getPrompt() {
|
|
22445
|
+
return this.promptText;
|
|
22446
|
+
}
|
|
21893
22447
|
pause() {
|
|
21894
22448
|
this.input?.pause?.();
|
|
21895
22449
|
return this;
|
|
@@ -21917,21 +22471,48 @@ function createReadlineModule(defaultInput) {
|
|
|
21917
22471
|
if (text2) {
|
|
21918
22472
|
this.line = this.line.slice(0, this.cursor) + text2 + this.line.slice(this.cursor);
|
|
21919
22473
|
this.cursor += text2.length;
|
|
22474
|
+
this.refresh();
|
|
21920
22475
|
}
|
|
21921
22476
|
}
|
|
21922
22477
|
getCursorPos() {
|
|
21923
|
-
return { rows: 0, cols: this.cursor + this.
|
|
22478
|
+
return { rows: 0, cols: this.cursor + this.currentPrompt().length };
|
|
21924
22479
|
}
|
|
21925
22480
|
close() {
|
|
21926
22481
|
if (this.closed) return;
|
|
21927
22482
|
this.closed = true;
|
|
21928
22483
|
if (this.terminal) {
|
|
21929
22484
|
this.input?.off?.("keypress", this.onTerminalKeypress);
|
|
22485
|
+
if (this.ownsRawMode) {
|
|
22486
|
+
this.ownsRawMode = false;
|
|
22487
|
+
try {
|
|
22488
|
+
this.input?.setRawMode?.(false);
|
|
22489
|
+
} catch {
|
|
22490
|
+
}
|
|
22491
|
+
}
|
|
21930
22492
|
this.input?.pause?.();
|
|
21931
22493
|
}
|
|
21932
22494
|
for (const waiting of this.pending.splice(0)) waiting("");
|
|
21933
22495
|
this.emit("close");
|
|
21934
22496
|
}
|
|
22497
|
+
/** The text shown to the left of the edited line. */
|
|
22498
|
+
currentPrompt() {
|
|
22499
|
+
return this.questionPrompt ?? this.promptText;
|
|
22500
|
+
}
|
|
22501
|
+
/**
|
|
22502
|
+
* Repaint the edited line.
|
|
22503
|
+
*
|
|
22504
|
+
* In raw mode nothing echoes on its own, so an Interface that does not do
|
|
22505
|
+
* this leaves the user typing blind. Libraries that draw their own frame
|
|
22506
|
+
* (clack, inquirer) simply overwrite this, exactly as they do on Node.
|
|
22507
|
+
*/
|
|
22508
|
+
refresh() {
|
|
22509
|
+
if (!this.terminal) return;
|
|
22510
|
+
const prompt = this.currentPrompt();
|
|
22511
|
+
let text2 = `\r\x1B[0K${prompt}${this.line}`;
|
|
22512
|
+
const back = this.line.length - this.cursor;
|
|
22513
|
+
if (back > 0) text2 += `\x1B[${back}D`;
|
|
22514
|
+
this.output?.write?.(text2);
|
|
22515
|
+
}
|
|
21935
22516
|
edit(sequence, key) {
|
|
21936
22517
|
if (this.closed) return;
|
|
21937
22518
|
const name = key.name;
|
|
@@ -21939,48 +22520,62 @@ function createReadlineModule(defaultInput) {
|
|
|
21939
22520
|
const value = this.line;
|
|
21940
22521
|
this.line = "";
|
|
21941
22522
|
this.cursor = 0;
|
|
21942
|
-
this.
|
|
22523
|
+
this.output?.write?.("\r\n");
|
|
22524
|
+
this.deliver(value);
|
|
21943
22525
|
return;
|
|
21944
22526
|
}
|
|
21945
22527
|
if (name === "left") {
|
|
21946
22528
|
this.cursor = Math.max(0, this.cursor - 1);
|
|
22529
|
+
this.refresh();
|
|
21947
22530
|
return;
|
|
21948
22531
|
}
|
|
21949
22532
|
if (name === "right") {
|
|
21950
22533
|
this.cursor = Math.min(this.line.length, this.cursor + 1);
|
|
22534
|
+
this.refresh();
|
|
21951
22535
|
return;
|
|
21952
22536
|
}
|
|
21953
22537
|
if (name === "home" || key.ctrl && name === "a") {
|
|
21954
22538
|
this.cursor = 0;
|
|
22539
|
+
this.refresh();
|
|
21955
22540
|
return;
|
|
21956
22541
|
}
|
|
21957
22542
|
if (name === "end" || key.ctrl && name === "e") {
|
|
21958
22543
|
this.cursor = this.line.length;
|
|
22544
|
+
this.refresh();
|
|
21959
22545
|
return;
|
|
21960
22546
|
}
|
|
21961
22547
|
if (name === "backspace" || key.ctrl && name === "h") {
|
|
21962
22548
|
if (this.cursor > 0) {
|
|
21963
22549
|
this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
|
|
21964
22550
|
this.cursor--;
|
|
22551
|
+
this.refresh();
|
|
21965
22552
|
}
|
|
21966
22553
|
return;
|
|
21967
22554
|
}
|
|
21968
22555
|
if (name === "delete") {
|
|
21969
|
-
if (this.cursor < this.line.length)
|
|
22556
|
+
if (this.cursor < this.line.length) {
|
|
22557
|
+
this.line = this.line.slice(0, this.cursor) + this.line.slice(this.cursor + 1);
|
|
22558
|
+
this.refresh();
|
|
22559
|
+
}
|
|
21970
22560
|
return;
|
|
21971
22561
|
}
|
|
21972
22562
|
if (key.ctrl && name === "u") {
|
|
21973
22563
|
this.line = this.line.slice(this.cursor);
|
|
21974
22564
|
this.cursor = 0;
|
|
22565
|
+
this.refresh();
|
|
21975
22566
|
return;
|
|
21976
22567
|
}
|
|
21977
22568
|
if (key.ctrl && name === "k") {
|
|
21978
22569
|
this.line = this.line.slice(0, this.cursor);
|
|
22570
|
+
this.refresh();
|
|
21979
22571
|
return;
|
|
21980
22572
|
}
|
|
21981
22573
|
if (key.ctrl || key.meta || sequence.length !== 1 || sequence < " ") return;
|
|
22574
|
+
const atEnd = this.cursor === this.line.length;
|
|
21982
22575
|
this.line = this.line.slice(0, this.cursor) + sequence + this.line.slice(this.cursor);
|
|
21983
22576
|
this.cursor += sequence.length;
|
|
22577
|
+
if (atEnd) this.output?.write?.(sequence);
|
|
22578
|
+
else this.refresh();
|
|
21984
22579
|
}
|
|
21985
22580
|
async *[Symbol.asyncIterator]() {
|
|
21986
22581
|
while (!this.closed || this.lines.length) {
|
|
@@ -22010,13 +22605,23 @@ function createReadlineModule(defaultInput) {
|
|
|
22010
22605
|
}
|
|
22011
22606
|
}
|
|
22012
22607
|
}
|
|
22608
|
+
const isTerminal = (options, output) => {
|
|
22609
|
+
if (typeof options?.terminal === "boolean") return options.terminal;
|
|
22610
|
+
return Boolean(output?.isTTY);
|
|
22611
|
+
};
|
|
22013
22612
|
const createInterface = (options, output) => {
|
|
22014
22613
|
if (options && typeof options === "object" && !options.on) {
|
|
22015
|
-
const
|
|
22614
|
+
const resolvedOutput2 = options.output ?? defaultOutput();
|
|
22615
|
+
const instance = new Interface(
|
|
22616
|
+
options.input ?? defaultInput(),
|
|
22617
|
+
resolvedOutput2,
|
|
22618
|
+
isTerminal(options, resolvedOutput2)
|
|
22619
|
+
);
|
|
22016
22620
|
if (typeof options.prompt === "string") instance.setPrompt(options.prompt);
|
|
22017
22621
|
return instance;
|
|
22018
22622
|
}
|
|
22019
|
-
|
|
22623
|
+
const resolvedOutput = output ?? defaultOutput();
|
|
22624
|
+
return new Interface(options ?? defaultInput(), resolvedOutput, isTerminal(void 0, resolvedOutput));
|
|
22020
22625
|
};
|
|
22021
22626
|
const noop = () => {
|
|
22022
22627
|
};
|
|
@@ -22033,6 +22638,7 @@ function createReadlineModule(defaultInput) {
|
|
|
22033
22638
|
}
|
|
22034
22639
|
|
|
22035
22640
|
// src/runtime/core-modules.ts
|
|
22641
|
+
installReadableFrom(streamModule4);
|
|
22036
22642
|
var Dirent = class {
|
|
22037
22643
|
/** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
|
|
22038
22644
|
constructor(name, stat2, parentPath = "") {
|
|
@@ -22238,9 +22844,20 @@ function createCoreModules(options) {
|
|
|
22238
22844
|
throw new Error("createRequire is only available inside a loaded module");
|
|
22239
22845
|
}
|
|
22240
22846
|
};
|
|
22241
|
-
|
|
22242
|
-
const
|
|
22243
|
-
|
|
22847
|
+
let inFlightRequests = 0;
|
|
22848
|
+
const httpOptions = {
|
|
22849
|
+
...options.http?.fetch ? { fetch: options.http.fetch } : {},
|
|
22850
|
+
trackRequest: () => {
|
|
22851
|
+
inFlightRequests++;
|
|
22852
|
+
return () => {
|
|
22853
|
+
inFlightRequests--;
|
|
22854
|
+
};
|
|
22855
|
+
}
|
|
22856
|
+
};
|
|
22857
|
+
const http = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "http:") : createUnsupportedModule("http");
|
|
22858
|
+
const https = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "https:") : createUnsupportedModule("https");
|
|
22859
|
+
const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd, options.syncSpawn) : createUnsupportedModule("child_process");
|
|
22860
|
+
const readline = createReadlineModule(() => processObject.stdin, () => processObject.stdout);
|
|
22244
22861
|
const dns = createDnsModule();
|
|
22245
22862
|
const builtins = {
|
|
22246
22863
|
assert: assert_module_default,
|
|
@@ -22258,7 +22875,7 @@ function createCoreModules(options) {
|
|
|
22258
22875
|
"fs/promises": fs.promises,
|
|
22259
22876
|
module: moduleBuiltin,
|
|
22260
22877
|
http,
|
|
22261
|
-
https
|
|
22878
|
+
https,
|
|
22262
22879
|
os,
|
|
22263
22880
|
path,
|
|
22264
22881
|
"path/posix": path,
|
|
@@ -22298,6 +22915,9 @@ function createCoreModules(options) {
|
|
|
22298
22915
|
process: processObject,
|
|
22299
22916
|
pendingHandles: timers.pending,
|
|
22300
22917
|
pendingUnrefed: timers.pendingUnrefed,
|
|
22918
|
+
/** Client requests sent but not yet read to completion. */
|
|
22919
|
+
pendingRequests: () => inFlightRequests,
|
|
22920
|
+
cancelTimers: timers.cancelAll,
|
|
22301
22921
|
writeStdin: (data) => {
|
|
22302
22922
|
if (options.interactiveStdin) stdin.write(data);
|
|
22303
22923
|
},
|
|
@@ -22525,9 +23145,20 @@ function createFsModule(volume, cwd, stdinPath) {
|
|
|
22525
23145
|
if (position == null) file3.position = start2 + chunk.length;
|
|
22526
23146
|
return chunk.length;
|
|
22527
23147
|
},
|
|
22528
|
-
createReadStream: (path) => {
|
|
22529
|
-
const
|
|
22530
|
-
|
|
23148
|
+
createReadStream: (path, options) => {
|
|
23149
|
+
const target = abs(path);
|
|
23150
|
+
const settings = typeof options === "string" ? { encoding: options } : options ?? {};
|
|
23151
|
+
const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
|
|
23152
|
+
const start2 = settings.start ?? 0;
|
|
23153
|
+
const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
|
|
23154
|
+
const slice = whole.subarray(start2, Math.max(start2, end));
|
|
23155
|
+
const stream = streamModule4.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
|
|
23156
|
+
Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
|
|
23157
|
+
queueMicrotask(() => {
|
|
23158
|
+
stream.emit("open", 0);
|
|
23159
|
+
stream.emit("ready");
|
|
23160
|
+
});
|
|
23161
|
+
return stream;
|
|
22531
23162
|
},
|
|
22532
23163
|
createWriteStream: (path, options) => {
|
|
22533
23164
|
const target = abs(path);
|
|
@@ -22968,6 +23599,27 @@ function createTrackedTimers() {
|
|
|
22968
23599
|
live.delete(handle);
|
|
22969
23600
|
native(handle);
|
|
22970
23601
|
};
|
|
23602
|
+
const cancelAll = () => {
|
|
23603
|
+
for (const handle of [...live, ...unrefed]) {
|
|
23604
|
+
const state = states.get(handle);
|
|
23605
|
+
if (!state) continue;
|
|
23606
|
+
state.active = false;
|
|
23607
|
+
try {
|
|
23608
|
+
clearTimeout(state.native);
|
|
23609
|
+
} catch {
|
|
23610
|
+
}
|
|
23611
|
+
try {
|
|
23612
|
+
clearInterval(state.native);
|
|
23613
|
+
} catch {
|
|
23614
|
+
}
|
|
23615
|
+
try {
|
|
23616
|
+
(globalThis.clearImmediate ?? clearTimeout)(state.native);
|
|
23617
|
+
} catch {
|
|
23618
|
+
}
|
|
23619
|
+
}
|
|
23620
|
+
live.clear();
|
|
23621
|
+
unrefed.clear();
|
|
23622
|
+
};
|
|
22971
23623
|
return {
|
|
22972
23624
|
api: {
|
|
22973
23625
|
setTimeout: setTimeoutTracked,
|
|
@@ -22978,7 +23630,8 @@ function createTrackedTimers() {
|
|
|
22978
23630
|
clearImmediate: (handle) => clear2(handle, globalThis.clearImmediate ?? clearTimeout)
|
|
22979
23631
|
},
|
|
22980
23632
|
pending: () => live.size,
|
|
22981
|
-
pendingUnrefed: () => unrefed.size
|
|
23633
|
+
pendingUnrefed: () => unrefed.size,
|
|
23634
|
+
cancelAll
|
|
22982
23635
|
};
|
|
22983
23636
|
}
|
|
22984
23637
|
function createTimerPromises() {
|
|
@@ -23432,22 +24085,209 @@ var MemoryVolume = class {
|
|
|
23432
24085
|
}
|
|
23433
24086
|
};
|
|
23434
24087
|
|
|
23435
|
-
// src/runtime/
|
|
23436
|
-
|
|
23437
|
-
|
|
23438
|
-
|
|
23439
|
-
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
|
|
23443
|
-
|
|
23444
|
-
|
|
23445
|
-
|
|
23446
|
-
|
|
23447
|
-
|
|
23448
|
-
|
|
23449
|
-
|
|
23450
|
-
|
|
24088
|
+
// src/runtime/mirroring-volume.ts
|
|
24089
|
+
init_path();
|
|
24090
|
+
var MirroringVolume = class {
|
|
24091
|
+
constructor(inner = new MemoryVolume()) {
|
|
24092
|
+
this.inner = inner;
|
|
24093
|
+
}
|
|
24094
|
+
inner;
|
|
24095
|
+
mirror;
|
|
24096
|
+
root = "/";
|
|
24097
|
+
/**
|
|
24098
|
+
* Start mirroring the tree under `root`, seeding it with what is there now.
|
|
24099
|
+
*
|
|
24100
|
+
* Called once the Rolldown binding is known to be in play; before that a
|
|
24101
|
+
* container pays nothing for this.
|
|
24102
|
+
*/
|
|
24103
|
+
attach(mirror, root) {
|
|
24104
|
+
this.mirror = mirror;
|
|
24105
|
+
this.root = clean(root);
|
|
24106
|
+
this.seed();
|
|
24107
|
+
}
|
|
24108
|
+
detach() {
|
|
24109
|
+
this.mirror = void 0;
|
|
24110
|
+
}
|
|
24111
|
+
/** Copy the whole subtree across. The only bulk operation that remains. */
|
|
24112
|
+
seed() {
|
|
24113
|
+
const mirror = this.mirror;
|
|
24114
|
+
if (!mirror) return;
|
|
24115
|
+
try {
|
|
24116
|
+
mirror.rmSync?.(this.root, { recursive: true, force: true });
|
|
24117
|
+
} catch {
|
|
24118
|
+
}
|
|
24119
|
+
const copy = (path) => {
|
|
24120
|
+
let stat2;
|
|
24121
|
+
try {
|
|
24122
|
+
stat2 = this.inner.lstatSync(path);
|
|
24123
|
+
} catch {
|
|
24124
|
+
return;
|
|
24125
|
+
}
|
|
24126
|
+
if (stat2.isDirectory()) {
|
|
24127
|
+
this.safely(() => mirror.mkdirSync(path, { recursive: true }));
|
|
24128
|
+
for (const name of this.inner.readdirSync(path)) copy(join(path, name));
|
|
24129
|
+
} else if (stat2.isSymbolicLink()) {
|
|
24130
|
+
this.safely(() => {
|
|
24131
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24132
|
+
mirror.symlinkSync(this.inner.readlinkSync(path), path);
|
|
24133
|
+
});
|
|
24134
|
+
} else if (!path.endsWith(".node")) {
|
|
24135
|
+
this.safely(() => {
|
|
24136
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24137
|
+
mirror.writeFileSync(path, this.inner.readFileSync(path));
|
|
24138
|
+
});
|
|
24139
|
+
}
|
|
24140
|
+
};
|
|
24141
|
+
copy(this.root);
|
|
24142
|
+
}
|
|
24143
|
+
/** Is this path inside the mirrored subtree? */
|
|
24144
|
+
mirrored(path) {
|
|
24145
|
+
if (!this.mirror) return false;
|
|
24146
|
+
const clean2 = clean(path);
|
|
24147
|
+
return this.root === "/" || clean2 === this.root || clean2.startsWith(`${this.root}/`);
|
|
24148
|
+
}
|
|
24149
|
+
/**
|
|
24150
|
+
* Run a mirror update, swallowing failure.
|
|
24151
|
+
*
|
|
24152
|
+
* The mirror is a read-only cache for another engine. If it rejects
|
|
24153
|
+
* something — an unsupported operation, a path it has not seen — the
|
|
24154
|
+
* container's own write has still happened and must still succeed.
|
|
24155
|
+
*/
|
|
24156
|
+
safely(update) {
|
|
24157
|
+
try {
|
|
24158
|
+
update();
|
|
24159
|
+
} catch {
|
|
24160
|
+
}
|
|
24161
|
+
}
|
|
24162
|
+
/** Push a path's current state across, whatever it is now. */
|
|
24163
|
+
sync(path) {
|
|
24164
|
+
const mirror = this.mirror;
|
|
24165
|
+
if (!mirror || !this.mirrored(path)) return;
|
|
24166
|
+
let stat2;
|
|
24167
|
+
try {
|
|
24168
|
+
stat2 = this.inner.lstatSync(path);
|
|
24169
|
+
} catch {
|
|
24170
|
+
this.safely(() => {
|
|
24171
|
+
if (mirror.rmSync) mirror.rmSync(path, { recursive: true, force: true });
|
|
24172
|
+
else mirror.unlinkSync?.(path);
|
|
24173
|
+
});
|
|
24174
|
+
return;
|
|
24175
|
+
}
|
|
24176
|
+
if (stat2.isDirectory()) {
|
|
24177
|
+
this.safely(() => mirror.mkdirSync(path, { recursive: true }));
|
|
24178
|
+
return;
|
|
24179
|
+
}
|
|
24180
|
+
if (stat2.isSymbolicLink()) {
|
|
24181
|
+
this.safely(() => {
|
|
24182
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24183
|
+
mirror.symlinkSync(this.inner.readlinkSync(path), path);
|
|
24184
|
+
});
|
|
24185
|
+
return;
|
|
24186
|
+
}
|
|
24187
|
+
if (path.endsWith(".node")) return;
|
|
24188
|
+
this.safely(() => {
|
|
24189
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24190
|
+
mirror.writeFileSync(path, this.inner.readFileSync(path));
|
|
24191
|
+
});
|
|
24192
|
+
}
|
|
24193
|
+
// ── reads: straight through ───────────────────────────────────────────────
|
|
24194
|
+
readFileSync(path) {
|
|
24195
|
+
return this.inner.readFileSync(path);
|
|
24196
|
+
}
|
|
24197
|
+
readdirSync(path) {
|
|
24198
|
+
return this.inner.readdirSync(path);
|
|
24199
|
+
}
|
|
24200
|
+
lstatSync(path) {
|
|
24201
|
+
return this.inner.lstatSync(path);
|
|
24202
|
+
}
|
|
24203
|
+
readlinkSync(path) {
|
|
24204
|
+
return this.inner.readlinkSync(path);
|
|
24205
|
+
}
|
|
24206
|
+
getStats() {
|
|
24207
|
+
return this.inner.getStats();
|
|
24208
|
+
}
|
|
24209
|
+
// ── writes: applied, then mirrored ────────────────────────────────────────
|
|
24210
|
+
writeFileSync(path, data) {
|
|
24211
|
+
this.inner.writeFileSync(path, data);
|
|
24212
|
+
this.sync(path);
|
|
24213
|
+
}
|
|
24214
|
+
appendFileSync(path, data) {
|
|
24215
|
+
this.inner.appendFileSync(path, data);
|
|
24216
|
+
this.sync(path);
|
|
24217
|
+
}
|
|
24218
|
+
mkdirSync(path, options) {
|
|
24219
|
+
this.inner.mkdirSync(path, options);
|
|
24220
|
+
this.sync(path);
|
|
24221
|
+
}
|
|
24222
|
+
rmdirSync(path) {
|
|
24223
|
+
this.inner.rmdirSync(path);
|
|
24224
|
+
this.sync(path);
|
|
24225
|
+
}
|
|
24226
|
+
unlinkSync(path) {
|
|
24227
|
+
this.inner.unlinkSync(path);
|
|
24228
|
+
this.sync(path);
|
|
24229
|
+
}
|
|
24230
|
+
renameSync(from, to) {
|
|
24231
|
+
this.inner.renameSync(from, to);
|
|
24232
|
+
this.sync(from);
|
|
24233
|
+
this.sync(to);
|
|
24234
|
+
}
|
|
24235
|
+
symlinkSync(target, path) {
|
|
24236
|
+
this.inner.symlinkSync(target, path);
|
|
24237
|
+
this.sync(path);
|
|
24238
|
+
}
|
|
24239
|
+
linkSync(existing, path) {
|
|
24240
|
+
this.inner.linkSync(existing, path);
|
|
24241
|
+
this.sync(path);
|
|
24242
|
+
}
|
|
24243
|
+
truncateSync(path, length) {
|
|
24244
|
+
this.inner.truncateSync(path, length);
|
|
24245
|
+
this.sync(path);
|
|
24246
|
+
}
|
|
24247
|
+
/* Permissions and timestamps do not change what a bundler resolves, and
|
|
24248
|
+
* `memfs` is stricter about them than this volume is. Applied here only. */
|
|
24249
|
+
chmodSync(path, mode) {
|
|
24250
|
+
this.inner.chmodSync(path, mode);
|
|
24251
|
+
}
|
|
24252
|
+
lchmodSync(path, mode) {
|
|
24253
|
+
this.inner.lchmodSync(path, mode);
|
|
24254
|
+
}
|
|
24255
|
+
chownSync(path, uid, gid) {
|
|
24256
|
+
this.inner.chownSync(path, uid, gid);
|
|
24257
|
+
}
|
|
24258
|
+
lchownSync(path, uid, gid) {
|
|
24259
|
+
this.inner.lchownSync(path, uid, gid);
|
|
24260
|
+
}
|
|
24261
|
+
utimesSync(path, atime, mtime) {
|
|
24262
|
+
this.inner.utimesSync(path, atime, mtime);
|
|
24263
|
+
}
|
|
24264
|
+
// ── snapshots ─────────────────────────────────────────────────────────────
|
|
24265
|
+
snapshot() {
|
|
24266
|
+
return this.inner.snapshot();
|
|
24267
|
+
}
|
|
24268
|
+
/** A restore replaces everything, so the mirror is rebuilt rather than patched. */
|
|
24269
|
+
restore(entries) {
|
|
24270
|
+
this.inner.restore(entries);
|
|
24271
|
+
this.seed();
|
|
24272
|
+
}
|
|
24273
|
+
};
|
|
24274
|
+
|
|
24275
|
+
// src/runtime/host-esbuild.ts
|
|
24276
|
+
var ASYNC_API = ["transform", "build", "context", "formatMessages", "analyzeMetafile"];
|
|
24277
|
+
function createHostEsbuild() {
|
|
24278
|
+
let loading = null;
|
|
24279
|
+
let started = null;
|
|
24280
|
+
const ensure = async () => {
|
|
24281
|
+
loading ??= start().then((api) => started = api);
|
|
24282
|
+
return loading;
|
|
24283
|
+
};
|
|
24284
|
+
const module = new Proxy({}, {
|
|
24285
|
+
get(_target, key) {
|
|
24286
|
+
if (typeof key !== "string") return void 0;
|
|
24287
|
+
if (ASYNC_API.includes(key)) {
|
|
24288
|
+
return async (...args) => {
|
|
24289
|
+
const api = await ensure();
|
|
24290
|
+
if (!api) throw esbuildUnavailable();
|
|
23451
24291
|
return api[key](...args);
|
|
23452
24292
|
};
|
|
23453
24293
|
}
|
|
@@ -23501,6 +24341,7 @@ function ensureProcessGlobal() {
|
|
|
23501
24341
|
}
|
|
23502
24342
|
|
|
23503
24343
|
// src/runtime/host-rolldown.ts
|
|
24344
|
+
var BUNDLER_HINT = "If this is a bundler pre-bundling the worker away, exclude the binding from dependency optimisation \u2014 in Vite:\n\n optimizeDeps: { exclude: ['@rolldown/binding-wasm32-wasi'] }";
|
|
23504
24345
|
async function loadHostRolldownBinding() {
|
|
23505
24346
|
if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) {
|
|
23506
24347
|
throw new Error(
|
|
@@ -23514,7 +24355,13 @@ async function loadHostRolldownBinding() {
|
|
|
23514
24355
|
if (typeof process !== "undefined" && process.env?.SANDBOXEDJS_DEBUG) {
|
|
23515
24356
|
console.error("[sandboxedjs] Rolldown WASI binding unavailable:", error);
|
|
23516
24357
|
}
|
|
23517
|
-
|
|
24358
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
24359
|
+
throw new Error(
|
|
24360
|
+
`The optional Rolldown WASI binding could not be loaded: ${reason}` + (typeof window === "undefined" ? "" : `
|
|
24361
|
+
|
|
24362
|
+
${BUNDLER_HINT}`),
|
|
24363
|
+
{ cause: error }
|
|
24364
|
+
);
|
|
23518
24365
|
}
|
|
23519
24366
|
}
|
|
23520
24367
|
|
|
@@ -23554,6 +24401,7 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
23554
24401
|
inputEnded = false;
|
|
23555
24402
|
pendingInput = [];
|
|
23556
24403
|
resolveKilled;
|
|
24404
|
+
cleanup;
|
|
23557
24405
|
killedPromise = new Promise((resolve2) => {
|
|
23558
24406
|
this.resolveKilled = resolve2;
|
|
23559
24407
|
});
|
|
@@ -23592,13 +24440,32 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
23592
24440
|
for (const chunk of this.pendingInput.splice(0)) input(chunk);
|
|
23593
24441
|
if (this.inputEnded) end();
|
|
23594
24442
|
}
|
|
24443
|
+
/**
|
|
24444
|
+
* End the process now.
|
|
24445
|
+
*
|
|
24446
|
+
* Killing has to settle `completion`, not merely record the intent. A
|
|
24447
|
+
* program with an interval outstanding has work pending forever, so the
|
|
24448
|
+
* runtime's own idle check will never end it — before this, killing such a
|
|
24449
|
+
* process left the caller awaiting a promise that could not resolve.
|
|
24450
|
+
*/
|
|
23595
24451
|
kill(_signal = "SIGTERM") {
|
|
24452
|
+
if (this.killed) return;
|
|
23596
24453
|
this.killed = true;
|
|
23597
24454
|
this.resolveKilled();
|
|
24455
|
+
this.cleanup?.();
|
|
24456
|
+
this.finish(137);
|
|
23598
24457
|
}
|
|
23599
24458
|
waitForKill() {
|
|
23600
24459
|
return this.killedPromise;
|
|
23601
24460
|
}
|
|
24461
|
+
isKilled() {
|
|
24462
|
+
return this.killed;
|
|
24463
|
+
}
|
|
24464
|
+
/** Registered by the task so a kill can release what the program still holds. */
|
|
24465
|
+
onKill(cleanup) {
|
|
24466
|
+
this.cleanup = cleanup;
|
|
24467
|
+
if (this.killed) cleanup();
|
|
24468
|
+
}
|
|
23602
24469
|
/** End the process now, for an asynchronous `process.exit`. */
|
|
23603
24470
|
exitNow(code) {
|
|
23604
24471
|
this.finish(code);
|
|
@@ -23644,6 +24511,11 @@ var PodChildProcess = class {
|
|
|
23644
24511
|
started = false;
|
|
23645
24512
|
cancelled = false;
|
|
23646
24513
|
child;
|
|
24514
|
+
/* The child is launched asynchronously, but a parent may write and close
|
|
24515
|
+
* its input synchronously right after spawning. Holding both until the
|
|
24516
|
+
* child exists is what keeps `echo hi | child` from losing the `hi`. */
|
|
24517
|
+
pendingInput = "";
|
|
24518
|
+
inputEnded = false;
|
|
23647
24519
|
on(event, listener) {
|
|
23648
24520
|
let set = this.listeners.get(event);
|
|
23649
24521
|
if (!set) this.listeners.set(event, set = /* @__PURE__ */ new Set());
|
|
@@ -23666,6 +24538,11 @@ var PodChildProcess = class {
|
|
|
23666
24538
|
(child) => {
|
|
23667
24539
|
this.child = child;
|
|
23668
24540
|
if (this.cancelled) child.kill();
|
|
24541
|
+
if (this.pendingInput !== "") {
|
|
24542
|
+
child.write(this.pendingInput);
|
|
24543
|
+
this.pendingInput = "";
|
|
24544
|
+
}
|
|
24545
|
+
if (this.inputEnded) child.endInput?.();
|
|
23669
24546
|
child.on("output", (text2) => {
|
|
23670
24547
|
this.stdout += text2;
|
|
23671
24548
|
this.emit("stdout", text2);
|
|
@@ -23688,7 +24565,13 @@ var PodChildProcess = class {
|
|
|
23688
24565
|
});
|
|
23689
24566
|
}
|
|
23690
24567
|
sendStdin(data) {
|
|
23691
|
-
this.child
|
|
24568
|
+
if (this.child) this.child.write(data);
|
|
24569
|
+
else this.pendingInput += data;
|
|
24570
|
+
}
|
|
24571
|
+
/** Signal EOF, so a child reading stdin to the end can finish. */
|
|
24572
|
+
endStdin() {
|
|
24573
|
+
if (this.child) this.child.endInput?.();
|
|
24574
|
+
else this.inputEnded = true;
|
|
23692
24575
|
}
|
|
23693
24576
|
kill(signal = "SIGTERM") {
|
|
23694
24577
|
if (this.child) this.child.kill(signal);
|
|
@@ -23744,7 +24627,10 @@ function removeEscapedErrorReporting() {
|
|
|
23744
24627
|
}
|
|
23745
24628
|
var DRAIN_TURNS = 4;
|
|
23746
24629
|
var LocalRuntimePod = class _LocalRuntimePod {
|
|
23747
|
-
|
|
24630
|
+
/* Wrapped so that a foreign filesystem — Rolldown's WebAssembly memfs — can
|
|
24631
|
+
* be kept in step as writes happen, rather than deep-copied once per spawn.
|
|
24632
|
+
* With nothing attached this is a straight pass-through. */
|
|
24633
|
+
volume = new MirroringVolume(new MemoryVolume());
|
|
23748
24634
|
packages;
|
|
23749
24635
|
instanceId = `sbx-${Math.random().toString(36).slice(2)}`;
|
|
23750
24636
|
router = new VirtualHttpRouter();
|
|
@@ -23771,6 +24657,8 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23771
24657
|
modules;
|
|
23772
24658
|
esbuild;
|
|
23773
24659
|
rolldownBinding;
|
|
24660
|
+
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
24661
|
+
fetch;
|
|
23774
24662
|
constructor(options) {
|
|
23775
24663
|
ensureProcessGlobal();
|
|
23776
24664
|
this.workdir = options.workdir ?? "/";
|
|
@@ -23785,6 +24673,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23785
24673
|
const notify = options.onServerReady;
|
|
23786
24674
|
this.router.onListen = (port) => notify(port, `http://localhost:${port}`);
|
|
23787
24675
|
}
|
|
24676
|
+
if (options.fetch) this.fetch = options.fetch;
|
|
23788
24677
|
this.packages = new CleanPackageInstaller(this.volume, {
|
|
23789
24678
|
cwd: this.workdir,
|
|
23790
24679
|
...options.registry ? { registry: options.registry } : {},
|
|
@@ -23824,7 +24713,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23824
24713
|
proc.exitNow(code);
|
|
23825
24714
|
if (engine?.isEvaluating) throw new ProcessExit(code);
|
|
23826
24715
|
},
|
|
23827
|
-
http: { router: this.router, owner },
|
|
24716
|
+
http: { router: this.router, owner, ...this.fetch ? { fetch: this.fetch } : {} },
|
|
23828
24717
|
spawnChild: (config) => this.processManager.spawn(config),
|
|
23829
24718
|
...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
|
|
23830
24719
|
...options.interactiveStdin ? { interactiveStdin: true } : {},
|
|
@@ -23832,6 +24721,10 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23832
24721
|
onRawMode: (enabled) => proc.emit("rawmode", enabled)
|
|
23833
24722
|
});
|
|
23834
24723
|
proc.acceptInput((data) => core.writeStdin(data), () => core.endStdin());
|
|
24724
|
+
proc.onKill(() => {
|
|
24725
|
+
core.cancelTimers();
|
|
24726
|
+
this.router.closeOwner(owner);
|
|
24727
|
+
});
|
|
23835
24728
|
engine = new CommonJsEngine(this.volume, {
|
|
23836
24729
|
cwd,
|
|
23837
24730
|
builtins: core.builtins,
|
|
@@ -23841,7 +24734,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23841
24734
|
});
|
|
23842
24735
|
try {
|
|
23843
24736
|
await engine.run(script);
|
|
23844
|
-
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin);
|
|
24737
|
+
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests, () => proc.isKilled());
|
|
23845
24738
|
if (this.router.activePorts(owner).length) {
|
|
23846
24739
|
await proc.waitForKill();
|
|
23847
24740
|
return 137;
|
|
@@ -23862,13 +24755,13 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23862
24755
|
*/
|
|
23863
24756
|
async prepareRolldown(cwd, env2) {
|
|
23864
24757
|
const specifier = "@rolldown/binding-wasm32-wasi";
|
|
23865
|
-
if (!this.modules[specifier] &&
|
|
24758
|
+
if (!this.modules[specifier] && packageIsInstalled(this.volume, cwd, "rolldown")) {
|
|
23866
24759
|
this.rolldownBinding ??= loadHostRolldownBinding();
|
|
23867
24760
|
const binding = await this.rolldownBinding;
|
|
23868
24761
|
if (binding) this.modules[specifier] = binding;
|
|
23869
24762
|
}
|
|
23870
24763
|
if (this.modules[specifier]) {
|
|
23871
|
-
|
|
24764
|
+
attachRolldownMirror(this.modules[specifier], this.volume, cwd);
|
|
23872
24765
|
env2.NAPI_RS_FORCE_WASI ??= "true";
|
|
23873
24766
|
}
|
|
23874
24767
|
}
|
|
@@ -23887,18 +24780,18 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23887
24780
|
* A plain script that has genuinely finished falls straight through both,
|
|
23888
24781
|
* costing a handful of empty turns.
|
|
23889
24782
|
*/
|
|
23890
|
-
async settle(owner, pendingHandles, pendingUnrefed, readingStdin) {
|
|
24783
|
+
async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests, killed) {
|
|
23891
24784
|
for (let turn = 0; turn < DRAIN_TURNS; turn++) {
|
|
23892
|
-
if (this.router.activePorts(owner).length) return;
|
|
24785
|
+
if (this.router.activePorts(owner).length || killed()) return;
|
|
23893
24786
|
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
23894
24787
|
}
|
|
23895
|
-
if (pendingHandles() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
24788
|
+
if (pendingHandles() === 0 && pendingRequests() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
23896
24789
|
const deadline = Date.now() + 1e3;
|
|
23897
|
-
while (!this.router.activePorts(owner).length && Date.now() < deadline) {
|
|
24790
|
+
while (!this.router.activePorts(owner).length && !killed() && Date.now() < deadline) {
|
|
23898
24791
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23899
24792
|
}
|
|
23900
24793
|
}
|
|
23901
|
-
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || readingStdin())) {
|
|
24794
|
+
while (!this.router.activePorts(owner).length && !killed() && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
|
|
23902
24795
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23903
24796
|
}
|
|
23904
24797
|
}
|
|
@@ -23950,7 +24843,7 @@ function formatError(error) {
|
|
|
23950
24843
|
function isRecord(value) {
|
|
23951
24844
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23952
24845
|
}
|
|
23953
|
-
function
|
|
24846
|
+
function packageIsInstalled(volume, cwd, wanted) {
|
|
23954
24847
|
for (let dir3 = clean(cwd); ; dir3 = dirname(dir3)) {
|
|
23955
24848
|
if (packageTreeContains(volume, join(dir3, "node_modules"), wanted, /* @__PURE__ */ new Set())) return true;
|
|
23956
24849
|
if (dir3 === "/") return false;
|
|
@@ -23979,30 +24872,565 @@ function directory(volume, path) {
|
|
|
23979
24872
|
return false;
|
|
23980
24873
|
}
|
|
23981
24874
|
}
|
|
23982
|
-
function
|
|
24875
|
+
function attachRolldownMirror(binding, volume, root) {
|
|
23983
24876
|
const fs = binding?.__fs;
|
|
23984
24877
|
if (!fs?.mkdirSync || !fs?.writeFileSync) return;
|
|
23985
|
-
|
|
23986
|
-
|
|
23987
|
-
|
|
24878
|
+
volume.attach(fs, root);
|
|
24879
|
+
}
|
|
24880
|
+
|
|
24881
|
+
// src/runtime/sync-channel.ts
|
|
24882
|
+
var STATE = 0;
|
|
24883
|
+
var LENGTH = 1;
|
|
24884
|
+
var MORE = 2;
|
|
24885
|
+
var CONTROL_WORDS = 4;
|
|
24886
|
+
var STATE_REQUEST = 1;
|
|
24887
|
+
var STATE_RESPONSE = 2;
|
|
24888
|
+
var STATE_CONTINUE = 3;
|
|
24889
|
+
var STATE_CLOSED = 4;
|
|
24890
|
+
function createSyncChannelBuffers(capacityBytes = 1 << 20) {
|
|
24891
|
+
return {
|
|
24892
|
+
control: new SharedArrayBuffer(CONTROL_WORDS * Int32Array.BYTES_PER_ELEMENT),
|
|
24893
|
+
data: new SharedArrayBuffer(capacityBytes)
|
|
24894
|
+
};
|
|
24895
|
+
}
|
|
24896
|
+
function syncChannelSupported() {
|
|
24897
|
+
if (typeof SharedArrayBuffer !== "function") return false;
|
|
24898
|
+
if (typeof Atomics !== "object" || typeof Atomics.wait !== "function") return false;
|
|
24899
|
+
if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) return false;
|
|
24900
|
+
return true;
|
|
24901
|
+
}
|
|
24902
|
+
var SyncChannelServer = class {
|
|
24903
|
+
constructor(buffers, handle) {
|
|
24904
|
+
this.handle = handle;
|
|
24905
|
+
this.control = new Int32Array(buffers.control);
|
|
24906
|
+
this.data = new Uint8Array(buffers.data);
|
|
24907
|
+
this.capacity = this.data.length;
|
|
23988
24908
|
}
|
|
23989
|
-
|
|
23990
|
-
|
|
23991
|
-
|
|
23992
|
-
|
|
23993
|
-
|
|
23994
|
-
|
|
23995
|
-
|
|
24909
|
+
handle;
|
|
24910
|
+
control;
|
|
24911
|
+
data;
|
|
24912
|
+
capacity;
|
|
24913
|
+
/** Request chunks gathered so far, and the response still to be sent. */
|
|
24914
|
+
incoming = [];
|
|
24915
|
+
outgoing = null;
|
|
24916
|
+
sent = 0;
|
|
24917
|
+
closed = false;
|
|
24918
|
+
/** Call from the wake message the client sends after each chunk. */
|
|
24919
|
+
async pump() {
|
|
24920
|
+
if (this.closed) return;
|
|
24921
|
+
const state = Atomics.load(this.control, STATE);
|
|
24922
|
+
if (state === STATE_REQUEST) {
|
|
24923
|
+
const size = Atomics.load(this.control, LENGTH);
|
|
24924
|
+
this.incoming.push(this.data.slice(0, size));
|
|
24925
|
+
if (Atomics.load(this.control, MORE) === 1) {
|
|
24926
|
+
this.publish(STATE_CONTINUE);
|
|
24927
|
+
return;
|
|
24928
|
+
}
|
|
24929
|
+
const request = concat3(this.incoming);
|
|
24930
|
+
this.incoming = [];
|
|
24931
|
+
let response;
|
|
23996
24932
|
try {
|
|
23997
|
-
|
|
24933
|
+
response = await this.handle(request);
|
|
23998
24934
|
} catch {
|
|
24935
|
+
response = new Uint8Array();
|
|
24936
|
+
}
|
|
24937
|
+
if (this.closed) return;
|
|
24938
|
+
this.outgoing = response;
|
|
24939
|
+
this.sent = 0;
|
|
24940
|
+
this.sendChunk();
|
|
24941
|
+
return;
|
|
24942
|
+
}
|
|
24943
|
+
if (state === STATE_CONTINUE) this.sendChunk();
|
|
24944
|
+
}
|
|
24945
|
+
/** Release a blocked client, e.g. when the container is torn down. */
|
|
24946
|
+
close() {
|
|
24947
|
+
if (this.closed) return;
|
|
24948
|
+
this.closed = true;
|
|
24949
|
+
Atomics.store(this.control, STATE, STATE_CLOSED);
|
|
24950
|
+
Atomics.notify(this.control, STATE);
|
|
24951
|
+
}
|
|
24952
|
+
sendChunk() {
|
|
24953
|
+
const payload = this.outgoing ?? new Uint8Array();
|
|
24954
|
+
const size = Math.min(this.capacity, payload.length - this.sent);
|
|
24955
|
+
this.data.set(payload.subarray(this.sent, this.sent + size), 0);
|
|
24956
|
+
this.sent += size;
|
|
24957
|
+
Atomics.store(this.control, LENGTH, size);
|
|
24958
|
+
Atomics.store(this.control, MORE, this.sent < payload.length ? 1 : 0);
|
|
24959
|
+
this.publish(STATE_RESPONSE);
|
|
24960
|
+
}
|
|
24961
|
+
publish(state) {
|
|
24962
|
+
Atomics.store(this.control, STATE, state);
|
|
24963
|
+
Atomics.notify(this.control, STATE);
|
|
24964
|
+
}
|
|
24965
|
+
};
|
|
24966
|
+
function concat3(parts) {
|
|
24967
|
+
if (parts.length === 1) return parts[0];
|
|
24968
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
24969
|
+
const joined = new Uint8Array(total);
|
|
24970
|
+
let at = 0;
|
|
24971
|
+
for (const part of parts) {
|
|
24972
|
+
joined.set(part, at);
|
|
24973
|
+
at += part.length;
|
|
24974
|
+
}
|
|
24975
|
+
return joined;
|
|
24976
|
+
}
|
|
24977
|
+
|
|
24978
|
+
// src/runtime/remote-volume.ts
|
|
24979
|
+
var encoder7 = new TextEncoder();
|
|
24980
|
+
var decoder7 = new TextDecoder();
|
|
24981
|
+
function encodeFrame(header, body) {
|
|
24982
|
+
const json = encoder7.encode(JSON.stringify(header));
|
|
24983
|
+
const frame = new Uint8Array(4 + json.length + (body?.length ?? 0));
|
|
24984
|
+
new DataView(frame.buffer).setUint32(0, json.length, true);
|
|
24985
|
+
frame.set(json, 4);
|
|
24986
|
+
if (body?.length) frame.set(body, 4 + json.length);
|
|
24987
|
+
return frame;
|
|
24988
|
+
}
|
|
24989
|
+
function decodeFrame(frame) {
|
|
24990
|
+
const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
|
|
24991
|
+
const headerLength = view.getUint32(0, true);
|
|
24992
|
+
const header = JSON.parse(decoder7.decode(frame.subarray(4, 4 + headerLength)));
|
|
24993
|
+
return { header, body: frame.subarray(4 + headerLength) };
|
|
24994
|
+
}
|
|
24995
|
+
function flattenStat(stat2) {
|
|
24996
|
+
return {
|
|
24997
|
+
kind: stat2.isDirectory() ? "directory" : stat2.isSymbolicLink() ? "symlink" : "file",
|
|
24998
|
+
mode: stat2.mode,
|
|
24999
|
+
size: stat2.size,
|
|
25000
|
+
uid: stat2.uid,
|
|
25001
|
+
gid: stat2.gid,
|
|
25002
|
+
ino: stat2.ino,
|
|
25003
|
+
nlink: stat2.nlink,
|
|
25004
|
+
atimeMs: stat2.atimeMs,
|
|
25005
|
+
mtimeMs: stat2.mtimeMs,
|
|
25006
|
+
ctimeMs: stat2.ctimeMs,
|
|
25007
|
+
birthtimeMs: stat2.birthtimeMs
|
|
25008
|
+
};
|
|
25009
|
+
}
|
|
25010
|
+
var BINARY_RESULTS = /* @__PURE__ */ new Set(["readFileSync"]);
|
|
25011
|
+
var BINARY_ARGUMENTS = /* @__PURE__ */ new Set(["writeFileSync", "appendFileSync"]);
|
|
25012
|
+
function serveVolume(volume) {
|
|
25013
|
+
return (request) => {
|
|
25014
|
+
const { header, body } = decodeFrame(request);
|
|
25015
|
+
const target = volume;
|
|
25016
|
+
try {
|
|
25017
|
+
const method = target[header.op];
|
|
25018
|
+
if (typeof method !== "function") {
|
|
25019
|
+
return encodeFrame({ ok: false, error: { message: `unknown volume operation: ${header.op}` } });
|
|
25020
|
+
}
|
|
25021
|
+
const plain = header.args.map((value) => value === null ? void 0 : value);
|
|
25022
|
+
const args = BINARY_ARGUMENTS.has(header.op) ? [plain[0], body] : header.op === "utimesSync" ? [plain[0], new Date(plain[1]), new Date(plain[2])] : plain;
|
|
25023
|
+
const result = method.apply(volume, args);
|
|
25024
|
+
if (BINARY_RESULTS.has(header.op)) {
|
|
25025
|
+
return encodeFrame({ ok: true }, result);
|
|
23999
25026
|
}
|
|
24000
|
-
|
|
24001
|
-
|
|
24002
|
-
|
|
25027
|
+
if (header.op === "lstatSync") {
|
|
25028
|
+
return encodeFrame({ ok: true, value: flattenStat(result) });
|
|
25029
|
+
}
|
|
25030
|
+
return encodeFrame({ ok: true, value: result });
|
|
25031
|
+
} catch (error) {
|
|
25032
|
+
const failure = error;
|
|
25033
|
+
return encodeFrame({
|
|
25034
|
+
ok: false,
|
|
25035
|
+
error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
|
|
25036
|
+
});
|
|
24003
25037
|
}
|
|
24004
25038
|
};
|
|
24005
|
-
|
|
25039
|
+
}
|
|
25040
|
+
|
|
25041
|
+
// src/runtime/sync-syscalls.ts
|
|
25042
|
+
var SPAWN_OP = "spawnSync";
|
|
25043
|
+
function serveSyncSyscalls(options) {
|
|
25044
|
+
const volumeHandler = serveVolume(options.volume);
|
|
25045
|
+
return async (request) => {
|
|
25046
|
+
const { header } = decodeFrame(request);
|
|
25047
|
+
if (header.op !== SPAWN_OP) return volumeHandler(request);
|
|
25048
|
+
try {
|
|
25049
|
+
const result = await options.spawnChild(header.args[0]);
|
|
25050
|
+
return encodeFrame({ ok: true, value: result });
|
|
25051
|
+
} catch (error) {
|
|
25052
|
+
const failure = error;
|
|
25053
|
+
return encodeFrame({
|
|
25054
|
+
ok: true,
|
|
25055
|
+
value: {
|
|
25056
|
+
status: null,
|
|
25057
|
+
stdout: "",
|
|
25058
|
+
stderr: "",
|
|
25059
|
+
signal: null,
|
|
25060
|
+
error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
|
|
25061
|
+
}
|
|
25062
|
+
});
|
|
25063
|
+
}
|
|
25064
|
+
};
|
|
25065
|
+
}
|
|
25066
|
+
|
|
25067
|
+
// src/runtime/worker-host.ts
|
|
25068
|
+
function defaultWorkerUrl() {
|
|
25069
|
+
return new URL("./worker-entry.js", import.meta.url);
|
|
25070
|
+
}
|
|
25071
|
+
function hasDomWorker() {
|
|
25072
|
+
return typeof Worker === "function" && typeof document !== "undefined";
|
|
25073
|
+
}
|
|
25074
|
+
async function startRuntimeWorker(options = {}) {
|
|
25075
|
+
const url = options.url ?? defaultWorkerUrl();
|
|
25076
|
+
const worker = hasDomWorker() ? await startDomWorker(url) : await startNodeWorker(url, options.workerData ?? {});
|
|
25077
|
+
await new Promise((resolve2, reject) => {
|
|
25078
|
+
const timer = setTimeout(() => reject(new Error("the runtime worker did not start in time")), options.timeoutMs ?? 1e4);
|
|
25079
|
+
worker.onMessage((message) => {
|
|
25080
|
+
if (message?.type === "sandboxedjs:ready") {
|
|
25081
|
+
clearTimeout(timer);
|
|
25082
|
+
resolve2();
|
|
25083
|
+
}
|
|
25084
|
+
});
|
|
25085
|
+
worker.onError((error) => {
|
|
25086
|
+
clearTimeout(timer);
|
|
25087
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
25088
|
+
});
|
|
25089
|
+
});
|
|
25090
|
+
return worker;
|
|
25091
|
+
}
|
|
25092
|
+
async function startDomWorker(url) {
|
|
25093
|
+
const worker = new Worker(url, { type: "module" });
|
|
25094
|
+
const listeners = [];
|
|
25095
|
+
const errors = [];
|
|
25096
|
+
worker.addEventListener("message", (event) => {
|
|
25097
|
+
for (const listener of listeners) listener(event.data);
|
|
25098
|
+
});
|
|
25099
|
+
worker.addEventListener("error", (event) => {
|
|
25100
|
+
const detail = event.message || "the runtime worker failed to load";
|
|
25101
|
+
for (const listener of errors) listener(new Error(detail));
|
|
25102
|
+
});
|
|
25103
|
+
return {
|
|
25104
|
+
postMessage: (message) => worker.postMessage(message),
|
|
25105
|
+
onMessage: (listener) => {
|
|
25106
|
+
listeners.push(listener);
|
|
25107
|
+
},
|
|
25108
|
+
onError: (listener) => {
|
|
25109
|
+
errors.push(listener);
|
|
25110
|
+
},
|
|
25111
|
+
terminate: () => worker.terminate()
|
|
25112
|
+
};
|
|
25113
|
+
}
|
|
25114
|
+
async function startNodeWorker(url, workerData) {
|
|
25115
|
+
const specifier = ["node", "worker_threads"].join(":");
|
|
25116
|
+
const { Worker: NodeWorker } = await import(
|
|
25117
|
+
/* @vite-ignore */
|
|
25118
|
+
/* webpackIgnore: true */
|
|
25119
|
+
specifier
|
|
25120
|
+
);
|
|
25121
|
+
const worker = new NodeWorker(url, { workerData });
|
|
25122
|
+
return {
|
|
25123
|
+
postMessage: (message) => worker.postMessage(message),
|
|
25124
|
+
onMessage: (listener) => worker.on("message", listener),
|
|
25125
|
+
onError: (listener) => worker.on("error", listener),
|
|
25126
|
+
terminate: () => worker.terminate()
|
|
25127
|
+
};
|
|
25128
|
+
}
|
|
25129
|
+
var WorkerProcess = class extends EventEmitter4 {
|
|
25130
|
+
constructor(worker, release) {
|
|
25131
|
+
super();
|
|
25132
|
+
this.worker = worker;
|
|
25133
|
+
this.release = release;
|
|
25134
|
+
super.on("error", () => {
|
|
25135
|
+
});
|
|
25136
|
+
this.completion = new Promise((resolve2) => {
|
|
25137
|
+
this.resolveCompletion = resolve2;
|
|
25138
|
+
});
|
|
25139
|
+
}
|
|
25140
|
+
worker;
|
|
25141
|
+
release;
|
|
25142
|
+
completion;
|
|
25143
|
+
resolveCompletion;
|
|
25144
|
+
settled = false;
|
|
25145
|
+
out = [];
|
|
25146
|
+
err = [];
|
|
25147
|
+
started = false;
|
|
25148
|
+
pendingInput = [];
|
|
25149
|
+
inputEnded = false;
|
|
25150
|
+
on(event, listener) {
|
|
25151
|
+
return super.on(event, listener);
|
|
25152
|
+
}
|
|
25153
|
+
/** Called once the guest has been told to start; releases anything buffered. */
|
|
25154
|
+
begin() {
|
|
25155
|
+
this.started = true;
|
|
25156
|
+
for (const chunk of this.pendingInput.splice(0)) this.worker.postMessage({ type: "stdin", data: chunk });
|
|
25157
|
+
if (this.inputEnded) this.worker.postMessage({ type: "stdin-end" });
|
|
25158
|
+
}
|
|
25159
|
+
output(text2) {
|
|
25160
|
+
this.out.push(text2);
|
|
25161
|
+
this.emit("output", text2);
|
|
25162
|
+
}
|
|
25163
|
+
error(text2) {
|
|
25164
|
+
this.err.push(text2);
|
|
25165
|
+
this.emit("error", text2);
|
|
25166
|
+
}
|
|
25167
|
+
/**
|
|
25168
|
+
* Deliver input to the running program.
|
|
25169
|
+
*
|
|
25170
|
+
* Held until the guest has been started, for the same reason the in-realm
|
|
25171
|
+
* pod holds it: an interactive session's first keystrokes arrive while the
|
|
25172
|
+
* program is still loading, and dropping them loses the answer to a prompt.
|
|
25173
|
+
*/
|
|
25174
|
+
write(data) {
|
|
25175
|
+
if (this.started) this.worker.postMessage({ type: "stdin", data });
|
|
25176
|
+
else this.pendingInput.push(data);
|
|
25177
|
+
}
|
|
25178
|
+
endInput() {
|
|
25179
|
+
this.inputEnded = true;
|
|
25180
|
+
if (this.started) this.worker.postMessage({ type: "stdin-end" });
|
|
25181
|
+
}
|
|
25182
|
+
kill(_signal = "SIGTERM") {
|
|
25183
|
+
this.worker.postMessage({ type: "kill" });
|
|
25184
|
+
this.finish(137);
|
|
25185
|
+
}
|
|
25186
|
+
finish(exitCode) {
|
|
25187
|
+
if (this.settled) return;
|
|
25188
|
+
this.settled = true;
|
|
25189
|
+
this.emit("exit", exitCode);
|
|
25190
|
+
this.resolveCompletion({ exitCode, stdout: this.out.join(""), stderr: this.err.join("") });
|
|
25191
|
+
this.release();
|
|
25192
|
+
}
|
|
25193
|
+
};
|
|
25194
|
+
var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
25195
|
+
workerUrl;
|
|
25196
|
+
/** Live workers, so teardown can stop them all. */
|
|
25197
|
+
live = /* @__PURE__ */ new Set();
|
|
25198
|
+
constructor(options) {
|
|
25199
|
+
super(options);
|
|
25200
|
+
this.workerUrl = options.workerUrl;
|
|
25201
|
+
}
|
|
25202
|
+
/**
|
|
25203
|
+
* Boot a Worker-backed pod, or return null when this host cannot support one.
|
|
25204
|
+
*
|
|
25205
|
+
* Declining is a first-class outcome. `SharedArrayBuffer` needs cross-origin
|
|
25206
|
+
* isolation, a bundler may have made the guest script unreachable, and a host
|
|
25207
|
+
* that supplied its own module objects has handed over things no thread
|
|
25208
|
+
* boundary can carry. In every case the caller falls back to the in-realm pod
|
|
25209
|
+
* and keeps working.
|
|
25210
|
+
*/
|
|
25211
|
+
static async tryBoot(options = {}) {
|
|
25212
|
+
if (!syncChannelSupported()) return null;
|
|
25213
|
+
if (options.modules && Object.keys(options.modules).length > 0) return null;
|
|
25214
|
+
const pod = new _WorkerRuntimePod(options);
|
|
25215
|
+
try {
|
|
25216
|
+
const probe = await startRuntimeWorker({ ...options.workerUrl ? { url: options.workerUrl } : {}, timeoutMs: 1e4 });
|
|
25217
|
+
await probe.terminate();
|
|
25218
|
+
return pod;
|
|
25219
|
+
} catch {
|
|
25220
|
+
pod.teardown();
|
|
25221
|
+
return null;
|
|
25222
|
+
}
|
|
25223
|
+
}
|
|
25224
|
+
async spawn(command, args = [], options = {}) {
|
|
25225
|
+
if (command !== "node" && command !== "nodejs") return super.spawn(command, args, options);
|
|
25226
|
+
const script = args[0];
|
|
25227
|
+
if (!script) return super.spawn(command, args, options);
|
|
25228
|
+
const cwd = typeof options.cwd === "string" ? options.cwd : this.workdir;
|
|
25229
|
+
if (this.needsHostModules(cwd)) return super.spawn(command, args, options);
|
|
25230
|
+
return await this.spawnInWorker(script, args, cwd, options);
|
|
25231
|
+
}
|
|
25232
|
+
async spawnInWorker(script, args, cwd, options) {
|
|
25233
|
+
const env2 = { ...this.env, ...isRecord2(options.env) ? options.env : {} };
|
|
25234
|
+
const owner = `${this.instanceId}:${Math.random().toString(36).slice(2)}`;
|
|
25235
|
+
const buffers = createSyncChannelBuffers();
|
|
25236
|
+
const worker = await startRuntimeWorker({
|
|
25237
|
+
...this.workerUrl ? { url: this.workerUrl } : {},
|
|
25238
|
+
timeoutMs: 15e3
|
|
25239
|
+
});
|
|
25240
|
+
const server = new SyncChannelServer(buffers, serveSyncSyscalls({
|
|
25241
|
+
volume: this.volume,
|
|
25242
|
+
spawnChild: (request) => this.runChildToCompletion(request)
|
|
25243
|
+
}));
|
|
25244
|
+
const entry = { worker, server };
|
|
25245
|
+
this.live.add(entry);
|
|
25246
|
+
const process2 = new WorkerProcess(worker, () => {
|
|
25247
|
+
this.live.delete(entry);
|
|
25248
|
+
server.close();
|
|
25249
|
+
this.closeProxies(owner);
|
|
25250
|
+
void worker.terminate();
|
|
25251
|
+
});
|
|
25252
|
+
const children = /* @__PURE__ */ new Map();
|
|
25253
|
+
worker.onMessage((raw) => {
|
|
25254
|
+
const message = raw;
|
|
25255
|
+
switch (message?.type) {
|
|
25256
|
+
case "wake":
|
|
25257
|
+
void server.pump();
|
|
25258
|
+
return;
|
|
25259
|
+
case "output":
|
|
25260
|
+
process2.output(String(message.text));
|
|
25261
|
+
return;
|
|
25262
|
+
case "error":
|
|
25263
|
+
process2.error(String(message.text));
|
|
25264
|
+
return;
|
|
25265
|
+
case "rawmode":
|
|
25266
|
+
process2.emit("rawmode", Boolean(message.enabled));
|
|
25267
|
+
return;
|
|
25268
|
+
case "exit":
|
|
25269
|
+
process2.finish(Number(message.code));
|
|
25270
|
+
return;
|
|
25271
|
+
case "listen":
|
|
25272
|
+
this.proxyPort(Number(message.port), owner, worker);
|
|
25273
|
+
return;
|
|
25274
|
+
case "http-response":
|
|
25275
|
+
this.settleProxied(Number(message.id), message.response);
|
|
25276
|
+
return;
|
|
25277
|
+
case "child-start":
|
|
25278
|
+
this.startChild(worker, children, message);
|
|
25279
|
+
return;
|
|
25280
|
+
case "child-stdin":
|
|
25281
|
+
children.get(message.id)?.sendStdin?.(String(message.data));
|
|
25282
|
+
return;
|
|
25283
|
+
case "child-stdin-end":
|
|
25284
|
+
children.get(message.id)?.endStdin?.();
|
|
25285
|
+
return;
|
|
25286
|
+
case "child-kill":
|
|
25287
|
+
children.get(message.id)?.kill(String(message.signal));
|
|
25288
|
+
return;
|
|
25289
|
+
default:
|
|
25290
|
+
return;
|
|
25291
|
+
}
|
|
25292
|
+
});
|
|
25293
|
+
worker.postMessage({
|
|
25294
|
+
type: "start",
|
|
25295
|
+
buffers,
|
|
25296
|
+
script,
|
|
25297
|
+
cwd,
|
|
25298
|
+
env: env2,
|
|
25299
|
+
argv: Array.isArray(options.argv) ? options.argv : ["/usr/bin/node", script, ...args.slice(1)],
|
|
25300
|
+
aliases: this.aliases,
|
|
25301
|
+
...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
|
|
25302
|
+
...options.interactiveStdin ? { interactiveStdin: true } : {},
|
|
25303
|
+
...options.tty ? { tty: true } : {}
|
|
25304
|
+
});
|
|
25305
|
+
process2.begin();
|
|
25306
|
+
return process2;
|
|
25307
|
+
}
|
|
25308
|
+
/** Start an asynchronous child on the host's behalf and relay its events. */
|
|
25309
|
+
startChild(worker, children, message) {
|
|
25310
|
+
const handle = this.processManager.spawn(message.config);
|
|
25311
|
+
children.set(message.id, handle);
|
|
25312
|
+
for (const event of ["stdout", "stderr", "exit"]) {
|
|
25313
|
+
handle.on(event, (value) => worker.postMessage({ type: "child-event", id: message.id, event, value }));
|
|
25314
|
+
}
|
|
25315
|
+
handle.exec();
|
|
25316
|
+
}
|
|
25317
|
+
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
25318
|
+
runChildToCompletion(request) {
|
|
25319
|
+
return new Promise((resolve2) => {
|
|
25320
|
+
let handle;
|
|
25321
|
+
try {
|
|
25322
|
+
handle = this.processManager.spawn({
|
|
25323
|
+
command: request.command,
|
|
25324
|
+
args: request.args,
|
|
25325
|
+
cwd: request.cwd,
|
|
25326
|
+
...request.env ? { env: request.env } : {}
|
|
25327
|
+
});
|
|
25328
|
+
} catch (error) {
|
|
25329
|
+
const failure = error;
|
|
25330
|
+
resolve2({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure.code ? { code: failure.code } : {}, message: failure.message } });
|
|
25331
|
+
return;
|
|
25332
|
+
}
|
|
25333
|
+
let stdout = "";
|
|
25334
|
+
let stderr = "";
|
|
25335
|
+
handle.on("stdout", (text2) => {
|
|
25336
|
+
stdout += text2;
|
|
25337
|
+
});
|
|
25338
|
+
handle.on("stderr", (text2) => {
|
|
25339
|
+
stderr += text2;
|
|
25340
|
+
});
|
|
25341
|
+
handle.on("exit", (code) => resolve2({ status: code, stdout, stderr, signal: null }));
|
|
25342
|
+
handle.exec();
|
|
25343
|
+
if (request.input !== void 0) {
|
|
25344
|
+
handle.sendStdin?.(request.input);
|
|
25345
|
+
}
|
|
25346
|
+
handle.endStdin?.();
|
|
25347
|
+
});
|
|
25348
|
+
}
|
|
25349
|
+
// ── HTTP servers living on another thread ─────────────────────────────────
|
|
25350
|
+
proxies = /* @__PURE__ */ new Map();
|
|
25351
|
+
waiting = /* @__PURE__ */ new Map();
|
|
25352
|
+
nextRequestId = 1;
|
|
25353
|
+
/**
|
|
25354
|
+
* Register a stand-in for a server that is actually running in the Worker.
|
|
25355
|
+
*
|
|
25356
|
+
* The router only knows how to reach servers on this thread, so each bound
|
|
25357
|
+
* port gets a local server whose whole job is to forward and wait.
|
|
25358
|
+
*/
|
|
25359
|
+
proxyPort(port, owner, worker) {
|
|
25360
|
+
if (this.proxies.has(port)) return;
|
|
25361
|
+
const server = new VirtualHttpServer(this.router, owner, (request, response) => {
|
|
25362
|
+
void this.forward(worker, port, request, response);
|
|
25363
|
+
});
|
|
25364
|
+
try {
|
|
25365
|
+
server.listen(port);
|
|
25366
|
+
this.proxies.set(port, server);
|
|
25367
|
+
} catch {
|
|
25368
|
+
}
|
|
25369
|
+
}
|
|
25370
|
+
async forward(worker, port, request, response) {
|
|
25371
|
+
const chunks = [];
|
|
25372
|
+
for await (const chunk of request) chunks.push(chunk);
|
|
25373
|
+
const body = concat4(chunks);
|
|
25374
|
+
const id = this.nextRequestId++;
|
|
25375
|
+
const answered = new Promise((resolve2) => this.waiting.set(id, resolve2));
|
|
25376
|
+
worker.postMessage({
|
|
25377
|
+
type: "http-request",
|
|
25378
|
+
id,
|
|
25379
|
+
port,
|
|
25380
|
+
init: { method: request.method, path: request.url, headers: request.headers, body }
|
|
25381
|
+
});
|
|
25382
|
+
let result;
|
|
25383
|
+
try {
|
|
25384
|
+
result = await answered;
|
|
25385
|
+
} catch (error) {
|
|
25386
|
+
this.waiting.delete(id);
|
|
25387
|
+
response.writeHead(500, "Internal Server Error", {});
|
|
25388
|
+
response.end(new TextEncoder().encode(error instanceof Error ? error.message : String(error)));
|
|
25389
|
+
return;
|
|
25390
|
+
}
|
|
25391
|
+
response.writeHead(Number(result.statusCode ?? 200), String(result.statusMessage ?? ""), result.headers ?? {});
|
|
25392
|
+
response.end(result.body ?? new Uint8Array());
|
|
25393
|
+
}
|
|
25394
|
+
settleProxied(id, response) {
|
|
25395
|
+
const resolve2 = this.waiting.get(id);
|
|
25396
|
+
if (!resolve2) return;
|
|
25397
|
+
this.waiting.delete(id);
|
|
25398
|
+
resolve2(response);
|
|
25399
|
+
}
|
|
25400
|
+
closeProxies(owner) {
|
|
25401
|
+
for (const [port, server] of [...this.proxies]) {
|
|
25402
|
+
if (server.owner !== owner) continue;
|
|
25403
|
+
server.close();
|
|
25404
|
+
this.proxies.delete(port);
|
|
25405
|
+
}
|
|
25406
|
+
}
|
|
25407
|
+
teardown() {
|
|
25408
|
+
for (const { worker, server } of [...this.live]) {
|
|
25409
|
+
server.close();
|
|
25410
|
+
void worker.terminate();
|
|
25411
|
+
}
|
|
25412
|
+
this.live.clear();
|
|
25413
|
+
super.teardown();
|
|
25414
|
+
}
|
|
25415
|
+
/** Does anything under `cwd` need a module only the host can supply? */
|
|
25416
|
+
needsHostModules(cwd) {
|
|
25417
|
+
return packageIsInstalled(this.volume, cwd, "rolldown");
|
|
25418
|
+
}
|
|
25419
|
+
};
|
|
25420
|
+
function isRecord2(value) {
|
|
25421
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25422
|
+
}
|
|
25423
|
+
function concat4(parts) {
|
|
25424
|
+
if (parts.length === 0) return new Uint8Array();
|
|
25425
|
+
if (parts.length === 1) return parts[0];
|
|
25426
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
25427
|
+
const joined = new Uint8Array(total);
|
|
25428
|
+
let at = 0;
|
|
25429
|
+
for (const part of parts) {
|
|
25430
|
+
joined.set(part, at);
|
|
25431
|
+
at += part.length;
|
|
25432
|
+
}
|
|
25433
|
+
return joined;
|
|
24006
25434
|
}
|
|
24007
25435
|
|
|
24008
25436
|
// src/container/container.ts
|
|
@@ -24049,11 +25477,13 @@ var Container = class _Container {
|
|
|
24049
25477
|
// ── boot ──────────────────────────────────────────────────────────────────
|
|
24050
25478
|
static async create(opts = {}) {
|
|
24051
25479
|
if (opts.python) configurePython(opts.python);
|
|
24052
|
-
const
|
|
25480
|
+
const podOptions = {
|
|
24053
25481
|
workdir: opts.cwd ?? "/",
|
|
24054
25482
|
env: opts.env ?? {},
|
|
24055
25483
|
...opts.onServerReady ? { onServerReady: opts.onServerReady } : {}
|
|
24056
|
-
}
|
|
25484
|
+
};
|
|
25485
|
+
const workerOptions = { ...podOptions, ...opts.workerUrl ? { workerUrl: opts.workerUrl } : {} };
|
|
25486
|
+
const pod = opts.pod ?? (opts.isolation === "realm" ? null : await WorkerRuntimePod.tryBoot(workerOptions)) ?? await LocalRuntimePod.boot(podOptions);
|
|
24057
25487
|
const kernel = new Kernel({
|
|
24058
25488
|
pod,
|
|
24059
25489
|
hostname: opts.hostname ?? "sandbox",
|
|
@@ -24295,15 +25725,15 @@ var Container = class _Container {
|
|
|
24295
25725
|
}
|
|
24296
25726
|
makeStdio(opts) {
|
|
24297
25727
|
const combined = [];
|
|
24298
|
-
const
|
|
25728
|
+
const decoder8 = new TextDecoder();
|
|
24299
25729
|
const stdout = new BufferSink((chunk) => {
|
|
24300
|
-
const text2 =
|
|
25730
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
24301
25731
|
combined.push(text2);
|
|
24302
25732
|
opts.onStdout?.(text2);
|
|
24303
25733
|
this.hooks.onStdout?.(text2);
|
|
24304
25734
|
});
|
|
24305
25735
|
const stderr = new BufferSink((chunk) => {
|
|
24306
|
-
const text2 =
|
|
25736
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
24307
25737
|
combined.push(text2);
|
|
24308
25738
|
opts.onStderr?.(text2);
|
|
24309
25739
|
this.hooks.onStderr?.(text2);
|
|
@@ -24559,17 +25989,18 @@ var Terminal = class {
|
|
|
24559
25989
|
// ── key handling ──────────────────────────────────────────────────────────
|
|
24560
25990
|
key(ch) {
|
|
24561
25991
|
if (this.running) {
|
|
24562
|
-
|
|
25992
|
+
const raw = this.currentStdin?.rawMode === true;
|
|
25993
|
+
if (ch === CTRL_C && !raw) {
|
|
24563
25994
|
this.session.proc.deliver("SIGINT");
|
|
24564
25995
|
this.write("^C\r\n");
|
|
24565
25996
|
return;
|
|
24566
25997
|
}
|
|
24567
|
-
if (ch === CTRL_D) {
|
|
25998
|
+
if (ch === CTRL_D && !raw) {
|
|
24568
25999
|
this.currentStdin?.end();
|
|
24569
26000
|
return;
|
|
24570
26001
|
}
|
|
24571
|
-
if (!
|
|
24572
|
-
this.currentStdin?.write(ch === "\r" ? "\n" : ch);
|
|
26002
|
+
if (!raw) this.write(ch === "\r" ? "\r\n" : ch);
|
|
26003
|
+
this.currentStdin?.write(!raw && ch === "\r" ? "\n" : ch);
|
|
24573
26004
|
return;
|
|
24574
26005
|
}
|
|
24575
26006
|
if (this.escapeBuffer !== "") {
|
|
@@ -24915,6 +26346,6 @@ init_expand();
|
|
|
24915
26346
|
init_builtins();
|
|
24916
26347
|
var src_default = createContainer;
|
|
24917
26348
|
|
|
24918
|
-
export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, strerror, transformEsm, unameInfo };
|
|
26349
|
+
export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, startRuntimeWorker, strerror, syncChannelSupported, transformEsm, unameInfo };
|
|
24919
26350
|
//# sourceMappingURL=index.js.map
|
|
24920
26351
|
//# sourceMappingURL=index.js.map
|