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.cjs
CHANGED
|
@@ -7349,15 +7349,15 @@ var Parser = class {
|
|
|
7349
7349
|
if (this.isWord("-p")) this.next();
|
|
7350
7350
|
}
|
|
7351
7351
|
}
|
|
7352
|
-
const
|
|
7352
|
+
const commands12 = [this.parseCommand()];
|
|
7353
7353
|
const stderrToo = [];
|
|
7354
7354
|
while (this.isOp("|") || this.isOp("|&")) {
|
|
7355
7355
|
stderrToo.push(this.next().value === "|&");
|
|
7356
7356
|
this.skipNewlines();
|
|
7357
|
-
|
|
7357
|
+
commands12.push(this.parseCommand());
|
|
7358
7358
|
}
|
|
7359
|
-
if (
|
|
7360
|
-
return { type: "pipeline", commands:
|
|
7359
|
+
if (commands12.length === 1 && !negated && !timed) return commands12[0];
|
|
7360
|
+
return { type: "pipeline", commands: commands12, negated, stderrToo, timed };
|
|
7361
7361
|
}
|
|
7362
7362
|
// ── commands ─────────────────────────────────────────────────────────────
|
|
7363
7363
|
parseCommand() {
|
|
@@ -16980,6 +16980,145 @@ var helpCmd = defineCommand({
|
|
|
16980
16980
|
});
|
|
16981
16981
|
var commands10 = [man, whatis, apropos, less, helpCmd];
|
|
16982
16982
|
|
|
16983
|
+
// src/bin/clipboard.ts
|
|
16984
|
+
init_path();
|
|
16985
|
+
var CLIPBOARD_DIR = "/run/clipboard";
|
|
16986
|
+
function selectionPath(selection) {
|
|
16987
|
+
return join(CLIPBOARD_DIR, selection);
|
|
16988
|
+
}
|
|
16989
|
+
function readSelection(ctx, selection) {
|
|
16990
|
+
try {
|
|
16991
|
+
return ctx.vfs.readFile(selectionPath(selection), ctx.cred);
|
|
16992
|
+
} catch {
|
|
16993
|
+
return new Uint8Array();
|
|
16994
|
+
}
|
|
16995
|
+
}
|
|
16996
|
+
function writeSelection(ctx, selection, bytes2) {
|
|
16997
|
+
try {
|
|
16998
|
+
ctx.vfs.mkdir(CLIPBOARD_DIR, { recursive: true, mode: 511 });
|
|
16999
|
+
} catch {
|
|
17000
|
+
}
|
|
17001
|
+
ctx.vfs.writeFile(selectionPath(selection), bytes2, { privileged: true, mode: 438 });
|
|
17002
|
+
}
|
|
17003
|
+
var xsel = defineCommand({
|
|
17004
|
+
name: "xsel",
|
|
17005
|
+
summary: "access an X selection",
|
|
17006
|
+
usage: "xsel [--clipboard|--primary|--secondary] [--input|--output|--clear]",
|
|
17007
|
+
async run(ctx) {
|
|
17008
|
+
let selection = "primary";
|
|
17009
|
+
let mode = "output";
|
|
17010
|
+
for (const arg of ctx.args) {
|
|
17011
|
+
switch (arg) {
|
|
17012
|
+
case "-b":
|
|
17013
|
+
case "--clipboard":
|
|
17014
|
+
selection = "clipboard";
|
|
17015
|
+
break;
|
|
17016
|
+
case "-p":
|
|
17017
|
+
case "--primary":
|
|
17018
|
+
selection = "primary";
|
|
17019
|
+
break;
|
|
17020
|
+
case "-s":
|
|
17021
|
+
case "--secondary":
|
|
17022
|
+
selection = "secondary";
|
|
17023
|
+
break;
|
|
17024
|
+
case "-i":
|
|
17025
|
+
case "--input":
|
|
17026
|
+
case "-a":
|
|
17027
|
+
case "--append":
|
|
17028
|
+
mode = "input";
|
|
17029
|
+
break;
|
|
17030
|
+
case "-o":
|
|
17031
|
+
case "--output":
|
|
17032
|
+
mode = "output";
|
|
17033
|
+
break;
|
|
17034
|
+
case "-c":
|
|
17035
|
+
case "--clear":
|
|
17036
|
+
mode = "clear";
|
|
17037
|
+
break;
|
|
17038
|
+
}
|
|
17039
|
+
}
|
|
17040
|
+
if (mode === "clear") {
|
|
17041
|
+
writeSelection(ctx, selection, new Uint8Array());
|
|
17042
|
+
return 0;
|
|
17043
|
+
}
|
|
17044
|
+
if (mode === "input") {
|
|
17045
|
+
writeSelection(ctx, selection, await ctx.stdin.readAll());
|
|
17046
|
+
return 0;
|
|
17047
|
+
}
|
|
17048
|
+
ctx.write(readSelection(ctx, selection));
|
|
17049
|
+
return 0;
|
|
17050
|
+
}
|
|
17051
|
+
});
|
|
17052
|
+
var xclip = defineCommand({
|
|
17053
|
+
name: "xclip",
|
|
17054
|
+
summary: "access an X selection",
|
|
17055
|
+
usage: "xclip [-selection clipboard|primary|secondary] [-i|-o]",
|
|
17056
|
+
async run(ctx) {
|
|
17057
|
+
let selection = "primary";
|
|
17058
|
+
let mode = "input";
|
|
17059
|
+
const args = ctx.args;
|
|
17060
|
+
for (let index = 0; index < args.length; index++) {
|
|
17061
|
+
const arg = args[index];
|
|
17062
|
+
if (arg === "-selection" || arg === "-sel" || arg === "--selection") {
|
|
17063
|
+
const value = args[++index];
|
|
17064
|
+
if (value === "clipboard" || value === "primary" || value === "secondary") selection = value;
|
|
17065
|
+
continue;
|
|
17066
|
+
}
|
|
17067
|
+
if (arg === "-i" || arg === "-in") mode = "input";
|
|
17068
|
+
else if (arg === "-o" || arg === "-out") mode = "output";
|
|
17069
|
+
}
|
|
17070
|
+
if (mode === "input") {
|
|
17071
|
+
writeSelection(ctx, selection, await ctx.stdin.readAll());
|
|
17072
|
+
return 0;
|
|
17073
|
+
}
|
|
17074
|
+
ctx.write(readSelection(ctx, selection));
|
|
17075
|
+
return 0;
|
|
17076
|
+
}
|
|
17077
|
+
});
|
|
17078
|
+
var pbcopy = defineCommand({
|
|
17079
|
+
name: "pbcopy",
|
|
17080
|
+
summary: "copy standard input to the clipboard",
|
|
17081
|
+
usage: "pbcopy",
|
|
17082
|
+
async run(ctx) {
|
|
17083
|
+
writeSelection(ctx, "clipboard", await ctx.stdin.readAll());
|
|
17084
|
+
return 0;
|
|
17085
|
+
}
|
|
17086
|
+
});
|
|
17087
|
+
var pbpaste = defineCommand({
|
|
17088
|
+
name: "pbpaste",
|
|
17089
|
+
summary: "write the clipboard to standard output",
|
|
17090
|
+
usage: "pbpaste",
|
|
17091
|
+
run(ctx) {
|
|
17092
|
+
ctx.write(readSelection(ctx, "clipboard"));
|
|
17093
|
+
return 0;
|
|
17094
|
+
}
|
|
17095
|
+
});
|
|
17096
|
+
var wlCopy = defineCommand({
|
|
17097
|
+
name: "wl-copy",
|
|
17098
|
+
summary: "copy standard input to the Wayland clipboard",
|
|
17099
|
+
usage: "wl-copy [--primary] [text...]",
|
|
17100
|
+
async run(ctx) {
|
|
17101
|
+
const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
|
|
17102
|
+
const operands = ctx.args.filter((arg) => !arg.startsWith("-"));
|
|
17103
|
+
const bytes2 = operands.length ? new TextEncoder().encode(operands.join(" ")) : await ctx.stdin.readAll();
|
|
17104
|
+
writeSelection(ctx, selection, bytes2);
|
|
17105
|
+
return 0;
|
|
17106
|
+
}
|
|
17107
|
+
});
|
|
17108
|
+
var wlPaste = defineCommand({
|
|
17109
|
+
name: "wl-paste",
|
|
17110
|
+
summary: "write the Wayland clipboard to standard output",
|
|
17111
|
+
usage: "wl-paste [--primary] [-n]",
|
|
17112
|
+
run(ctx) {
|
|
17113
|
+
const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
|
|
17114
|
+
const bytes2 = readSelection(ctx, selection);
|
|
17115
|
+
ctx.write(bytes2);
|
|
17116
|
+
if (!ctx.args.includes("-n") && !ctx.args.includes("--no-newline")) ctx.write("\n");
|
|
17117
|
+
return 0;
|
|
17118
|
+
}
|
|
17119
|
+
});
|
|
17120
|
+
var commands11 = [xsel, xclip, pbcopy, pbpaste, wlCopy, wlPaste];
|
|
17121
|
+
|
|
16983
17122
|
// src/runtime/node.ts
|
|
16984
17123
|
init_path();
|
|
16985
17124
|
var NODE_VERSION = "v22.12.0";
|
|
@@ -19336,6 +19475,7 @@ function allCommands() {
|
|
|
19336
19475
|
...commands8,
|
|
19337
19476
|
...commands9,
|
|
19338
19477
|
...commands10,
|
|
19478
|
+
...commands11,
|
|
19339
19479
|
...nodeCommands(),
|
|
19340
19480
|
...pythonCommands(),
|
|
19341
19481
|
...ffmpegCommands(),
|
|
@@ -19632,6 +19772,13 @@ var KernelChildProcess = class {
|
|
|
19632
19772
|
} catch {
|
|
19633
19773
|
}
|
|
19634
19774
|
}
|
|
19775
|
+
/** Signal EOF, so a child reading stdin to the end can finish. */
|
|
19776
|
+
endStdin() {
|
|
19777
|
+
try {
|
|
19778
|
+
this.stdin.end();
|
|
19779
|
+
} catch {
|
|
19780
|
+
}
|
|
19781
|
+
}
|
|
19635
19782
|
kill(signal = "SIGTERM") {
|
|
19636
19783
|
if (this.process) {
|
|
19637
19784
|
this.process.deliver(signal);
|
|
@@ -20543,6 +20690,55 @@ function splitSpecifier(specifier) {
|
|
|
20543
20690
|
return { name: parts.slice(0, size).join("/"), subpath: parts.slice(size).join("/") };
|
|
20544
20691
|
}
|
|
20545
20692
|
|
|
20693
|
+
// src/runtime/readable-from.ts
|
|
20694
|
+
function createReadableFrom(Readable) {
|
|
20695
|
+
return function from(source, options = {}) {
|
|
20696
|
+
if (source && typeof source.pipe === "function") return source;
|
|
20697
|
+
const iterator = source && typeof source[Symbol.asyncIterator] === "function" ? source[Symbol.asyncIterator]() : source && typeof source[Symbol.iterator] === "function" ? source[Symbol.iterator]() : (function* () {
|
|
20698
|
+
yield source;
|
|
20699
|
+
})();
|
|
20700
|
+
let reading = false;
|
|
20701
|
+
const stream = new Readable({
|
|
20702
|
+
...options,
|
|
20703
|
+
objectMode: options.objectMode ?? false,
|
|
20704
|
+
read() {
|
|
20705
|
+
if (reading) return;
|
|
20706
|
+
reading = true;
|
|
20707
|
+
void (async () => {
|
|
20708
|
+
try {
|
|
20709
|
+
for (; ; ) {
|
|
20710
|
+
const next = await iterator.next();
|
|
20711
|
+
if (next.done) {
|
|
20712
|
+
stream.push(null);
|
|
20713
|
+
return;
|
|
20714
|
+
}
|
|
20715
|
+
const value = next.value;
|
|
20716
|
+
if (!stream.push(value === void 0 ? null : value)) return;
|
|
20717
|
+
}
|
|
20718
|
+
} catch (error) {
|
|
20719
|
+
stream.destroy(error);
|
|
20720
|
+
} finally {
|
|
20721
|
+
reading = false;
|
|
20722
|
+
}
|
|
20723
|
+
})();
|
|
20724
|
+
},
|
|
20725
|
+
destroy(error, callback) {
|
|
20726
|
+
void (async () => {
|
|
20727
|
+
try {
|
|
20728
|
+
await iterator.return?.();
|
|
20729
|
+
} catch {
|
|
20730
|
+
}
|
|
20731
|
+
callback(error);
|
|
20732
|
+
})();
|
|
20733
|
+
}
|
|
20734
|
+
});
|
|
20735
|
+
return stream;
|
|
20736
|
+
};
|
|
20737
|
+
}
|
|
20738
|
+
function installReadableFrom(streamModule5) {
|
|
20739
|
+
streamModule5.Readable.from = createReadableFrom(streamModule5.Readable);
|
|
20740
|
+
}
|
|
20741
|
+
|
|
20546
20742
|
// src/runtime/util-module.ts
|
|
20547
20743
|
var customInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
20548
20744
|
var promisifyCustom = /* @__PURE__ */ Symbol.for("nodejs.util.promisify.custom");
|
|
@@ -21430,6 +21626,10 @@ var VirtualHttpRouter = class {
|
|
|
21430
21626
|
unregister(port, server) {
|
|
21431
21627
|
if (this.servers.get(port)?.server === server) this.servers.delete(port);
|
|
21432
21628
|
}
|
|
21629
|
+
/** Whether anything in this container is listening on `port`. */
|
|
21630
|
+
activePortsIncludes(port) {
|
|
21631
|
+
return this.servers.has(port);
|
|
21632
|
+
}
|
|
21433
21633
|
activePorts(owner) {
|
|
21434
21634
|
return [...this.servers].filter(([, item]) => owner === void 0 || item.owner === owner).map(([port]) => port).sort((a, b) => a - b);
|
|
21435
21635
|
}
|
|
@@ -21453,13 +21653,269 @@ var VirtualHttpRouter = class {
|
|
|
21453
21653
|
}
|
|
21454
21654
|
}
|
|
21455
21655
|
};
|
|
21456
|
-
|
|
21656
|
+
var VirtualClientResponse = class extends streamModule4__default.default.Readable {
|
|
21657
|
+
constructor(statusCode, statusMessage, headers, body) {
|
|
21658
|
+
super();
|
|
21659
|
+
this.statusCode = statusCode;
|
|
21660
|
+
this.statusMessage = statusMessage;
|
|
21661
|
+
this.headers = headers;
|
|
21662
|
+
this.rawHeaders = Object.entries(headers).flatMap(([key, value]) => [key, value]);
|
|
21663
|
+
if (body.length) this.push(Buffer2.from(body));
|
|
21664
|
+
this.push(null);
|
|
21665
|
+
this.complete = true;
|
|
21666
|
+
}
|
|
21667
|
+
statusCode;
|
|
21668
|
+
statusMessage;
|
|
21669
|
+
headers;
|
|
21670
|
+
httpVersion = "1.1";
|
|
21671
|
+
httpVersionMajor = 1;
|
|
21672
|
+
httpVersionMinor = 1;
|
|
21673
|
+
socket = socketStub();
|
|
21674
|
+
connection = this.socket;
|
|
21675
|
+
rawHeaders;
|
|
21676
|
+
complete = false;
|
|
21677
|
+
_read() {
|
|
21678
|
+
}
|
|
21679
|
+
setTimeout(_milliseconds, callback) {
|
|
21680
|
+
if (callback) this.once("timeout", callback);
|
|
21681
|
+
return this;
|
|
21682
|
+
}
|
|
21683
|
+
};
|
|
21684
|
+
function resolveTarget(input, overrides, defaultProtocol) {
|
|
21685
|
+
const options = {};
|
|
21686
|
+
if (typeof input === "string" || input instanceof URL) {
|
|
21687
|
+
const url = new URL(String(input));
|
|
21688
|
+
options.protocol = url.protocol;
|
|
21689
|
+
options.hostname = url.hostname;
|
|
21690
|
+
if (url.port) options.port = Number(url.port);
|
|
21691
|
+
options.path = `${url.pathname}${url.search}`;
|
|
21692
|
+
if (url.username || url.password) options.auth = `${url.username}:${url.password}`;
|
|
21693
|
+
} else if (input && typeof input === "object") {
|
|
21694
|
+
Object.assign(options, input);
|
|
21695
|
+
}
|
|
21696
|
+
if (overrides) Object.assign(options, overrides);
|
|
21697
|
+
const protocol = String(options.protocol ?? defaultProtocol).replace(/:?$/, ":");
|
|
21698
|
+
const headers = {};
|
|
21699
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
21700
|
+
if (value === void 0 || value === null) continue;
|
|
21701
|
+
headers[String(name)] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
21702
|
+
}
|
|
21703
|
+
if (options.auth && headers.authorization === void 0) {
|
|
21704
|
+
headers.authorization = `Basic ${Buffer2.from(String(options.auth)).toString("base64")}`;
|
|
21705
|
+
}
|
|
21706
|
+
const rawHost = String(options.hostname ?? options.host ?? "localhost");
|
|
21707
|
+
const hostMatch = /^(\[[^\]]*\]|[^:]*)(?::(\d+))?$/.exec(rawHost);
|
|
21708
|
+
const hostname = (hostMatch?.[1] ?? rawHost).replace(/^\[|\]$/g, "");
|
|
21709
|
+
const explicitPort = options.port ?? hostMatch?.[2];
|
|
21710
|
+
const port = explicitPort === void 0 || explicitPort === null || explicitPort === "" || Number.isNaN(Number(explicitPort)) ? protocol === "https:" ? 443 : 80 : Number(explicitPort);
|
|
21711
|
+
return {
|
|
21712
|
+
protocol,
|
|
21713
|
+
hostname,
|
|
21714
|
+
port,
|
|
21715
|
+
path: String(options.path ?? "/"),
|
|
21716
|
+
method: String(options.method ?? "GET").toUpperCase(),
|
|
21717
|
+
headers
|
|
21718
|
+
};
|
|
21719
|
+
}
|
|
21720
|
+
function isLoopback(hostname) {
|
|
21721
|
+
return hostname === "localhost" || hostname === "0.0.0.0" || hostname === "::1" || hostname === "::" || hostname.startsWith("127.") || hostname.endsWith(".localhost");
|
|
21722
|
+
}
|
|
21723
|
+
var VirtualClientRequest = class extends streamModule4__default.default.Writable {
|
|
21724
|
+
constructor(target, router, fetchImpl, trackRequest) {
|
|
21725
|
+
super();
|
|
21726
|
+
this.target = target;
|
|
21727
|
+
this.router = router;
|
|
21728
|
+
this.fetchImpl = fetchImpl;
|
|
21729
|
+
this.trackRequest = trackRequest;
|
|
21730
|
+
for (const [name, value] of Object.entries(target.headers)) this.setHeader(name, value);
|
|
21731
|
+
}
|
|
21732
|
+
target;
|
|
21733
|
+
router;
|
|
21734
|
+
fetchImpl;
|
|
21735
|
+
trackRequest;
|
|
21736
|
+
socket = socketStub();
|
|
21737
|
+
connection = this.socket;
|
|
21738
|
+
chunks = [];
|
|
21739
|
+
headerMap = /* @__PURE__ */ new Map();
|
|
21740
|
+
dispatched = false;
|
|
21741
|
+
destroyedByUser = false;
|
|
21742
|
+
timer;
|
|
21743
|
+
aborted = false;
|
|
21744
|
+
finished = false;
|
|
21745
|
+
reusedSocket = false;
|
|
21746
|
+
get method() {
|
|
21747
|
+
return this.target.method;
|
|
21748
|
+
}
|
|
21749
|
+
get path() {
|
|
21750
|
+
return this.target.path;
|
|
21751
|
+
}
|
|
21752
|
+
get host() {
|
|
21753
|
+
return this.target.hostname;
|
|
21754
|
+
}
|
|
21755
|
+
get protocol() {
|
|
21756
|
+
return this.target.protocol;
|
|
21757
|
+
}
|
|
21758
|
+
setHeader(name, value) {
|
|
21759
|
+
validateHeaderName(name);
|
|
21760
|
+
validateHeaderValue(name, value);
|
|
21761
|
+
this.headerMap.set(name.toLowerCase(), { name, value: Array.isArray(value) ? [...value].map(String).join(", ") : String(value) });
|
|
21762
|
+
return this;
|
|
21763
|
+
}
|
|
21764
|
+
getHeader(name) {
|
|
21765
|
+
return this.headerMap.get(name.toLowerCase())?.value;
|
|
21766
|
+
}
|
|
21767
|
+
getHeaders() {
|
|
21768
|
+
return Object.fromEntries([...this.headerMap].map(([key, entry]) => [key, entry.value]));
|
|
21769
|
+
}
|
|
21770
|
+
getHeaderNames() {
|
|
21771
|
+
return [...this.headerMap.keys()];
|
|
21772
|
+
}
|
|
21773
|
+
hasHeader(name) {
|
|
21774
|
+
return this.headerMap.has(name.toLowerCase());
|
|
21775
|
+
}
|
|
21776
|
+
removeHeader(name) {
|
|
21777
|
+
this.headerMap.delete(name.toLowerCase());
|
|
21778
|
+
}
|
|
21779
|
+
flushHeaders() {
|
|
21780
|
+
}
|
|
21781
|
+
setNoDelay() {
|
|
21782
|
+
}
|
|
21783
|
+
setSocketKeepAlive() {
|
|
21784
|
+
}
|
|
21785
|
+
ref() {
|
|
21786
|
+
return this;
|
|
21787
|
+
}
|
|
21788
|
+
unref() {
|
|
21789
|
+
return this;
|
|
21790
|
+
}
|
|
21791
|
+
setTimeout(milliseconds, callback) {
|
|
21792
|
+
if (callback) this.once("timeout", callback);
|
|
21793
|
+
clearTimeout(this.timer);
|
|
21794
|
+
this.timer = setTimeout(() => this.emit("timeout"), milliseconds);
|
|
21795
|
+
return this;
|
|
21796
|
+
}
|
|
21797
|
+
abort() {
|
|
21798
|
+
this.destroyRequest();
|
|
21799
|
+
}
|
|
21800
|
+
destroy(error) {
|
|
21801
|
+
this.destroyRequest(error);
|
|
21802
|
+
return this;
|
|
21803
|
+
}
|
|
21804
|
+
destroyRequest(error) {
|
|
21805
|
+
if (this.destroyedByUser) return;
|
|
21806
|
+
this.destroyedByUser = true;
|
|
21807
|
+
this.aborted = true;
|
|
21808
|
+
clearTimeout(this.timer);
|
|
21809
|
+
this.emit("abort");
|
|
21810
|
+
if (error) this.emit("error", error);
|
|
21811
|
+
this.emit("close");
|
|
21812
|
+
}
|
|
21813
|
+
_write(chunk, encoding, callback) {
|
|
21814
|
+
this.chunks.push(Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk, encoding));
|
|
21815
|
+
callback();
|
|
21816
|
+
}
|
|
21817
|
+
_final(callback) {
|
|
21818
|
+
this.finished = true;
|
|
21819
|
+
callback();
|
|
21820
|
+
void this.dispatch();
|
|
21821
|
+
}
|
|
21822
|
+
async dispatch() {
|
|
21823
|
+
if (this.dispatched || this.destroyedByUser) return;
|
|
21824
|
+
this.dispatched = true;
|
|
21825
|
+
const body = Buffer2.concat(this.chunks);
|
|
21826
|
+
const release = this.trackRequest?.();
|
|
21827
|
+
let released = false;
|
|
21828
|
+
const untrack = () => {
|
|
21829
|
+
if (released || !release) return;
|
|
21830
|
+
released = true;
|
|
21831
|
+
release();
|
|
21832
|
+
};
|
|
21833
|
+
let settled = false;
|
|
21834
|
+
try {
|
|
21835
|
+
const response = this.router.activePortsIncludes(this.target.port) && isLoopback(this.target.hostname) ? await this.viaRouter(body) : await this.viaFetch(body);
|
|
21836
|
+
if (this.destroyedByUser) return;
|
|
21837
|
+
clearTimeout(this.timer);
|
|
21838
|
+
settled = true;
|
|
21839
|
+
response.once("end", untrack);
|
|
21840
|
+
response.once("close", untrack);
|
|
21841
|
+
response.once("error", untrack);
|
|
21842
|
+
this.emit("response", response);
|
|
21843
|
+
queueMicrotask(() => {
|
|
21844
|
+
if (this.listenerCount("response") === 0) response.resume();
|
|
21845
|
+
});
|
|
21846
|
+
} catch (error) {
|
|
21847
|
+
clearTimeout(this.timer);
|
|
21848
|
+
if (this.destroyedByUser) return;
|
|
21849
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
21850
|
+
if (!("code" in failure)) Object.assign(failure, { code: "ECONNREFUSED" });
|
|
21851
|
+
this.emit("error", failure);
|
|
21852
|
+
} finally {
|
|
21853
|
+
if (!settled) untrack();
|
|
21854
|
+
}
|
|
21855
|
+
}
|
|
21856
|
+
async viaRouter(body) {
|
|
21857
|
+
const result = await this.router.request(this.target.port, {
|
|
21858
|
+
method: this.target.method,
|
|
21859
|
+
path: this.target.path,
|
|
21860
|
+
headers: this.getHeaders(),
|
|
21861
|
+
body: body.length ? new Uint8Array(body) : null
|
|
21862
|
+
});
|
|
21863
|
+
const body_ = result.body;
|
|
21864
|
+
const bytes2 = typeof body_ === "string" ? new TextEncoder().encode(body_) : body_ instanceof ArrayBuffer ? new Uint8Array(body_) : body_ ?? new Uint8Array();
|
|
21865
|
+
const status = result.statusCode ?? 200;
|
|
21866
|
+
return new VirtualClientResponse(status, result.statusMessage ?? STATUS_CODES[status] ?? "", lowercaseHeaders(result.headers), bytes2);
|
|
21867
|
+
}
|
|
21868
|
+
async viaFetch(body) {
|
|
21869
|
+
const fetchImpl = this.fetchImpl ?? globalThis.fetch;
|
|
21870
|
+
if (typeof fetchImpl !== "function") {
|
|
21871
|
+
throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${this.target.hostname}`), { code: "ENOTFOUND" });
|
|
21872
|
+
}
|
|
21873
|
+
const portSuffix = this.target.protocol === "https:" && this.target.port === 443 || this.target.protocol === "http:" && this.target.port === 80 ? "" : `:${this.target.port}`;
|
|
21874
|
+
const url = `${this.target.protocol}//${this.target.hostname}${portSuffix}${this.target.path}`;
|
|
21875
|
+
const bodyless = this.target.method === "GET" || this.target.method === "HEAD";
|
|
21876
|
+
const headers = this.getHeaders();
|
|
21877
|
+
delete headers.host;
|
|
21878
|
+
delete headers.connection;
|
|
21879
|
+
delete headers["content-length"];
|
|
21880
|
+
const response = await fetchImpl(url, {
|
|
21881
|
+
method: this.target.method,
|
|
21882
|
+
headers,
|
|
21883
|
+
...bodyless || body.length === 0 ? {} : { body: new Uint8Array(body) },
|
|
21884
|
+
redirect: "follow"
|
|
21885
|
+
});
|
|
21886
|
+
const received = {};
|
|
21887
|
+
response.headers.forEach((value, key) => {
|
|
21888
|
+
received[key.toLowerCase()] = value;
|
|
21889
|
+
});
|
|
21890
|
+
const bytes2 = new Uint8Array(await response.arrayBuffer());
|
|
21891
|
+
return new VirtualClientResponse(response.status, response.statusText, received, bytes2);
|
|
21892
|
+
}
|
|
21893
|
+
};
|
|
21894
|
+
function lowercaseHeaders(headers) {
|
|
21895
|
+
return Object.fromEntries(Object.entries(headers ?? {}).map(([key, value]) => [key.toLowerCase(), String(value)]));
|
|
21896
|
+
}
|
|
21897
|
+
function createHttpModule(router, owner, options = {}, defaultProtocol = "http:") {
|
|
21457
21898
|
const createServer = (listener) => new VirtualHttpServer(router, owner, listener);
|
|
21458
|
-
const
|
|
21899
|
+
const request = (input, second, third) => {
|
|
21900
|
+
const overrides = second && typeof second === "object" && !(second instanceof Function) ? second : void 0;
|
|
21901
|
+
const callback = [second, third].find((value) => typeof value === "function");
|
|
21902
|
+
const req = new VirtualClientRequest(resolveTarget(input, overrides, defaultProtocol), router, options.fetch, options.trackRequest);
|
|
21903
|
+
if (callback) req.on("response", callback);
|
|
21904
|
+
return req;
|
|
21905
|
+
};
|
|
21906
|
+
const get = (input, second, third) => {
|
|
21907
|
+
const req = request(input, second, third);
|
|
21908
|
+
req.end();
|
|
21909
|
+
return req;
|
|
21910
|
+
};
|
|
21911
|
+
return {
|
|
21459
21912
|
createServer,
|
|
21913
|
+
request,
|
|
21914
|
+
get,
|
|
21460
21915
|
Server: VirtualHttpServer,
|
|
21461
21916
|
ServerResponse: VirtualServerResponse,
|
|
21462
21917
|
IncomingMessage: VirtualIncomingMessage,
|
|
21918
|
+
ClientRequest: VirtualClientRequest,
|
|
21463
21919
|
METHODS,
|
|
21464
21920
|
STATUS_CODES,
|
|
21465
21921
|
maxHeaderSize: 16 * 1024,
|
|
@@ -21469,10 +21925,6 @@ function createHttpModule(router, owner) {
|
|
|
21469
21925
|
Agent: class Agent {
|
|
21470
21926
|
}
|
|
21471
21927
|
};
|
|
21472
|
-
return { ...module, request: unsupportedClient, get: unsupportedClient };
|
|
21473
|
-
}
|
|
21474
|
-
function unsupportedClient() {
|
|
21475
|
-
throw Object.assign(new Error("http client requests are not implemented yet"), { code: "ERR_NOT_IMPLEMENTED" });
|
|
21476
21928
|
}
|
|
21477
21929
|
function validateHeaderName(name) {
|
|
21478
21930
|
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" });
|
|
@@ -21612,6 +22064,13 @@ var ChildProcess = class extends EventEmitter4__default.default {
|
|
|
21612
22064
|
} catch {
|
|
21613
22065
|
}
|
|
21614
22066
|
done();
|
|
22067
|
+
},
|
|
22068
|
+
final: (done) => {
|
|
22069
|
+
try {
|
|
22070
|
+
handle.endStdin?.();
|
|
22071
|
+
} catch {
|
|
22072
|
+
}
|
|
22073
|
+
done();
|
|
21615
22074
|
}
|
|
21616
22075
|
});
|
|
21617
22076
|
this.stdio = [this.stdin, this.stdout, this.stderr];
|
|
@@ -21850,7 +22309,7 @@ function emitKeypressEvents(stream) {
|
|
|
21850
22309
|
}
|
|
21851
22310
|
});
|
|
21852
22311
|
}
|
|
21853
|
-
function createReadlineModule(defaultInput) {
|
|
22312
|
+
function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
21854
22313
|
class Interface extends EventEmitter4__default.default {
|
|
21855
22314
|
constructor(input, output, terminal = false) {
|
|
21856
22315
|
super();
|
|
@@ -21861,6 +22320,14 @@ function createReadlineModule(defaultInput) {
|
|
|
21861
22320
|
if (terminal) {
|
|
21862
22321
|
emitKeypressEvents(input);
|
|
21863
22322
|
input?.on?.("keypress", this.onTerminalKeypress);
|
|
22323
|
+
if (typeof input?.setRawMode === "function") {
|
|
22324
|
+
try {
|
|
22325
|
+
input.setRawMode(true);
|
|
22326
|
+
this.ownsRawMode = true;
|
|
22327
|
+
} catch {
|
|
22328
|
+
}
|
|
22329
|
+
}
|
|
22330
|
+
input?.resume?.();
|
|
21864
22331
|
} else {
|
|
21865
22332
|
input?.on?.("data", (chunk) => this.receive(String(chunk)));
|
|
21866
22333
|
}
|
|
@@ -21872,6 +22339,10 @@ function createReadlineModule(defaultInput) {
|
|
|
21872
22339
|
buffer = "";
|
|
21873
22340
|
pending = [];
|
|
21874
22341
|
lines = [];
|
|
22342
|
+
/** Set while `question` is waiting, so the echoed line carries the query. */
|
|
22343
|
+
questionPrompt = null;
|
|
22344
|
+
/** Raw mode is only ours to restore if we were the one to enable it. */
|
|
22345
|
+
ownsRawMode = false;
|
|
21875
22346
|
line = "";
|
|
21876
22347
|
cursor = 0;
|
|
21877
22348
|
terminal;
|
|
@@ -21879,20 +22350,31 @@ function createReadlineModule(defaultInput) {
|
|
|
21879
22350
|
/** Split incoming data into lines, answering any waiting `question`. */
|
|
21880
22351
|
receive(text2) {
|
|
21881
22352
|
this.buffer += text2;
|
|
21882
|
-
let
|
|
21883
|
-
while (
|
|
21884
|
-
const line = this.buffer.slice(0,
|
|
21885
|
-
this.buffer = this.buffer.slice(
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
21889
|
-
|
|
21890
|
-
|
|
21891
|
-
|
|
21892
|
-
|
|
22353
|
+
let match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22354
|
+
while (match2) {
|
|
22355
|
+
const line = this.buffer.slice(0, match2.index);
|
|
22356
|
+
this.buffer = this.buffer.slice(match2.index + match2[0].length);
|
|
22357
|
+
this.deliver(line);
|
|
22358
|
+
match2 = /\r\n|\r|\n/.exec(this.buffer);
|
|
22359
|
+
}
|
|
22360
|
+
}
|
|
22361
|
+
/** Hand a completed line to whoever is waiting for it. */
|
|
22362
|
+
deliver(line) {
|
|
22363
|
+
const waiting = this.pending.shift();
|
|
22364
|
+
if (waiting) {
|
|
22365
|
+
this.questionPrompt = null;
|
|
22366
|
+
waiting(line);
|
|
22367
|
+
return;
|
|
21893
22368
|
}
|
|
22369
|
+
this.lines.push(line);
|
|
22370
|
+
this.emit("line", line);
|
|
21894
22371
|
}
|
|
21895
22372
|
question(query, callback) {
|
|
22373
|
+
if (this.terminal) {
|
|
22374
|
+
this.questionPrompt = query;
|
|
22375
|
+
this.line = "";
|
|
22376
|
+
this.cursor = 0;
|
|
22377
|
+
}
|
|
21896
22378
|
this.output?.write?.(query);
|
|
21897
22379
|
if (callback) {
|
|
21898
22380
|
this.pending.push(callback);
|
|
@@ -21907,6 +22389,9 @@ function createReadlineModule(defaultInput) {
|
|
|
21907
22389
|
setPrompt(text2) {
|
|
21908
22390
|
this.promptText = text2;
|
|
21909
22391
|
}
|
|
22392
|
+
getPrompt() {
|
|
22393
|
+
return this.promptText;
|
|
22394
|
+
}
|
|
21910
22395
|
pause() {
|
|
21911
22396
|
this.input?.pause?.();
|
|
21912
22397
|
return this;
|
|
@@ -21934,21 +22419,48 @@ function createReadlineModule(defaultInput) {
|
|
|
21934
22419
|
if (text2) {
|
|
21935
22420
|
this.line = this.line.slice(0, this.cursor) + text2 + this.line.slice(this.cursor);
|
|
21936
22421
|
this.cursor += text2.length;
|
|
22422
|
+
this.refresh();
|
|
21937
22423
|
}
|
|
21938
22424
|
}
|
|
21939
22425
|
getCursorPos() {
|
|
21940
|
-
return { rows: 0, cols: this.cursor + this.
|
|
22426
|
+
return { rows: 0, cols: this.cursor + this.currentPrompt().length };
|
|
21941
22427
|
}
|
|
21942
22428
|
close() {
|
|
21943
22429
|
if (this.closed) return;
|
|
21944
22430
|
this.closed = true;
|
|
21945
22431
|
if (this.terminal) {
|
|
21946
22432
|
this.input?.off?.("keypress", this.onTerminalKeypress);
|
|
22433
|
+
if (this.ownsRawMode) {
|
|
22434
|
+
this.ownsRawMode = false;
|
|
22435
|
+
try {
|
|
22436
|
+
this.input?.setRawMode?.(false);
|
|
22437
|
+
} catch {
|
|
22438
|
+
}
|
|
22439
|
+
}
|
|
21947
22440
|
this.input?.pause?.();
|
|
21948
22441
|
}
|
|
21949
22442
|
for (const waiting of this.pending.splice(0)) waiting("");
|
|
21950
22443
|
this.emit("close");
|
|
21951
22444
|
}
|
|
22445
|
+
/** The text shown to the left of the edited line. */
|
|
22446
|
+
currentPrompt() {
|
|
22447
|
+
return this.questionPrompt ?? this.promptText;
|
|
22448
|
+
}
|
|
22449
|
+
/**
|
|
22450
|
+
* Repaint the edited line.
|
|
22451
|
+
*
|
|
22452
|
+
* In raw mode nothing echoes on its own, so an Interface that does not do
|
|
22453
|
+
* this leaves the user typing blind. Libraries that draw their own frame
|
|
22454
|
+
* (clack, inquirer) simply overwrite this, exactly as they do on Node.
|
|
22455
|
+
*/
|
|
22456
|
+
refresh() {
|
|
22457
|
+
if (!this.terminal) return;
|
|
22458
|
+
const prompt = this.currentPrompt();
|
|
22459
|
+
let text2 = `\r\x1B[0K${prompt}${this.line}`;
|
|
22460
|
+
const back = this.line.length - this.cursor;
|
|
22461
|
+
if (back > 0) text2 += `\x1B[${back}D`;
|
|
22462
|
+
this.output?.write?.(text2);
|
|
22463
|
+
}
|
|
21952
22464
|
edit(sequence, key) {
|
|
21953
22465
|
if (this.closed) return;
|
|
21954
22466
|
const name = key.name;
|
|
@@ -21956,48 +22468,62 @@ function createReadlineModule(defaultInput) {
|
|
|
21956
22468
|
const value = this.line;
|
|
21957
22469
|
this.line = "";
|
|
21958
22470
|
this.cursor = 0;
|
|
21959
|
-
this.
|
|
22471
|
+
this.output?.write?.("\r\n");
|
|
22472
|
+
this.deliver(value);
|
|
21960
22473
|
return;
|
|
21961
22474
|
}
|
|
21962
22475
|
if (name === "left") {
|
|
21963
22476
|
this.cursor = Math.max(0, this.cursor - 1);
|
|
22477
|
+
this.refresh();
|
|
21964
22478
|
return;
|
|
21965
22479
|
}
|
|
21966
22480
|
if (name === "right") {
|
|
21967
22481
|
this.cursor = Math.min(this.line.length, this.cursor + 1);
|
|
22482
|
+
this.refresh();
|
|
21968
22483
|
return;
|
|
21969
22484
|
}
|
|
21970
22485
|
if (name === "home" || key.ctrl && name === "a") {
|
|
21971
22486
|
this.cursor = 0;
|
|
22487
|
+
this.refresh();
|
|
21972
22488
|
return;
|
|
21973
22489
|
}
|
|
21974
22490
|
if (name === "end" || key.ctrl && name === "e") {
|
|
21975
22491
|
this.cursor = this.line.length;
|
|
22492
|
+
this.refresh();
|
|
21976
22493
|
return;
|
|
21977
22494
|
}
|
|
21978
22495
|
if (name === "backspace" || key.ctrl && name === "h") {
|
|
21979
22496
|
if (this.cursor > 0) {
|
|
21980
22497
|
this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
|
|
21981
22498
|
this.cursor--;
|
|
22499
|
+
this.refresh();
|
|
21982
22500
|
}
|
|
21983
22501
|
return;
|
|
21984
22502
|
}
|
|
21985
22503
|
if (name === "delete") {
|
|
21986
|
-
if (this.cursor < this.line.length)
|
|
22504
|
+
if (this.cursor < this.line.length) {
|
|
22505
|
+
this.line = this.line.slice(0, this.cursor) + this.line.slice(this.cursor + 1);
|
|
22506
|
+
this.refresh();
|
|
22507
|
+
}
|
|
21987
22508
|
return;
|
|
21988
22509
|
}
|
|
21989
22510
|
if (key.ctrl && name === "u") {
|
|
21990
22511
|
this.line = this.line.slice(this.cursor);
|
|
21991
22512
|
this.cursor = 0;
|
|
22513
|
+
this.refresh();
|
|
21992
22514
|
return;
|
|
21993
22515
|
}
|
|
21994
22516
|
if (key.ctrl && name === "k") {
|
|
21995
22517
|
this.line = this.line.slice(0, this.cursor);
|
|
22518
|
+
this.refresh();
|
|
21996
22519
|
return;
|
|
21997
22520
|
}
|
|
21998
22521
|
if (key.ctrl || key.meta || sequence.length !== 1 || sequence < " ") return;
|
|
22522
|
+
const atEnd = this.cursor === this.line.length;
|
|
21999
22523
|
this.line = this.line.slice(0, this.cursor) + sequence + this.line.slice(this.cursor);
|
|
22000
22524
|
this.cursor += sequence.length;
|
|
22525
|
+
if (atEnd) this.output?.write?.(sequence);
|
|
22526
|
+
else this.refresh();
|
|
22001
22527
|
}
|
|
22002
22528
|
async *[Symbol.asyncIterator]() {
|
|
22003
22529
|
while (!this.closed || this.lines.length) {
|
|
@@ -22027,13 +22553,23 @@ function createReadlineModule(defaultInput) {
|
|
|
22027
22553
|
}
|
|
22028
22554
|
}
|
|
22029
22555
|
}
|
|
22556
|
+
const isTerminal = (options, output) => {
|
|
22557
|
+
if (typeof options?.terminal === "boolean") return options.terminal;
|
|
22558
|
+
return Boolean(output?.isTTY);
|
|
22559
|
+
};
|
|
22030
22560
|
const createInterface = (options, output) => {
|
|
22031
22561
|
if (options && typeof options === "object" && !options.on) {
|
|
22032
|
-
const
|
|
22562
|
+
const resolvedOutput2 = options.output ?? defaultOutput();
|
|
22563
|
+
const instance = new Interface(
|
|
22564
|
+
options.input ?? defaultInput(),
|
|
22565
|
+
resolvedOutput2,
|
|
22566
|
+
isTerminal(options, resolvedOutput2)
|
|
22567
|
+
);
|
|
22033
22568
|
if (typeof options.prompt === "string") instance.setPrompt(options.prompt);
|
|
22034
22569
|
return instance;
|
|
22035
22570
|
}
|
|
22036
|
-
|
|
22571
|
+
const resolvedOutput = output ?? defaultOutput();
|
|
22572
|
+
return new Interface(options ?? defaultInput(), resolvedOutput, isTerminal(void 0, resolvedOutput));
|
|
22037
22573
|
};
|
|
22038
22574
|
const noop = () => {
|
|
22039
22575
|
};
|
|
@@ -22050,6 +22586,7 @@ function createReadlineModule(defaultInput) {
|
|
|
22050
22586
|
}
|
|
22051
22587
|
|
|
22052
22588
|
// src/runtime/core-modules.ts
|
|
22589
|
+
installReadableFrom(streamModule4__default.default);
|
|
22053
22590
|
var Dirent = class {
|
|
22054
22591
|
/** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
|
|
22055
22592
|
constructor(name, stat2, parentPath = "") {
|
|
@@ -22255,9 +22792,20 @@ function createCoreModules(options) {
|
|
|
22255
22792
|
throw new Error("createRequire is only available inside a loaded module");
|
|
22256
22793
|
}
|
|
22257
22794
|
};
|
|
22258
|
-
|
|
22795
|
+
let inFlightRequests = 0;
|
|
22796
|
+
const httpOptions = {
|
|
22797
|
+
...options.http?.fetch ? { fetch: options.http.fetch } : {},
|
|
22798
|
+
trackRequest: () => {
|
|
22799
|
+
inFlightRequests++;
|
|
22800
|
+
return () => {
|
|
22801
|
+
inFlightRequests--;
|
|
22802
|
+
};
|
|
22803
|
+
}
|
|
22804
|
+
};
|
|
22805
|
+
const http = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "http:") : createUnsupportedModule("http");
|
|
22806
|
+
const https = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "https:") : createUnsupportedModule("https");
|
|
22259
22807
|
const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd) : createUnsupportedModule("child_process");
|
|
22260
|
-
const readline = createReadlineModule(() => processObject.stdin);
|
|
22808
|
+
const readline = createReadlineModule(() => processObject.stdin, () => processObject.stdout);
|
|
22261
22809
|
const dns = createDnsModule();
|
|
22262
22810
|
const builtins = {
|
|
22263
22811
|
assert: assert_module_default,
|
|
@@ -22275,7 +22823,7 @@ function createCoreModules(options) {
|
|
|
22275
22823
|
"fs/promises": fs.promises,
|
|
22276
22824
|
module: moduleBuiltin,
|
|
22277
22825
|
http,
|
|
22278
|
-
https
|
|
22826
|
+
https,
|
|
22279
22827
|
os,
|
|
22280
22828
|
path,
|
|
22281
22829
|
"path/posix": path,
|
|
@@ -22315,6 +22863,8 @@ function createCoreModules(options) {
|
|
|
22315
22863
|
process: processObject,
|
|
22316
22864
|
pendingHandles: timers.pending,
|
|
22317
22865
|
pendingUnrefed: timers.pendingUnrefed,
|
|
22866
|
+
/** Client requests sent but not yet read to completion. */
|
|
22867
|
+
pendingRequests: () => inFlightRequests,
|
|
22318
22868
|
writeStdin: (data) => {
|
|
22319
22869
|
if (options.interactiveStdin) stdin.write(data);
|
|
22320
22870
|
},
|
|
@@ -22542,9 +23092,20 @@ function createFsModule(volume, cwd, stdinPath) {
|
|
|
22542
23092
|
if (position == null) file3.position = start2 + chunk.length;
|
|
22543
23093
|
return chunk.length;
|
|
22544
23094
|
},
|
|
22545
|
-
createReadStream: (path) => {
|
|
22546
|
-
const
|
|
22547
|
-
|
|
23095
|
+
createReadStream: (path, options) => {
|
|
23096
|
+
const target = abs(path);
|
|
23097
|
+
const settings = typeof options === "string" ? { encoding: options } : options ?? {};
|
|
23098
|
+
const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
|
|
23099
|
+
const start2 = settings.start ?? 0;
|
|
23100
|
+
const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
|
|
23101
|
+
const slice = whole.subarray(start2, Math.max(start2, end));
|
|
23102
|
+
const stream = streamModule4__default.default.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
|
|
23103
|
+
Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
|
|
23104
|
+
queueMicrotask(() => {
|
|
23105
|
+
stream.emit("open", 0);
|
|
23106
|
+
stream.emit("ready");
|
|
23107
|
+
});
|
|
23108
|
+
return stream;
|
|
22548
23109
|
},
|
|
22549
23110
|
createWriteStream: (path, options) => {
|
|
22550
23111
|
const target = abs(path);
|
|
@@ -23661,6 +24222,11 @@ var PodChildProcess = class {
|
|
|
23661
24222
|
started = false;
|
|
23662
24223
|
cancelled = false;
|
|
23663
24224
|
child;
|
|
24225
|
+
/* The child is launched asynchronously, but a parent may write and close
|
|
24226
|
+
* its input synchronously right after spawning. Holding both until the
|
|
24227
|
+
* child exists is what keeps `echo hi | child` from losing the `hi`. */
|
|
24228
|
+
pendingInput = "";
|
|
24229
|
+
inputEnded = false;
|
|
23664
24230
|
on(event, listener) {
|
|
23665
24231
|
let set = this.listeners.get(event);
|
|
23666
24232
|
if (!set) this.listeners.set(event, set = /* @__PURE__ */ new Set());
|
|
@@ -23683,6 +24249,11 @@ var PodChildProcess = class {
|
|
|
23683
24249
|
(child) => {
|
|
23684
24250
|
this.child = child;
|
|
23685
24251
|
if (this.cancelled) child.kill();
|
|
24252
|
+
if (this.pendingInput !== "") {
|
|
24253
|
+
child.write(this.pendingInput);
|
|
24254
|
+
this.pendingInput = "";
|
|
24255
|
+
}
|
|
24256
|
+
if (this.inputEnded) child.endInput?.();
|
|
23686
24257
|
child.on("output", (text2) => {
|
|
23687
24258
|
this.stdout += text2;
|
|
23688
24259
|
this.emit("stdout", text2);
|
|
@@ -23705,7 +24276,13 @@ var PodChildProcess = class {
|
|
|
23705
24276
|
});
|
|
23706
24277
|
}
|
|
23707
24278
|
sendStdin(data) {
|
|
23708
|
-
this.child
|
|
24279
|
+
if (this.child) this.child.write(data);
|
|
24280
|
+
else this.pendingInput += data;
|
|
24281
|
+
}
|
|
24282
|
+
/** Signal EOF, so a child reading stdin to the end can finish. */
|
|
24283
|
+
endStdin() {
|
|
24284
|
+
if (this.child) this.child.endInput?.();
|
|
24285
|
+
else this.inputEnded = true;
|
|
23709
24286
|
}
|
|
23710
24287
|
kill(signal = "SIGTERM") {
|
|
23711
24288
|
if (this.child) this.child.kill(signal);
|
|
@@ -23788,6 +24365,8 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23788
24365
|
modules;
|
|
23789
24366
|
esbuild;
|
|
23790
24367
|
rolldownBinding;
|
|
24368
|
+
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
24369
|
+
fetch;
|
|
23791
24370
|
constructor(options) {
|
|
23792
24371
|
ensureProcessGlobal();
|
|
23793
24372
|
this.workdir = options.workdir ?? "/";
|
|
@@ -23802,6 +24381,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23802
24381
|
const notify = options.onServerReady;
|
|
23803
24382
|
this.router.onListen = (port) => notify(port, `http://localhost:${port}`);
|
|
23804
24383
|
}
|
|
24384
|
+
if (options.fetch) this.fetch = options.fetch;
|
|
23805
24385
|
this.packages = new CleanPackageInstaller(this.volume, {
|
|
23806
24386
|
cwd: this.workdir,
|
|
23807
24387
|
...options.registry ? { registry: options.registry } : {},
|
|
@@ -23841,7 +24421,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23841
24421
|
proc.exitNow(code);
|
|
23842
24422
|
if (engine?.isEvaluating) throw new ProcessExit(code);
|
|
23843
24423
|
},
|
|
23844
|
-
http: { router: this.router, owner },
|
|
24424
|
+
http: { router: this.router, owner, ...this.fetch ? { fetch: this.fetch } : {} },
|
|
23845
24425
|
spawnChild: (config) => this.processManager.spawn(config),
|
|
23846
24426
|
...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
|
|
23847
24427
|
...options.interactiveStdin ? { interactiveStdin: true } : {},
|
|
@@ -23858,7 +24438,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23858
24438
|
});
|
|
23859
24439
|
try {
|
|
23860
24440
|
await engine.run(script);
|
|
23861
|
-
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin);
|
|
24441
|
+
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests);
|
|
23862
24442
|
if (this.router.activePorts(owner).length) {
|
|
23863
24443
|
await proc.waitForKill();
|
|
23864
24444
|
return 137;
|
|
@@ -23904,18 +24484,18 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
23904
24484
|
* A plain script that has genuinely finished falls straight through both,
|
|
23905
24485
|
* costing a handful of empty turns.
|
|
23906
24486
|
*/
|
|
23907
|
-
async settle(owner, pendingHandles, pendingUnrefed, readingStdin) {
|
|
24487
|
+
async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests) {
|
|
23908
24488
|
for (let turn = 0; turn < DRAIN_TURNS; turn++) {
|
|
23909
24489
|
if (this.router.activePorts(owner).length) return;
|
|
23910
24490
|
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
23911
24491
|
}
|
|
23912
|
-
if (pendingHandles() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
24492
|
+
if (pendingHandles() === 0 && pendingRequests() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
23913
24493
|
const deadline = Date.now() + 1e3;
|
|
23914
24494
|
while (!this.router.activePorts(owner).length && Date.now() < deadline) {
|
|
23915
24495
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23916
24496
|
}
|
|
23917
24497
|
}
|
|
23918
|
-
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || readingStdin())) {
|
|
24498
|
+
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
|
|
23919
24499
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
23920
24500
|
}
|
|
23921
24501
|
}
|
|
@@ -24576,17 +25156,18 @@ var Terminal = class {
|
|
|
24576
25156
|
// ── key handling ──────────────────────────────────────────────────────────
|
|
24577
25157
|
key(ch) {
|
|
24578
25158
|
if (this.running) {
|
|
24579
|
-
|
|
25159
|
+
const raw = this.currentStdin?.rawMode === true;
|
|
25160
|
+
if (ch === CTRL_C && !raw) {
|
|
24580
25161
|
this.session.proc.deliver("SIGINT");
|
|
24581
25162
|
this.write("^C\r\n");
|
|
24582
25163
|
return;
|
|
24583
25164
|
}
|
|
24584
|
-
if (ch === CTRL_D) {
|
|
25165
|
+
if (ch === CTRL_D && !raw) {
|
|
24585
25166
|
this.currentStdin?.end();
|
|
24586
25167
|
return;
|
|
24587
25168
|
}
|
|
24588
|
-
if (!
|
|
24589
|
-
this.currentStdin?.write(ch === "\r" ? "\n" : ch);
|
|
25169
|
+
if (!raw) this.write(ch === "\r" ? "\r\n" : ch);
|
|
25170
|
+
this.currentStdin?.write(!raw && ch === "\r" ? "\n" : ch);
|
|
24590
25171
|
return;
|
|
24591
25172
|
}
|
|
24592
25173
|
if (this.escapeBuffer !== "") {
|