sandboxedjs 0.1.27 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +624 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +624 -43
- package/dist/index.js.map +1 -1
- 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";
|
|
@@ -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(),
|
|
@@ -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,269 @@ 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 = this.router.activePortsIncludes(this.target.port) && 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
|
+
const result = await this.router.request(this.target.port, {
|
|
21841
|
+
method: this.target.method,
|
|
21842
|
+
path: this.target.path,
|
|
21843
|
+
headers: this.getHeaders(),
|
|
21844
|
+
body: body.length ? new Uint8Array(body) : null
|
|
21845
|
+
});
|
|
21846
|
+
const body_ = result.body;
|
|
21847
|
+
const bytes2 = typeof body_ === "string" ? new TextEncoder().encode(body_) : body_ instanceof ArrayBuffer ? new Uint8Array(body_) : body_ ?? new Uint8Array();
|
|
21848
|
+
const status = result.statusCode ?? 200;
|
|
21849
|
+
return new VirtualClientResponse(status, result.statusMessage ?? STATUS_CODES[status] ?? "", lowercaseHeaders(result.headers), bytes2);
|
|
21850
|
+
}
|
|
21851
|
+
async viaFetch(body) {
|
|
21852
|
+
const fetchImpl = this.fetchImpl ?? globalThis.fetch;
|
|
21853
|
+
if (typeof fetchImpl !== "function") {
|
|
21854
|
+
throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${this.target.hostname}`), { code: "ENOTFOUND" });
|
|
21855
|
+
}
|
|
21856
|
+
const portSuffix = this.target.protocol === "https:" && this.target.port === 443 || this.target.protocol === "http:" && this.target.port === 80 ? "" : `:${this.target.port}`;
|
|
21857
|
+
const url = `${this.target.protocol}//${this.target.hostname}${portSuffix}${this.target.path}`;
|
|
21858
|
+
const bodyless = this.target.method === "GET" || this.target.method === "HEAD";
|
|
21859
|
+
const headers = this.getHeaders();
|
|
21860
|
+
delete headers.host;
|
|
21861
|
+
delete headers.connection;
|
|
21862
|
+
delete headers["content-length"];
|
|
21863
|
+
const response = await fetchImpl(url, {
|
|
21864
|
+
method: this.target.method,
|
|
21865
|
+
headers,
|
|
21866
|
+
...bodyless || body.length === 0 ? {} : { body: new Uint8Array(body) },
|
|
21867
|
+
redirect: "follow"
|
|
21868
|
+
});
|
|
21869
|
+
const received = {};
|
|
21870
|
+
response.headers.forEach((value, key) => {
|
|
21871
|
+
received[key.toLowerCase()] = value;
|
|
21872
|
+
});
|
|
21873
|
+
const bytes2 = new Uint8Array(await response.arrayBuffer());
|
|
21874
|
+
return new VirtualClientResponse(response.status, response.statusText, received, bytes2);
|
|
21875
|
+
}
|
|
21876
|
+
};
|
|
21877
|
+
function lowercaseHeaders(headers) {
|
|
21878
|
+
return Object.fromEntries(Object.entries(headers ?? {}).map(([key, value]) => [key.toLowerCase(), String(value)]));
|
|
21879
|
+
}
|
|
21880
|
+
function createHttpModule(router, owner, options = {}, defaultProtocol = "http:") {
|
|
21440
21881
|
const createServer = (listener) => new VirtualHttpServer(router, owner, listener);
|
|
21441
|
-
const
|
|
21882
|
+
const request = (input, second, third) => {
|
|
21883
|
+
const overrides = second && typeof second === "object" && !(second instanceof Function) ? second : void 0;
|
|
21884
|
+
const callback = [second, third].find((value) => typeof value === "function");
|
|
21885
|
+
const req = new VirtualClientRequest(resolveTarget(input, overrides, defaultProtocol), router, options.fetch, options.trackRequest);
|
|
21886
|
+
if (callback) req.on("response", callback);
|
|
21887
|
+
return req;
|
|
21888
|
+
};
|
|
21889
|
+
const get = (input, second, third) => {
|
|
21890
|
+
const req = request(input, second, third);
|
|
21891
|
+
req.end();
|
|
21892
|
+
return req;
|
|
21893
|
+
};
|
|
21894
|
+
return {
|
|
21442
21895
|
createServer,
|
|
21896
|
+
request,
|
|
21897
|
+
get,
|
|
21443
21898
|
Server: VirtualHttpServer,
|
|
21444
21899
|
ServerResponse: VirtualServerResponse,
|
|
21445
21900
|
IncomingMessage: VirtualIncomingMessage,
|
|
21901
|
+
ClientRequest: VirtualClientRequest,
|
|
21446
21902
|
METHODS,
|
|
21447
21903
|
STATUS_CODES,
|
|
21448
21904
|
maxHeaderSize: 16 * 1024,
|
|
@@ -21452,10 +21908,6 @@ function createHttpModule(router, owner) {
|
|
|
21452
21908
|
Agent: class Agent {
|
|
21453
21909
|
}
|
|
21454
21910
|
};
|
|
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
21911
|
}
|
|
21460
21912
|
function validateHeaderName(name) {
|
|
21461
21913
|
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 +22047,13 @@ var ChildProcess = class extends EventEmitter4 {
|
|
|
21595
22047
|
} catch {
|
|
21596
22048
|
}
|
|
21597
22049
|
done();
|
|
22050
|
+
},
|
|
22051
|
+
final: (done) => {
|
|
22052
|
+
try {
|
|
22053
|
+
handle.endStdin?.();
|
|
22054
|
+
} catch {
|
|
22055
|
+
}
|
|
22056
|
+
done();
|
|
21598
22057
|
}
|
|
21599
22058
|
});
|
|
21600
22059
|
this.stdio = [this.stdin, this.stdout, this.stderr];
|
|
@@ -21833,7 +22292,7 @@ function emitKeypressEvents(stream) {
|
|
|
21833
22292
|
}
|
|
21834
22293
|
});
|
|
21835
22294
|
}
|
|
21836
|
-
function createReadlineModule(defaultInput) {
|
|
22295
|
+
function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
21837
22296
|
class Interface extends EventEmitter4 {
|
|
21838
22297
|
constructor(input, output, terminal = false) {
|
|
21839
22298
|
super();
|
|
@@ -21844,6 +22303,14 @@ function createReadlineModule(defaultInput) {
|
|
|
21844
22303
|
if (terminal) {
|
|
21845
22304
|
emitKeypressEvents(input);
|
|
21846
22305
|
input?.on?.("keypress", this.onTerminalKeypress);
|
|
22306
|
+
if (typeof input?.setRawMode === "function") {
|
|
22307
|
+
try {
|
|
22308
|
+
input.setRawMode(true);
|
|
22309
|
+
this.ownsRawMode = true;
|
|
22310
|
+
} catch {
|
|
22311
|
+
}
|
|
22312
|
+
}
|
|
22313
|
+
input?.resume?.();
|
|
21847
22314
|
} else {
|
|
21848
22315
|
input?.on?.("data", (chunk) => this.receive(String(chunk)));
|
|
21849
22316
|
}
|
|
@@ -21855,6 +22322,10 @@ function createReadlineModule(defaultInput) {
|
|
|
21855
22322
|
buffer = "";
|
|
21856
22323
|
pending = [];
|
|
21857
22324
|
lines = [];
|
|
22325
|
+
/** Set while `question` is waiting, so the echoed line carries the query. */
|
|
22326
|
+
questionPrompt = null;
|
|
22327
|
+
/** Raw mode is only ours to restore if we were the one to enable it. */
|
|
22328
|
+
ownsRawMode = false;
|
|
21858
22329
|
line = "";
|
|
21859
22330
|
cursor = 0;
|
|
21860
22331
|
terminal;
|
|
@@ -21862,20 +22333,31 @@ function createReadlineModule(defaultInput) {
|
|
|
21862
22333
|
/** Split incoming data into lines, answering any waiting `question`. */
|
|
21863
22334
|
receive(text2) {
|
|
21864
22335
|
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
|
-
|
|
22336
|
+
let match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22337
|
+
while (match2) {
|
|
22338
|
+
const line = this.buffer.slice(0, match2.index);
|
|
22339
|
+
this.buffer = this.buffer.slice(match2.index + match2[0].length);
|
|
22340
|
+
this.deliver(line);
|
|
22341
|
+
match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22342
|
+
}
|
|
22343
|
+
}
|
|
22344
|
+
/** Hand a completed line to whoever is waiting for it. */
|
|
22345
|
+
deliver(line) {
|
|
22346
|
+
const waiting = this.pending.shift();
|
|
22347
|
+
if (waiting) {
|
|
22348
|
+
this.questionPrompt = null;
|
|
22349
|
+
waiting(line);
|
|
22350
|
+
return;
|
|
21876
22351
|
}
|
|
22352
|
+
this.lines.push(line);
|
|
22353
|
+
this.emit("line", line);
|
|
21877
22354
|
}
|
|
21878
22355
|
question(query, callback) {
|
|
22356
|
+
if (this.terminal) {
|
|
22357
|
+
this.questionPrompt = query;
|
|
22358
|
+
this.line = "";
|
|
22359
|
+
this.cursor = 0;
|
|
22360
|
+
}
|
|
21879
22361
|
this.output?.write?.(query);
|
|
21880
22362
|
if (callback) {
|
|
21881
22363
|
this.pending.push(callback);
|
|
@@ -21890,6 +22372,9 @@ function createReadlineModule(defaultInput) {
|
|
|
21890
22372
|
setPrompt(text2) {
|
|
21891
22373
|
this.promptText = text2;
|
|
21892
22374
|
}
|
|
22375
|
+
getPrompt() {
|
|
22376
|
+
return this.promptText;
|
|
22377
|
+
}
|
|
21893
22378
|
pause() {
|
|
21894
22379
|
this.input?.pause?.();
|
|
21895
22380
|
return this;
|
|
@@ -21917,21 +22402,48 @@ function createReadlineModule(defaultInput) {
|
|
|
21917
22402
|
if (text2) {
|
|
21918
22403
|
this.line = this.line.slice(0, this.cursor) + text2 + this.line.slice(this.cursor);
|
|
21919
22404
|
this.cursor += text2.length;
|
|
22405
|
+
this.refresh();
|
|
21920
22406
|
}
|
|
21921
22407
|
}
|
|
21922
22408
|
getCursorPos() {
|
|
21923
|
-
return { rows: 0, cols: this.cursor + this.
|
|
22409
|
+
return { rows: 0, cols: this.cursor + this.currentPrompt().length };
|
|
21924
22410
|
}
|
|
21925
22411
|
close() {
|
|
21926
22412
|
if (this.closed) return;
|
|
21927
22413
|
this.closed = true;
|
|
21928
22414
|
if (this.terminal) {
|
|
21929
22415
|
this.input?.off?.("keypress", this.onTerminalKeypress);
|
|
22416
|
+
if (this.ownsRawMode) {
|
|
22417
|
+
this.ownsRawMode = false;
|
|
22418
|
+
try {
|
|
22419
|
+
this.input?.setRawMode?.(false);
|
|
22420
|
+
} catch {
|
|
22421
|
+
}
|
|
22422
|
+
}
|
|
21930
22423
|
this.input?.pause?.();
|
|
21931
22424
|
}
|
|
21932
22425
|
for (const waiting of this.pending.splice(0)) waiting("");
|
|
21933
22426
|
this.emit("close");
|
|
21934
22427
|
}
|
|
22428
|
+
/** The text shown to the left of the edited line. */
|
|
22429
|
+
currentPrompt() {
|
|
22430
|
+
return this.questionPrompt ?? this.promptText;
|
|
22431
|
+
}
|
|
22432
|
+
/**
|
|
22433
|
+
* Repaint the edited line.
|
|
22434
|
+
*
|
|
22435
|
+
* In raw mode nothing echoes on its own, so an Interface that does not do
|
|
22436
|
+
* this leaves the user typing blind. Libraries that draw their own frame
|
|
22437
|
+
* (clack, inquirer) simply overwrite this, exactly as they do on Node.
|
|
22438
|
+
*/
|
|
22439
|
+
refresh() {
|
|
22440
|
+
if (!this.terminal) return;
|
|
22441
|
+
const prompt = this.currentPrompt();
|
|
22442
|
+
let text2 = `\r\x1B[0K${prompt}${this.line}`;
|
|
22443
|
+
const back = this.line.length - this.cursor;
|
|
22444
|
+
if (back > 0) text2 += `\x1B[${back}D`;
|
|
22445
|
+
this.output?.write?.(text2);
|
|
22446
|
+
}
|
|
21935
22447
|
edit(sequence, key) {
|
|
21936
22448
|
if (this.closed) return;
|
|
21937
22449
|
const name = key.name;
|
|
@@ -21939,48 +22451,62 @@ function createReadlineModule(defaultInput) {
|
|
|
21939
22451
|
const value = this.line;
|
|
21940
22452
|
this.line = "";
|
|
21941
22453
|
this.cursor = 0;
|
|
21942
|
-
this.
|
|
22454
|
+
this.output?.write?.("\r\n");
|
|
22455
|
+
this.deliver(value);
|
|
21943
22456
|
return;
|
|
21944
22457
|
}
|
|
21945
22458
|
if (name === "left") {
|
|
21946
22459
|
this.cursor = Math.max(0, this.cursor - 1);
|
|
22460
|
+
this.refresh();
|
|
21947
22461
|
return;
|
|
21948
22462
|
}
|
|
21949
22463
|
if (name === "right") {
|
|
21950
22464
|
this.cursor = Math.min(this.line.length, this.cursor + 1);
|
|
22465
|
+
this.refresh();
|
|
21951
22466
|
return;
|
|
21952
22467
|
}
|
|
21953
22468
|
if (name === "home" || key.ctrl && name === "a") {
|
|
21954
22469
|
this.cursor = 0;
|
|
22470
|
+
this.refresh();
|
|
21955
22471
|
return;
|
|
21956
22472
|
}
|
|
21957
22473
|
if (name === "end" || key.ctrl && name === "e") {
|
|
21958
22474
|
this.cursor = this.line.length;
|
|
22475
|
+
this.refresh();
|
|
21959
22476
|
return;
|
|
21960
22477
|
}
|
|
21961
22478
|
if (name === "backspace" || key.ctrl && name === "h") {
|
|
21962
22479
|
if (this.cursor > 0) {
|
|
21963
22480
|
this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
|
|
21964
22481
|
this.cursor--;
|
|
22482
|
+
this.refresh();
|
|
21965
22483
|
}
|
|
21966
22484
|
return;
|
|
21967
22485
|
}
|
|
21968
22486
|
if (name === "delete") {
|
|
21969
|
-
if (this.cursor < this.line.length)
|
|
22487
|
+
if (this.cursor < this.line.length) {
|
|
22488
|
+
this.line = this.line.slice(0, this.cursor) + this.line.slice(this.cursor + 1);
|
|
22489
|
+
this.refresh();
|
|
22490
|
+
}
|
|
21970
22491
|
return;
|
|
21971
22492
|
}
|
|
21972
22493
|
if (key.ctrl && name === "u") {
|
|
21973
22494
|
this.line = this.line.slice(this.cursor);
|
|
21974
22495
|
this.cursor = 0;
|
|
22496
|
+
this.refresh();
|
|
21975
22497
|
return;
|
|
21976
22498
|
}
|
|
21977
22499
|
if (key.ctrl && name === "k") {
|
|
21978
22500
|
this.line = this.line.slice(0, this.cursor);
|
|
22501
|
+
this.refresh();
|
|
21979
22502
|
return;
|
|
21980
22503
|
}
|
|
21981
22504
|
if (key.ctrl || key.meta || sequence.length !== 1 || sequence < " ") return;
|
|
22505
|
+
const atEnd = this.cursor === this.line.length;
|
|
21982
22506
|
this.line = this.line.slice(0, this.cursor) + sequence + this.line.slice(this.cursor);
|
|
21983
22507
|
this.cursor += sequence.length;
|
|
22508
|
+
if (atEnd) this.output?.write?.(sequence);
|
|
22509
|
+
else this.refresh();
|
|
21984
22510
|
}
|
|
21985
22511
|
async *[Symbol.asyncIterator]() {
|
|
21986
22512
|
while (!this.closed || this.lines.length) {
|
|
@@ -22010,13 +22536,23 @@ function createReadlineModule(defaultInput) {
|
|
|
22010
22536
|
}
|
|
22011
22537
|
}
|
|
22012
22538
|
}
|
|
22539
|
+
const isTerminal = (options, output) => {
|
|
22540
|
+
if (typeof options?.terminal === "boolean") return options.terminal;
|
|
22541
|
+
return Boolean(output?.isTTY);
|
|
22542
|
+
};
|
|
22013
22543
|
const createInterface = (options, output) => {
|
|
22014
22544
|
if (options && typeof options === "object" && !options.on) {
|
|
22015
|
-
const
|
|
22545
|
+
const resolvedOutput2 = options.output ?? defaultOutput();
|
|
22546
|
+
const instance = new Interface(
|
|
22547
|
+
options.input ?? defaultInput(),
|
|
22548
|
+
resolvedOutput2,
|
|
22549
|
+
isTerminal(options, resolvedOutput2)
|
|
22550
|
+
);
|
|
22016
22551
|
if (typeof options.prompt === "string") instance.setPrompt(options.prompt);
|
|
22017
22552
|
return instance;
|
|
22018
22553
|
}
|
|
22019
|
-
|
|
22554
|
+
const resolvedOutput = output ?? defaultOutput();
|
|
22555
|
+
return new Interface(options ?? defaultInput(), resolvedOutput, isTerminal(void 0, resolvedOutput));
|
|
22020
22556
|
};
|
|
22021
22557
|
const noop = () => {
|
|
22022
22558
|
};
|
|
@@ -22033,6 +22569,7 @@ function createReadlineModule(defaultInput) {
|
|
|
22033
22569
|
}
|
|
22034
22570
|
|
|
22035
22571
|
// src/runtime/core-modules.ts
|
|
22572
|
+
installReadableFrom(streamModule4);
|
|
22036
22573
|
var Dirent = class {
|
|
22037
22574
|
/** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
|
|
22038
22575
|
constructor(name, stat2, parentPath = "") {
|
|
@@ -22238,9 +22775,20 @@ function createCoreModules(options) {
|
|
|
22238
22775
|
throw new Error("createRequire is only available inside a loaded module");
|
|
22239
22776
|
}
|
|
22240
22777
|
};
|
|
22241
|
-
|
|
22778
|
+
let inFlightRequests = 0;
|
|
22779
|
+
const httpOptions = {
|
|
22780
|
+
...options.http?.fetch ? { fetch: options.http.fetch } : {},
|
|
22781
|
+
trackRequest: () => {
|
|
22782
|
+
inFlightRequests++;
|
|
22783
|
+
return () => {
|
|
22784
|
+
inFlightRequests--;
|
|
22785
|
+
};
|
|
22786
|
+
}
|
|
22787
|
+
};
|
|
22788
|
+
const http = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "http:") : createUnsupportedModule("http");
|
|
22789
|
+
const https = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "https:") : createUnsupportedModule("https");
|
|
22242
22790
|
const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd) : createUnsupportedModule("child_process");
|
|
22243
|
-
const readline = createReadlineModule(() => processObject.stdin);
|
|
22791
|
+
const readline = createReadlineModule(() => processObject.stdin, () => processObject.stdout);
|
|
22244
22792
|
const dns = createDnsModule();
|
|
22245
22793
|
const builtins = {
|
|
22246
22794
|
assert: assert_module_default,
|
|
@@ -22258,7 +22806,7 @@ function createCoreModules(options) {
|
|
|
22258
22806
|
"fs/promises": fs.promises,
|
|
22259
22807
|
module: moduleBuiltin,
|
|
22260
22808
|
http,
|
|
22261
|
-
https
|
|
22809
|
+
https,
|
|
22262
22810
|
os,
|
|
22263
22811
|
path,
|
|
22264
22812
|
"path/posix": path,
|
|
@@ -22298,6 +22846,8 @@ function createCoreModules(options) {
|
|
|
22298
22846
|
process: processObject,
|
|
22299
22847
|
pendingHandles: timers.pending,
|
|
22300
22848
|
pendingUnrefed: timers.pendingUnrefed,
|
|
22849
|
+
/** Client requests sent but not yet read to completion. */
|
|
22850
|
+
pendingRequests: () => inFlightRequests,
|
|
22301
22851
|
writeStdin: (data) => {
|
|
22302
22852
|
if (options.interactiveStdin) stdin.write(data);
|
|
22303
22853
|
},
|
|
@@ -22525,9 +23075,20 @@ function createFsModule(volume, cwd, stdinPath) {
|
|
|
22525
23075
|
if (position == null) file3.position = start2 + chunk.length;
|
|
22526
23076
|
return chunk.length;
|
|
22527
23077
|
},
|
|
22528
|
-
createReadStream: (path) => {
|
|
22529
|
-
const
|
|
22530
|
-
|
|
23078
|
+
createReadStream: (path, options) => {
|
|
23079
|
+
const target = abs(path);
|
|
23080
|
+
const settings = typeof options === "string" ? { encoding: options } : options ?? {};
|
|
23081
|
+
const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
|
|
23082
|
+
const start2 = settings.start ?? 0;
|
|
23083
|
+
const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
|
|
23084
|
+
const slice = whole.subarray(start2, Math.max(start2, end));
|
|
23085
|
+
const stream = streamModule4.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
|
|
23086
|
+
Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
|
|
23087
|
+
queueMicrotask(() => {
|
|
23088
|
+
stream.emit("open", 0);
|
|
23089
|
+
stream.emit("ready");
|
|
23090
|
+
});
|
|
23091
|
+
return stream;
|
|
22531
23092
|
},
|
|
22532
23093
|
createWriteStream: (path, options) => {
|
|
22533
23094
|
const target = abs(path);
|
|
@@ -23644,6 +24205,11 @@ var PodChildProcess = class {
|
|
|
23644
24205
|
started = false;
|
|
23645
24206
|
cancelled = false;
|
|
23646
24207
|
child;
|
|
24208
|
+
/* The child is launched asynchronously, but a parent may write and close
|
|
24209
|
+
* its input synchronously right after spawning. Holding both until the
|
|
24210
|
+
* child exists is what keeps `echo hi | child` from losing the `hi`. */
|
|
24211
|
+
pendingInput = "";
|
|
24212
|
+
inputEnded = false;
|
|
23647
24213
|
on(event, listener) {
|
|
23648
24214
|
let set = this.listeners.get(event);
|
|
23649
24215
|
if (!set) this.listeners.set(event, set = /* @__PURE__ */ new Set());
|
|
@@ -23666,6 +24232,11 @@ var PodChildProcess = class {
|
|
|
23666
24232
|
(child) => {
|
|
23667
24233
|
this.child = child;
|
|
23668
24234
|
if (this.cancelled) child.kill();
|
|
24235
|
+
if (this.pendingInput !== "") {
|
|
24236
|
+
child.write(this.pendingInput);
|
|
24237
|
+
this.pendingInput = "";
|
|
24238
|
+
}
|
|
24239
|
+
if (this.inputEnded) child.endInput?.();
|
|
23669
24240
|
child.on("output", (text2) => {
|
|
23670
24241
|
this.stdout += text2;
|
|
23671
24242
|
this.emit("stdout", text2);
|
|
@@ -23688,7 +24259,13 @@ var PodChildProcess = class {
|
|
|
23688
24259
|
});
|
|
23689
24260
|
}
|
|
23690
24261
|
sendStdin(data) {
|
|
23691
|
-
this.child
|
|
24262
|
+
if (this.child) this.child.write(data);
|
|
24263
|
+
else this.pendingInput += data;
|
|
24264
|
+
}
|
|
24265
|
+
/** Signal EOF, so a child reading stdin to the end can finish. */
|
|
24266
|
+
endStdin() {
|
|
24267
|
+
if (this.child) this.child.endInput?.();
|
|
24268
|
+
else this.inputEnded = true;
|
|
23692
24269
|
}
|
|
23693
24270
|
kill(signal = "SIGTERM") {
|
|
23694
24271
|
if (this.child) this.child.kill(signal);
|
|
@@ -23771,6 +24348,8 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23771
24348
|
modules;
|
|
23772
24349
|
esbuild;
|
|
23773
24350
|
rolldownBinding;
|
|
24351
|
+
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
24352
|
+
fetch;
|
|
23774
24353
|
constructor(options) {
|
|
23775
24354
|
ensureProcessGlobal();
|
|
23776
24355
|
this.workdir = options.workdir ?? "/";
|
|
@@ -23785,6 +24364,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23785
24364
|
const notify = options.onServerReady;
|
|
23786
24365
|
this.router.onListen = (port) => notify(port, `http://localhost:${port}`);
|
|
23787
24366
|
}
|
|
24367
|
+
if (options.fetch) this.fetch = options.fetch;
|
|
23788
24368
|
this.packages = new CleanPackageInstaller(this.volume, {
|
|
23789
24369
|
cwd: this.workdir,
|
|
23790
24370
|
...options.registry ? { registry: options.registry } : {},
|
|
@@ -23824,7 +24404,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23824
24404
|
proc.exitNow(code);
|
|
23825
24405
|
if (engine?.isEvaluating) throw new ProcessExit(code);
|
|
23826
24406
|
},
|
|
23827
|
-
http: { router: this.router, owner },
|
|
24407
|
+
http: { router: this.router, owner, ...this.fetch ? { fetch: this.fetch } : {} },
|
|
23828
24408
|
spawnChild: (config) => this.processManager.spawn(config),
|
|
23829
24409
|
...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
|
|
23830
24410
|
...options.interactiveStdin ? { interactiveStdin: true } : {},
|
|
@@ -23841,7 +24421,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23841
24421
|
});
|
|
23842
24422
|
try {
|
|
23843
24423
|
await engine.run(script);
|
|
23844
|
-
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin);
|
|
24424
|
+
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests);
|
|
23845
24425
|
if (this.router.activePorts(owner).length) {
|
|
23846
24426
|
await proc.waitForKill();
|
|
23847
24427
|
return 137;
|
|
@@ -23887,18 +24467,18 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23887
24467
|
* A plain script that has genuinely finished falls straight through both,
|
|
23888
24468
|
* costing a handful of empty turns.
|
|
23889
24469
|
*/
|
|
23890
|
-
async settle(owner, pendingHandles, pendingUnrefed, readingStdin) {
|
|
24470
|
+
async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests) {
|
|
23891
24471
|
for (let turn = 0; turn < DRAIN_TURNS; turn++) {
|
|
23892
24472
|
if (this.router.activePorts(owner).length) return;
|
|
23893
24473
|
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
23894
24474
|
}
|
|
23895
|
-
if (pendingHandles() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
24475
|
+
if (pendingHandles() === 0 && pendingRequests() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
23896
24476
|
const deadline = Date.now() + 1e3;
|
|
23897
24477
|
while (!this.router.activePorts(owner).length && Date.now() < deadline) {
|
|
23898
24478
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23899
24479
|
}
|
|
23900
24480
|
}
|
|
23901
|
-
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || readingStdin())) {
|
|
24481
|
+
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
|
|
23902
24482
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23903
24483
|
}
|
|
23904
24484
|
}
|
|
@@ -24559,17 +25139,18 @@ var Terminal = class {
|
|
|
24559
25139
|
// ── key handling ──────────────────────────────────────────────────────────
|
|
24560
25140
|
key(ch) {
|
|
24561
25141
|
if (this.running) {
|
|
24562
|
-
|
|
25142
|
+
const raw = this.currentStdin?.rawMode === true;
|
|
25143
|
+
if (ch === CTRL_C && !raw) {
|
|
24563
25144
|
this.session.proc.deliver("SIGINT");
|
|
24564
25145
|
this.write("^C\r\n");
|
|
24565
25146
|
return;
|
|
24566
25147
|
}
|
|
24567
|
-
if (ch === CTRL_D) {
|
|
25148
|
+
if (ch === CTRL_D && !raw) {
|
|
24568
25149
|
this.currentStdin?.end();
|
|
24569
25150
|
return;
|
|
24570
25151
|
}
|
|
24571
|
-
if (!
|
|
24572
|
-
this.currentStdin?.write(ch === "\r" ? "\n" : ch);
|
|
25152
|
+
if (!raw) this.write(ch === "\r" ? "\r\n" : ch);
|
|
25153
|
+
this.currentStdin?.write(!raw && ch === "\r" ? "\n" : ch);
|
|
24573
25154
|
return;
|
|
24574
25155
|
}
|
|
24575
25156
|
if (this.escapeBuffer !== "") {
|