sandboxedjs 0.2.5 → 0.2.7
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/browser-host.cjs +137 -0
- package/dist/browser-host.d.cts +12 -0
- package/dist/browser-host.d.ts +12 -0
- package/dist/browser-host.js +137 -0
- package/dist/egress.cjs +12 -1
- package/dist/egress.d.cts +33 -1
- package/dist/egress.d.ts +33 -1
- package/dist/egress.js +11 -2
- package/dist/index.cjs +245 -129
- package/dist/index.js +245 -129
- package/dist/python-abi.cjs +5 -1
- package/dist/python-abi.js +5 -1
- package/dist/worker-entry.js +58 -17
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -622,32 +622,32 @@ var init_variables = __esm({
|
|
|
622
622
|
return this.find(name) !== void 0;
|
|
623
623
|
}
|
|
624
624
|
get(name) {
|
|
625
|
-
const
|
|
626
|
-
if (!
|
|
627
|
-
if (
|
|
628
|
-
return
|
|
625
|
+
const found2 = this.find(name);
|
|
626
|
+
if (!found2) return void 0;
|
|
627
|
+
if (found2.entry.array) return found2.entry.array[0] ?? "";
|
|
628
|
+
return found2.entry.value;
|
|
629
629
|
}
|
|
630
630
|
entry(name) {
|
|
631
631
|
return this.find(name)?.entry;
|
|
632
632
|
}
|
|
633
633
|
getArray(name) {
|
|
634
|
-
const
|
|
635
|
-
if (!
|
|
636
|
-
return
|
|
634
|
+
const found2 = this.find(name);
|
|
635
|
+
if (!found2) return void 0;
|
|
636
|
+
return found2.entry.array ?? [found2.entry.value];
|
|
637
637
|
}
|
|
638
638
|
isArray(name) {
|
|
639
639
|
return this.find(name)?.entry.array !== void 0;
|
|
640
640
|
}
|
|
641
641
|
set(name, value, attrs = {}) {
|
|
642
|
-
const
|
|
643
|
-
if (
|
|
642
|
+
const found2 = this.find(name);
|
|
643
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
644
644
|
let next = value;
|
|
645
|
-
if (
|
|
646
|
-
if (
|
|
647
|
-
if (
|
|
648
|
-
|
|
649
|
-
delete
|
|
650
|
-
Object.assign(
|
|
645
|
+
if (found2?.entry.upper || attrs.upper) next = next.toUpperCase();
|
|
646
|
+
if (found2?.entry.lower || attrs.lower) next = next.toLowerCase();
|
|
647
|
+
if (found2) {
|
|
648
|
+
found2.entry.value = next;
|
|
649
|
+
delete found2.entry.array;
|
|
650
|
+
Object.assign(found2.entry, attrs);
|
|
651
651
|
} else {
|
|
652
652
|
this.scopes[this.scopes.length - 1].set(name, { value: next, ...attrs });
|
|
653
653
|
}
|
|
@@ -657,28 +657,28 @@ var init_variables = __esm({
|
|
|
657
657
|
this.scopes[this.scopes.length - 1].set(name, { value, ...attrs });
|
|
658
658
|
}
|
|
659
659
|
setArray(name, values, attrs = {}) {
|
|
660
|
-
const
|
|
661
|
-
if (
|
|
662
|
-
if (
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
Object.assign(
|
|
660
|
+
const found2 = this.find(name);
|
|
661
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
662
|
+
if (found2) {
|
|
663
|
+
found2.entry.array = values.slice();
|
|
664
|
+
found2.entry.value = values[0] ?? "";
|
|
665
|
+
Object.assign(found2.entry, attrs);
|
|
666
666
|
} else {
|
|
667
667
|
this.scopes[this.scopes.length - 1].set(name, { value: values[0] ?? "", array: values.slice(), ...attrs });
|
|
668
668
|
}
|
|
669
669
|
}
|
|
670
670
|
setIndex(name, index, value) {
|
|
671
|
-
const
|
|
672
|
-
if (
|
|
673
|
-
const arr =
|
|
671
|
+
const found2 = this.find(name);
|
|
672
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
673
|
+
const arr = found2?.entry.array ?? (found2 ? [found2.entry.value] : []);
|
|
674
674
|
while (arr.length < index) arr.push("");
|
|
675
675
|
arr[index] = value;
|
|
676
676
|
this.setArray(name, arr);
|
|
677
677
|
}
|
|
678
678
|
append(name, value) {
|
|
679
|
-
const
|
|
680
|
-
if (
|
|
681
|
-
this.setArray(name, [...
|
|
679
|
+
const found2 = this.find(name);
|
|
680
|
+
if (found2?.entry.array) {
|
|
681
|
+
this.setArray(name, [...found2.entry.array, value]);
|
|
682
682
|
return;
|
|
683
683
|
}
|
|
684
684
|
this.set(name, (this.get(name) ?? "") + value);
|
|
@@ -695,13 +695,13 @@ var init_variables = __esm({
|
|
|
695
695
|
return false;
|
|
696
696
|
}
|
|
697
697
|
export(name, exported = true) {
|
|
698
|
-
const
|
|
699
|
-
if (
|
|
698
|
+
const found2 = this.find(name);
|
|
699
|
+
if (found2) found2.entry.exported = exported;
|
|
700
700
|
else this.scopes[this.scopes.length - 1].set(name, { value: "", exported });
|
|
701
701
|
}
|
|
702
702
|
markReadonly(name) {
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
703
|
+
const found2 = this.find(name);
|
|
704
|
+
if (found2) found2.entry.readonly = true;
|
|
705
705
|
else this.scopes[this.scopes.length - 1].set(name, { value: "", readonly: true });
|
|
706
706
|
}
|
|
707
707
|
names() {
|
|
@@ -2947,8 +2947,8 @@ async function builtinSource({ shell, argv, io }) {
|
|
|
2947
2947
|
}
|
|
2948
2948
|
let path = resolve(shell.cwd, target);
|
|
2949
2949
|
if (!target.includes("/")) {
|
|
2950
|
-
const
|
|
2951
|
-
if (
|
|
2950
|
+
const found2 = shell.kernel.which(target, shell.cwd, shell.vars.environment(), shell.cred);
|
|
2951
|
+
if (found2) path = found2;
|
|
2952
2952
|
}
|
|
2953
2953
|
let text2;
|
|
2954
2954
|
try {
|
|
@@ -3582,32 +3582,32 @@ function builtinType({ shell, argv, io }) {
|
|
|
3582
3582
|
const names = args.filter((a) => !a.startsWith("-"));
|
|
3583
3583
|
let status = 0;
|
|
3584
3584
|
for (const name of names) {
|
|
3585
|
-
const
|
|
3585
|
+
const found2 = [];
|
|
3586
3586
|
if (shell.aliases.has(name)) {
|
|
3587
|
-
if (typeOnly)
|
|
3588
|
-
else if (!pathOnly)
|
|
3587
|
+
if (typeOnly) found2.push("alias");
|
|
3588
|
+
else if (!pathOnly) found2.push(`${name} is aliased to \`${shell.aliases.get(name)}'`);
|
|
3589
3589
|
}
|
|
3590
3590
|
if (shell.functions.has(name)) {
|
|
3591
|
-
if (typeOnly)
|
|
3592
|
-
else if (!pathOnly)
|
|
3591
|
+
if (typeOnly) found2.push("function");
|
|
3592
|
+
else if (!pathOnly) found2.push(`${name} is a function`);
|
|
3593
3593
|
}
|
|
3594
3594
|
if (isBuiltinName(name)) {
|
|
3595
|
-
if (typeOnly)
|
|
3596
|
-
else if (!pathOnly)
|
|
3595
|
+
if (typeOnly) found2.push("builtin");
|
|
3596
|
+
else if (!pathOnly) found2.push(`${name} is a shell builtin`);
|
|
3597
3597
|
}
|
|
3598
3598
|
const path = shell.kernel.which(name, shell.cwd, shell.vars.environment(), shell.cred);
|
|
3599
3599
|
if (path) {
|
|
3600
|
-
if (typeOnly)
|
|
3601
|
-
else if (pathOnly)
|
|
3602
|
-
else
|
|
3600
|
+
if (typeOnly) found2.push("file");
|
|
3601
|
+
else if (pathOnly) found2.push(path);
|
|
3602
|
+
else found2.push(`${name} is ${path}`);
|
|
3603
3603
|
}
|
|
3604
|
-
if (
|
|
3604
|
+
if (found2.length === 0) {
|
|
3605
3605
|
if (!pathOnly && !typeOnly) io.stderr.write(`type: ${name}: not found
|
|
3606
3606
|
`);
|
|
3607
3607
|
status = 1;
|
|
3608
3608
|
continue;
|
|
3609
3609
|
}
|
|
3610
|
-
for (const line of all ?
|
|
3610
|
+
for (const line of all ? found2 : [found2[0]]) io.stdout.write(line + "\n");
|
|
3611
3611
|
}
|
|
3612
3612
|
return status;
|
|
3613
3613
|
}
|
|
@@ -5964,9 +5964,9 @@ function parseArgs(argv, specs, opts = {}) {
|
|
|
5964
5964
|
const resolveLong = (name) => {
|
|
5965
5965
|
const exact = byLong.get(name);
|
|
5966
5966
|
if (exact) return exact;
|
|
5967
|
-
const
|
|
5968
|
-
if (
|
|
5969
|
-
if (
|
|
5967
|
+
const candidates2 = [...byLong.keys()].filter((k) => k.startsWith(name));
|
|
5968
|
+
if (candidates2.length === 1) return byLong.get(candidates2[0]);
|
|
5969
|
+
if (candidates2.length > 1) throw new UsageError(`option '--${name}' is ambiguous`);
|
|
5970
5970
|
return void 0;
|
|
5971
5971
|
};
|
|
5972
5972
|
for (; i < argv.length; i++) {
|
|
@@ -6485,19 +6485,19 @@ var WasiHost = class {
|
|
|
6485
6485
|
}
|
|
6486
6486
|
// ── descriptors ──────────────────────────────────────────────────────────
|
|
6487
6487
|
get(fd) {
|
|
6488
|
-
const
|
|
6489
|
-
if (!
|
|
6490
|
-
return
|
|
6488
|
+
const found2 = this.fds.get(fd);
|
|
6489
|
+
if (!found2) throw new WasiError(WASI_EBADF);
|
|
6490
|
+
return found2;
|
|
6491
6491
|
}
|
|
6492
6492
|
dir(fd) {
|
|
6493
|
-
const
|
|
6494
|
-
if (
|
|
6495
|
-
return
|
|
6493
|
+
const found2 = this.get(fd);
|
|
6494
|
+
if (found2.kind !== "dir") throw new WasiError(WASI_ENOTDIR);
|
|
6495
|
+
return found2;
|
|
6496
6496
|
}
|
|
6497
6497
|
file(fd) {
|
|
6498
|
-
const
|
|
6499
|
-
if (
|
|
6500
|
-
return
|
|
6498
|
+
const found2 = this.get(fd);
|
|
6499
|
+
if (found2.kind !== "file") throw new WasiError(WASI_EBADF);
|
|
6500
|
+
return found2;
|
|
6501
6501
|
}
|
|
6502
6502
|
/**
|
|
6503
6503
|
* Resolve a guest path against a directory descriptor.
|
|
@@ -7442,13 +7442,13 @@ var Kernel = class {
|
|
|
7442
7442
|
* Find `name` the way `execvp` does. Returns null when nothing matches.
|
|
7443
7443
|
*/
|
|
7444
7444
|
resolveExecutable(name, cwd, env2, cred = ROOT_CRED) {
|
|
7445
|
-
const
|
|
7445
|
+
const candidates2 = [];
|
|
7446
7446
|
if (name.includes("/")) {
|
|
7447
|
-
|
|
7447
|
+
candidates2.push(resolve(cwd, name));
|
|
7448
7448
|
} else {
|
|
7449
|
-
for (const dir3 of this.pathDirs(env2))
|
|
7449
|
+
for (const dir3 of this.pathDirs(env2)) candidates2.push(join(dir3, name));
|
|
7450
7450
|
}
|
|
7451
|
-
for (const candidate of
|
|
7451
|
+
for (const candidate of candidates2) {
|
|
7452
7452
|
let real;
|
|
7453
7453
|
try {
|
|
7454
7454
|
real = this.vfs.realpath(candidate, cred);
|
|
@@ -8424,10 +8424,50 @@ function isBrowser() {
|
|
|
8424
8424
|
}
|
|
8425
8425
|
function browserBlocked(hostname, message) {
|
|
8426
8426
|
return new Error(
|
|
8427
|
-
`${message} \u2014 the request to ${hostname} was blocked by the browser. A page can only read a response from a host that sends CORS headers, and most APIs send none.
|
|
8427
|
+
`${message} \u2014 the request to ${hostname} was blocked by the browser. A page can only read a response from a host that sends CORS headers, and most APIs send none. The container looks for a proxy to make the request for it and found none: mount \`handleEgressRequest\` from "sandboxedjs/egress" at /__sandboxedjs__/egress on this origin, or run \`npx sandboxedjs-egress\`, and it is used without further configuration (network: { proxy } names one somewhere else) \u2014 or run the container on a server.`
|
|
8428
8428
|
);
|
|
8429
8429
|
}
|
|
8430
8430
|
|
|
8431
|
+
// src/net/discover-egress.ts
|
|
8432
|
+
var EGRESS_PATH = "/__sandboxedjs__/egress";
|
|
8433
|
+
var EGRESS_MARKER = { sandboxedjs: "egress", protocol: 1 };
|
|
8434
|
+
var CLI_PORT = 4181;
|
|
8435
|
+
var found = null;
|
|
8436
|
+
var PROBE_TIMEOUT_MS = 1500;
|
|
8437
|
+
async function isEgress(url, fetchImpl) {
|
|
8438
|
+
const control = new AbortController();
|
|
8439
|
+
const timer = setTimeout(() => control.abort(), PROBE_TIMEOUT_MS);
|
|
8440
|
+
try {
|
|
8441
|
+
const answer = await fetchImpl(url, { method: "GET", signal: control.signal });
|
|
8442
|
+
if (!answer.ok) return false;
|
|
8443
|
+
const payload = await answer.json();
|
|
8444
|
+
return payload?.sandboxedjs === EGRESS_MARKER.sandboxedjs;
|
|
8445
|
+
} catch {
|
|
8446
|
+
return false;
|
|
8447
|
+
} finally {
|
|
8448
|
+
clearTimeout(timer);
|
|
8449
|
+
}
|
|
8450
|
+
}
|
|
8451
|
+
function candidates() {
|
|
8452
|
+
const origin = globalThis.location?.origin;
|
|
8453
|
+
const list = [];
|
|
8454
|
+
if (origin && /^https?:/.test(origin)) list.push(`${origin}${EGRESS_PATH}`);
|
|
8455
|
+
list.push(`http://127.0.0.1:${CLI_PORT}/`);
|
|
8456
|
+
return list;
|
|
8457
|
+
}
|
|
8458
|
+
async function discoverEgress(fetchImpl = fetch) {
|
|
8459
|
+
if (!isBrowser()) return null;
|
|
8460
|
+
if (!found) {
|
|
8461
|
+
found = (async () => {
|
|
8462
|
+
for (const candidate of candidates()) {
|
|
8463
|
+
if (await isEgress(candidate, fetchImpl)) return candidate;
|
|
8464
|
+
}
|
|
8465
|
+
return null;
|
|
8466
|
+
})();
|
|
8467
|
+
}
|
|
8468
|
+
return await found;
|
|
8469
|
+
}
|
|
8470
|
+
|
|
8431
8471
|
// src/net/policy.ts
|
|
8432
8472
|
function isLoopbackHostname(hostname) {
|
|
8433
8473
|
const host2 = hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
@@ -8470,7 +8510,8 @@ function policedFetch(policy, fetchImpl) {
|
|
|
8470
8510
|
if (!outboundAllowed(policy, url)) {
|
|
8471
8511
|
throw Object.assign(new TypeError("fetch failed"), { cause: outboundBlockedError(url) });
|
|
8472
8512
|
}
|
|
8473
|
-
|
|
8513
|
+
const proxy = policy.proxy ?? await discoverEgress(fetchImpl);
|
|
8514
|
+
if (proxy) return await fetchThroughProxy(proxy, fetchImpl, input, init);
|
|
8474
8515
|
try {
|
|
8475
8516
|
return await fetchImpl(input, init);
|
|
8476
8517
|
} catch (error) {
|
|
@@ -9006,7 +9047,7 @@ var Lexer = class _Lexer {
|
|
|
9006
9047
|
const quoted = /['"\\]/.test(rawTag);
|
|
9007
9048
|
const tag2 = rawTag.replace(/['"\\]/g, "");
|
|
9008
9049
|
const lines = [];
|
|
9009
|
-
let
|
|
9050
|
+
let found2 = false;
|
|
9010
9051
|
while (this.pos < this.src.length) {
|
|
9011
9052
|
let eol = this.src.indexOf("\n", this.pos);
|
|
9012
9053
|
if (eol < 0) eol = this.src.length;
|
|
@@ -9014,13 +9055,13 @@ var Lexer = class _Lexer {
|
|
|
9014
9055
|
this.pos = eol + 1;
|
|
9015
9056
|
const compare = stripTabs ? rawLine.replace(/^\t+/, "") : rawLine;
|
|
9016
9057
|
if (compare === tag2) {
|
|
9017
|
-
|
|
9058
|
+
found2 = true;
|
|
9018
9059
|
break;
|
|
9019
9060
|
}
|
|
9020
9061
|
lines.push(stripTabs ? rawLine.replace(/^\t+/, "") : rawLine);
|
|
9021
9062
|
if (eol >= this.src.length) break;
|
|
9022
9063
|
}
|
|
9023
|
-
if (!
|
|
9064
|
+
if (!found2) {
|
|
9024
9065
|
throw new IncompleteInputError(`here-document delimited by end-of-file (wanted \`${tag2}')`, opToken.pos);
|
|
9025
9066
|
}
|
|
9026
9067
|
opToken.heredoc = { tag: tag2, stripTabs, quoted, body: lines.length ? lines.join("\n") + "\n" : "" };
|
|
@@ -14475,8 +14516,8 @@ var Interpreter = class {
|
|
|
14475
14516
|
for (let i = this.locals.length - 1; i >= 0; i--) {
|
|
14476
14517
|
const scope = this.locals[i];
|
|
14477
14518
|
if (scope.has(name)) {
|
|
14478
|
-
const
|
|
14479
|
-
return
|
|
14519
|
+
const found2 = scope.get(name);
|
|
14520
|
+
return found2 instanceof Map ? Value.uninitialized : found2;
|
|
14480
14521
|
}
|
|
14481
14522
|
}
|
|
14482
14523
|
if (name === "NF") {
|
|
@@ -14508,8 +14549,8 @@ var Interpreter = class {
|
|
|
14508
14549
|
for (let i = this.locals.length - 1; i >= 0; i--) {
|
|
14509
14550
|
const scope = this.locals[i];
|
|
14510
14551
|
if (scope.has(name)) {
|
|
14511
|
-
const
|
|
14512
|
-
if (
|
|
14552
|
+
const found2 = scope.get(name);
|
|
14553
|
+
if (found2 instanceof Map) return found2;
|
|
14513
14554
|
const created = /* @__PURE__ */ new Map();
|
|
14514
14555
|
scope.set(name, created);
|
|
14515
14556
|
return created;
|
|
@@ -17587,7 +17628,7 @@ async function performRequest(ctx, url, init) {
|
|
|
17587
17628
|
`outbound network access to ${url.hostname} is disabled for this container (enable with network: { allowOutbound: true })`
|
|
17588
17629
|
);
|
|
17589
17630
|
}
|
|
17590
|
-
const proxy = ctx.kernel.net.proxy;
|
|
17631
|
+
const proxy = ctx.kernel.net.proxy ?? await discoverEgress();
|
|
17591
17632
|
if (proxy) {
|
|
17592
17633
|
const result = await proxyExchange(proxy, {
|
|
17593
17634
|
url: url.toString(),
|
|
@@ -18558,14 +18599,14 @@ var apropos = defineCommand({
|
|
|
18558
18599
|
return 1;
|
|
18559
18600
|
}
|
|
18560
18601
|
const patterns = ctx.args.map((a) => new RegExp(a, "i"));
|
|
18561
|
-
let
|
|
18602
|
+
let found2 = 0;
|
|
18562
18603
|
for (const command of ctx.kernel.commands.all()) {
|
|
18563
18604
|
const haystack = `${command.name} ${command.summary ?? ""}`;
|
|
18564
18605
|
if (!patterns.some((p) => p.test(haystack))) continue;
|
|
18565
|
-
|
|
18606
|
+
found2++;
|
|
18566
18607
|
ctx.line(`${command.name} (1)${" ".repeat(Math.max(1, 16 - command.name.length))}- ${command.summary ?? ""}`);
|
|
18567
18608
|
}
|
|
18568
|
-
if (
|
|
18609
|
+
if (found2 === 0) {
|
|
18569
18610
|
ctx.line(`${ctx.args.join(" ")}: nothing appropriate.`);
|
|
18570
18611
|
return 1;
|
|
18571
18612
|
}
|
|
@@ -19589,8 +19630,8 @@ ${prelude}${preloadRequires(preloads)}${source}
|
|
|
19589
19630
|
}
|
|
19590
19631
|
function resolveScript(ctx, operand) {
|
|
19591
19632
|
const base2 = ctx.path(operand);
|
|
19592
|
-
const
|
|
19593
|
-
for (const candidate of
|
|
19633
|
+
const candidates2 = [base2, `${base2}.js`, `${base2}.mjs`, `${base2}.cjs`, `${base2}.json`];
|
|
19634
|
+
for (const candidate of candidates2) {
|
|
19594
19635
|
try {
|
|
19595
19636
|
const st = ctx.vfs.stat(candidate, { cred: ctx.cred });
|
|
19596
19637
|
if (st.isFile()) return ctx.vfs.realpath(candidate, ctx.cred);
|
|
@@ -21057,7 +21098,7 @@ var wheels_default = {
|
|
|
21057
21098
|
|
|
21058
21099
|
// package.json
|
|
21059
21100
|
var package_default = {
|
|
21060
|
-
version: "0.2.
|
|
21101
|
+
version: "0.2.7"};
|
|
21061
21102
|
|
|
21062
21103
|
// src/python/extension-abi.ts
|
|
21063
21104
|
var EXTENSION_ABI = {
|
|
@@ -22722,8 +22763,12 @@ function createHostAbiServer(proc) {
|
|
|
22722
22763
|
}
|
|
22723
22764
|
case Op.resolve: {
|
|
22724
22765
|
const sockets = proc.sockets;
|
|
22766
|
+
const name = r.string();
|
|
22767
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
22768
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
22769
|
+
}
|
|
22725
22770
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
22726
|
-
const address = sockets.outbound.resolve(
|
|
22771
|
+
const address = sockets.outbound.resolve(name);
|
|
22727
22772
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
22728
22773
|
}
|
|
22729
22774
|
case Op.send: {
|
|
@@ -23925,7 +23970,7 @@ function explain(name, constraints, chosenVersion, available2 = []) {
|
|
|
23925
23970
|
return lines;
|
|
23926
23971
|
}
|
|
23927
23972
|
async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, rejected = { versions: /* @__PURE__ */ new Set(), sourceAvailable: false }) {
|
|
23928
|
-
const
|
|
23973
|
+
const candidates2 = [];
|
|
23929
23974
|
if (prebuilt) assertIndexUsable(prebuilt);
|
|
23930
23975
|
for (const wheel of prebuilt?.wheels ?? []) {
|
|
23931
23976
|
if (normalize2(wheel.name) !== normalize2(name)) continue;
|
|
@@ -23934,7 +23979,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23934
23979
|
`${wheel.filename} in the wheel index was built for ABI ${wheel.abiId}, but this runtime implements ${EXTENSION_ABI.abiId}; rebuild it`
|
|
23935
23980
|
);
|
|
23936
23981
|
}
|
|
23937
|
-
|
|
23982
|
+
candidates2.push({
|
|
23938
23983
|
name: normalize2(wheel.name),
|
|
23939
23984
|
version: wheel.version,
|
|
23940
23985
|
kind: "sbx-wasm",
|
|
@@ -23945,13 +23990,13 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23945
23990
|
indexedRequires: wheel.requires
|
|
23946
23991
|
});
|
|
23947
23992
|
}
|
|
23948
|
-
|
|
23949
|
-
if (isBuiltinOnly(normalize2(name))) return
|
|
23993
|
+
candidates2.push(...builtinCandidates(normalize2(name)));
|
|
23994
|
+
if (isBuiltinOnly(normalize2(name))) return candidates2;
|
|
23950
23995
|
let index;
|
|
23951
23996
|
try {
|
|
23952
23997
|
index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
|
|
23953
23998
|
} catch (error) {
|
|
23954
|
-
if (
|
|
23999
|
+
if (candidates2.length > 0) return candidates2;
|
|
23955
24000
|
throw error;
|
|
23956
24001
|
}
|
|
23957
24002
|
for (const [version, files] of Object.entries(index.releases ?? {})) {
|
|
@@ -23964,7 +24009,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23964
24009
|
rejected.versions.add(version);
|
|
23965
24010
|
continue;
|
|
23966
24011
|
}
|
|
23967
|
-
|
|
24012
|
+
candidates2.push({
|
|
23968
24013
|
name: normalize2(name),
|
|
23969
24014
|
version,
|
|
23970
24015
|
kind,
|
|
@@ -23975,7 +24020,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23975
24020
|
});
|
|
23976
24021
|
}
|
|
23977
24022
|
}
|
|
23978
|
-
return
|
|
24023
|
+
return candidates2;
|
|
23979
24024
|
}
|
|
23980
24025
|
function newest(versions) {
|
|
23981
24026
|
return versions.reduce((a, b) => compareVersions(b, a, ">") ? b : a);
|
|
@@ -24272,17 +24317,17 @@ function createProcessService(ctx) {
|
|
|
24272
24317
|
return proc.pid;
|
|
24273
24318
|
},
|
|
24274
24319
|
async wait(pid, options) {
|
|
24275
|
-
const
|
|
24276
|
-
if (
|
|
24320
|
+
const candidates2 = pid > 0 ? [children.get(pid)].filter((p) => p !== void 0) : [...children.values()];
|
|
24321
|
+
if (candidates2.length === 0) throw new PosixError(Errno.ECHILD);
|
|
24277
24322
|
const reap = (proc) => {
|
|
24278
24323
|
children.delete(proc.pid);
|
|
24279
24324
|
return { pid: proc.pid, status: waitStatus(proc) };
|
|
24280
24325
|
};
|
|
24281
|
-
const done =
|
|
24326
|
+
const done = candidates2.find(exited);
|
|
24282
24327
|
if (done) return reap(done);
|
|
24283
24328
|
if (options & WNOHANG) return { pid: 0, status: 0 };
|
|
24284
|
-
await Promise.race(
|
|
24285
|
-
const finished =
|
|
24329
|
+
await Promise.race(candidates2.map((proc) => proc.wait()));
|
|
24330
|
+
const finished = candidates2.find(exited);
|
|
24286
24331
|
if (!finished) throw new PosixError(Errno.ECHILD);
|
|
24287
24332
|
return reap(finished);
|
|
24288
24333
|
},
|
|
@@ -24850,6 +24895,77 @@ if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1":
|
|
|
24850
24895
|
sys.meta_path.insert(0, _SbxTruststoreHook())
|
|
24851
24896
|
|
|
24852
24897
|
|
|
24898
|
+
# Literal addresses are answered here rather than through the host.
|
|
24899
|
+
#
|
|
24900
|
+
# The container's resolver is a host call, and a container with no outbound
|
|
24901
|
+
# sockets configured has no resolver to call: it answers ENOSYS. That is the
|
|
24902
|
+
# right answer for a name, but the egress hop below dials 127.0.0.1, and
|
|
24903
|
+
# http.client calls getaddrinfo even for an address that needs no resolving --
|
|
24904
|
+
# so every request through the egress died with "Function not implemented"
|
|
24905
|
+
# before it reached the endpoint. A numeric address (and loopback by its usual
|
|
24906
|
+
# names) is now formed here, which is what a resolver would have returned.
|
|
24907
|
+
def _sbx_local_addresses():
|
|
24908
|
+
import socket as _socket_module
|
|
24909
|
+
import _socket as _socket_native
|
|
24910
|
+
|
|
24911
|
+
# The native entry point, not socket.getaddrinfo: the stdlib wrapper
|
|
24912
|
+
# delegates to _socket, so wrapping the wrapper and replacing _socket with
|
|
24913
|
+
# the wrapper makes the two call each other forever.
|
|
24914
|
+
_real_getaddrinfo = _socket_native.getaddrinfo
|
|
24915
|
+
|
|
24916
|
+
_literals = {"localhost": "127.0.0.1", "localhost.localdomain": "127.0.0.1",
|
|
24917
|
+
"ip6-localhost": "127.0.0.1"}
|
|
24918
|
+
|
|
24919
|
+
def _literal(host):
|
|
24920
|
+
"""The address host already is, or None when it needs a resolver."""
|
|
24921
|
+
if isinstance(host, (bytes, bytearray)):
|
|
24922
|
+
host = bytes(host).decode("ascii", "replace")
|
|
24923
|
+
if host is None:
|
|
24924
|
+
return None
|
|
24925
|
+
host = _literals.get(host.lower(), host)
|
|
24926
|
+
parts = host.split(".")
|
|
24927
|
+
if len(parts) != 4:
|
|
24928
|
+
return None
|
|
24929
|
+
for part in parts:
|
|
24930
|
+
if not part.isdigit() or len(part) > 3 or int(part) > 255:
|
|
24931
|
+
return None
|
|
24932
|
+
return host
|
|
24933
|
+
|
|
24934
|
+
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
|
|
24935
|
+
address = _literal(host)
|
|
24936
|
+
if address is None:
|
|
24937
|
+
return _real_getaddrinfo(host, port, family, type, proto, flags)
|
|
24938
|
+
if isinstance(port, (bytes, bytearray)):
|
|
24939
|
+
port = bytes(port).decode("ascii", "replace")
|
|
24940
|
+
if isinstance(port, str):
|
|
24941
|
+
port = int(port) if port.isdigit() else _socket_module.getservbyname(port)
|
|
24942
|
+
if port is None:
|
|
24943
|
+
port = 0
|
|
24944
|
+
if family not in (0, _socket_module.AF_UNSPEC, _socket_module.AF_INET):
|
|
24945
|
+
raise _socket_module.gaierror(
|
|
24946
|
+
_socket_module.EAI_FAMILY, "only AF_INET is supported in this container"
|
|
24947
|
+
)
|
|
24948
|
+
kind = type or _socket_module.SOCK_STREAM
|
|
24949
|
+
protocol = proto or (_socket_module.IPPROTO_TCP
|
|
24950
|
+
if kind == _socket_module.SOCK_STREAM else 0)
|
|
24951
|
+
return [(_socket_module.AF_INET, kind, protocol, "", (address, int(port)))]
|
|
24952
|
+
|
|
24953
|
+
def gethostbyname(host):
|
|
24954
|
+
return getaddrinfo(host, 0)[0][4][0]
|
|
24955
|
+
|
|
24956
|
+
def gethostbyname_ex(host):
|
|
24957
|
+
return (host, [], [gethostbyname(host)])
|
|
24958
|
+
|
|
24959
|
+
_socket_module.getaddrinfo = getaddrinfo
|
|
24960
|
+
_socket_module.gethostbyname = gethostbyname
|
|
24961
|
+
_socket_module.gethostbyname_ex = gethostbyname_ex
|
|
24962
|
+
_socket_native.getaddrinfo = getaddrinfo
|
|
24963
|
+
_socket_native.gethostbyname = gethostbyname
|
|
24964
|
+
_socket_native.gethostbyname_ex = gethostbyname_ex
|
|
24965
|
+
|
|
24966
|
+
|
|
24967
|
+
_sbx_local_addresses()
|
|
24968
|
+
|
|
24853
24969
|
_egress = None if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1" else os.environ.get("SBX_HTTP_EGRESS")
|
|
24854
24970
|
if _egress:
|
|
24855
24971
|
import http.client
|
|
@@ -26439,9 +26555,9 @@ function resolveVersion(metadata, range) {
|
|
|
26439
26555
|
const tag2 = metadata["dist-tags"]?.[range];
|
|
26440
26556
|
if (tag2) return tag2;
|
|
26441
26557
|
if (semver.valid(range) && metadata.versions[range]) return range;
|
|
26442
|
-
const
|
|
26443
|
-
if (!
|
|
26444
|
-
return
|
|
26558
|
+
const found2 = semver.maxSatisfying(Object.keys(metadata.versions), range === "latest" ? "*" : range, { includePrerelease: false });
|
|
26559
|
+
if (!found2) throw new Error(`No matching version found for ${metadata.name}@${range}`);
|
|
26560
|
+
return found2;
|
|
26445
26561
|
}
|
|
26446
26562
|
function verifyIntegrity(data, integrity, shasum, identity) {
|
|
26447
26563
|
if (integrity) {
|
|
@@ -26903,23 +27019,23 @@ var npm = defineCommand({
|
|
|
26903
27019
|
case "uninstall":
|
|
26904
27020
|
case "remove":
|
|
26905
27021
|
case "rm": {
|
|
26906
|
-
const
|
|
27022
|
+
const found2 = readManifest(ctx, root);
|
|
26907
27023
|
for (const name of rest.filter((a) => !a.startsWith("-"))) {
|
|
26908
27024
|
const target = join(root, "node_modules", name);
|
|
26909
27025
|
if (ctx.vfs.lexists(target)) ctx.vfs.rmrf(target, ctx.cred);
|
|
26910
|
-
if (
|
|
26911
|
-
delete
|
|
26912
|
-
delete
|
|
27026
|
+
if (found2) {
|
|
27027
|
+
delete found2.manifest.dependencies?.[name];
|
|
27028
|
+
delete found2.manifest.devDependencies?.[name];
|
|
26913
27029
|
}
|
|
26914
27030
|
ctx.line(`removed ${name}`);
|
|
26915
27031
|
}
|
|
26916
|
-
if (
|
|
27032
|
+
if (found2) writeManifest(ctx, found2.path, found2.manifest);
|
|
26917
27033
|
return 0;
|
|
26918
27034
|
}
|
|
26919
27035
|
case "ls":
|
|
26920
27036
|
case "list": {
|
|
26921
|
-
const
|
|
26922
|
-
ctx.line(`${
|
|
27037
|
+
const found2 = readManifest(ctx, root);
|
|
27038
|
+
ctx.line(`${found2?.manifest.name ?? basename(root)}@${found2?.manifest.version ?? "1.0.0"} ${root}`);
|
|
26923
27039
|
const modules = join(root, "node_modules");
|
|
26924
27040
|
if (!ctx.vfs.lexists(modules)) return 0;
|
|
26925
27041
|
const names = ctx.vfs.readdir(modules, ctx.cred).filter((n) => !n.startsWith("."));
|
|
@@ -26941,29 +27057,29 @@ var npm = defineCommand({
|
|
|
26941
27057
|
case "build": {
|
|
26942
27058
|
const scriptName = subcommand === "run" || subcommand === "run-script" ? rest[0] : subcommand;
|
|
26943
27059
|
const scriptArgs = subcommand === "run" || subcommand === "run-script" ? rest.slice(1) : rest;
|
|
26944
|
-
const
|
|
26945
|
-
if (!
|
|
27060
|
+
const found2 = readManifest(ctx, root);
|
|
27061
|
+
if (!found2) return ctx.fail("could not read package.json", 1);
|
|
26946
27062
|
if (scriptName === void 0) {
|
|
26947
|
-
ctx.line("Lifecycle scripts included in " + (
|
|
26948
|
-
for (const [name, body] of Object.entries(
|
|
27063
|
+
ctx.line("Lifecycle scripts included in " + (found2.manifest.name ?? "app") + ":");
|
|
27064
|
+
for (const [name, body] of Object.entries(found2.manifest.scripts ?? {})) {
|
|
26949
27065
|
ctx.line(` ${name}`);
|
|
26950
27066
|
ctx.line(` ${body}`);
|
|
26951
27067
|
}
|
|
26952
27068
|
return 0;
|
|
26953
27069
|
}
|
|
26954
|
-
const script =
|
|
27070
|
+
const script = found2.manifest.scripts?.[scriptName];
|
|
26955
27071
|
if (script === void 0) {
|
|
26956
|
-
if (scriptName === "start" &&
|
|
26957
|
-
return await runScript(ctx, root, `node ${
|
|
27072
|
+
if (scriptName === "start" && found2.manifest.main) {
|
|
27073
|
+
return await runScript(ctx, root, `node ${found2.manifest.main}`, scriptArgs, found2.manifest);
|
|
26958
27074
|
}
|
|
26959
27075
|
ctx.warn(`Missing script: "${scriptName}"`);
|
|
26960
27076
|
return 1;
|
|
26961
27077
|
}
|
|
26962
27078
|
ctx.line("");
|
|
26963
|
-
ctx.line(`> ${
|
|
27079
|
+
ctx.line(`> ${found2.manifest.name ?? "app"}@${found2.manifest.version ?? "1.0.0"} ${scriptName}`);
|
|
26964
27080
|
ctx.line(`> ${script}`);
|
|
26965
27081
|
ctx.line("");
|
|
26966
|
-
return await runScript(ctx, root, script, scriptArgs,
|
|
27082
|
+
return await runScript(ctx, root, script, scriptArgs, found2.manifest);
|
|
26967
27083
|
}
|
|
26968
27084
|
case "exec":
|
|
26969
27085
|
return await runScript(ctx, root, rest.join(" "), [], readManifest(ctx, root)?.manifest ?? {});
|
|
@@ -29399,23 +29515,23 @@ var CommonJsEngine = class {
|
|
|
29399
29515
|
const builtin = this.builtin(specifier);
|
|
29400
29516
|
if (builtin.found) return specifier;
|
|
29401
29517
|
if (specifier.startsWith("#")) {
|
|
29402
|
-
const
|
|
29403
|
-
if (
|
|
29518
|
+
const found2 = this.resolveImports(specifier, importer, kind);
|
|
29519
|
+
if (found2) return found2;
|
|
29404
29520
|
throw this.moduleNotFound(specifier, importer);
|
|
29405
29521
|
}
|
|
29406
29522
|
const baseDir = dirname(importer);
|
|
29407
29523
|
if (specifier.startsWith("/") || specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
29408
29524
|
const resolved = specifier.startsWith("/") ? clean(specifier) : resolve(baseDir, specifier);
|
|
29409
|
-
const
|
|
29410
|
-
if (
|
|
29525
|
+
const found2 = this.resolvePath(resolved, kind);
|
|
29526
|
+
if (found2) return found2;
|
|
29411
29527
|
} else {
|
|
29412
29528
|
const aliased = this.aliasFor(specifier);
|
|
29413
29529
|
if (aliased) {
|
|
29414
29530
|
const substituted = this.resolvePackage(aliased, baseDir, kind);
|
|
29415
29531
|
if (substituted) return substituted;
|
|
29416
29532
|
}
|
|
29417
|
-
const
|
|
29418
|
-
if (
|
|
29533
|
+
const found2 = this.resolvePackage(specifier, baseDir, kind);
|
|
29534
|
+
if (found2) return found2;
|
|
29419
29535
|
}
|
|
29420
29536
|
throw this.moduleNotFound(specifier, importer);
|
|
29421
29537
|
}
|
|
@@ -29581,8 +29697,8 @@ ${code}
|
|
|
29581
29697
|
continue;
|
|
29582
29698
|
}
|
|
29583
29699
|
for (const target of targets ?? []) {
|
|
29584
|
-
const
|
|
29585
|
-
if (
|
|
29700
|
+
const found2 = this.resolvePath(resolve(root, target), kind);
|
|
29701
|
+
if (found2) return found2;
|
|
29586
29702
|
}
|
|
29587
29703
|
}
|
|
29588
29704
|
return null;
|
|
@@ -29591,8 +29707,8 @@ ${code}
|
|
|
29591
29707
|
for (const field of ENTRY_FIELDS[kind]) {
|
|
29592
29708
|
const value = manifest?.[field];
|
|
29593
29709
|
if (typeof value === "string") {
|
|
29594
|
-
const
|
|
29595
|
-
if (
|
|
29710
|
+
const found2 = this.resolvePath(resolve(root, value), kind);
|
|
29711
|
+
if (found2) return found2;
|
|
29596
29712
|
}
|
|
29597
29713
|
}
|
|
29598
29714
|
return this.resolveIndex(root);
|
|
@@ -29615,8 +29731,8 @@ ${code}
|
|
|
29615
29731
|
continue;
|
|
29616
29732
|
}
|
|
29617
29733
|
for (const target of targets ?? []) {
|
|
29618
|
-
const
|
|
29619
|
-
if (
|
|
29734
|
+
const found2 = target.startsWith(".") ? this.resolvePath(resolve(root, target), kind) : this.resolvePackage(target, root, kind);
|
|
29735
|
+
if (found2) return found2;
|
|
29620
29736
|
}
|
|
29621
29737
|
}
|
|
29622
29738
|
return null;
|
|
@@ -36250,12 +36366,12 @@ async function loadNodeRolldownMemfsBinding() {
|
|
|
36250
36366
|
function resolveWorkerPath(node2) {
|
|
36251
36367
|
const { dirname: dirname3, existsSync, fileURLToPath: fileURLToPath2, join: join3 } = node2;
|
|
36252
36368
|
const here = dirname3(fileURLToPath2((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
36253
|
-
const
|
|
36369
|
+
const candidates2 = [
|
|
36254
36370
|
join3(here, WORKER_FILE),
|
|
36255
36371
|
/* src/tools → dist, for a checkout that has been built. */
|
|
36256
36372
|
join3(here, "..", "..", "dist", WORKER_FILE)
|
|
36257
36373
|
];
|
|
36258
|
-
return
|
|
36374
|
+
return candidates2.find((candidate) => existsSync(candidate)) ?? null;
|
|
36259
36375
|
}
|
|
36260
36376
|
function resolveSubpath(node2, require2, packageName, subpath) {
|
|
36261
36377
|
const { dirname: dirname3, join: join3, pathToFileURL: pathToFileURL2, readFileSync } = node2;
|
|
@@ -38609,17 +38725,17 @@ var Terminal = class {
|
|
|
38609
38725
|
const match2 = /(\S*)$/.exec(left);
|
|
38610
38726
|
const word = match2?.[1] ?? "";
|
|
38611
38727
|
const isFirstWord = left.slice(0, left.length - word.length).trim() === "";
|
|
38612
|
-
const
|
|
38613
|
-
if (
|
|
38614
|
-
if (
|
|
38615
|
-
const completion =
|
|
38728
|
+
const candidates2 = isFirstWord && !word.includes("/") ? this.completeCommand(word) : this.completePath(word);
|
|
38729
|
+
if (candidates2.length === 0) return;
|
|
38730
|
+
if (candidates2.length === 1) {
|
|
38731
|
+
const completion = candidates2[0];
|
|
38616
38732
|
const suffix = completion.slice(word.length);
|
|
38617
38733
|
this.buffer = this.buffer.slice(0, this.cursor) + suffix + this.buffer.slice(this.cursor);
|
|
38618
38734
|
this.cursor += suffix.length;
|
|
38619
38735
|
this.redraw();
|
|
38620
38736
|
return;
|
|
38621
38737
|
}
|
|
38622
|
-
const common = longestCommonPrefix(
|
|
38738
|
+
const common = longestCommonPrefix(candidates2);
|
|
38623
38739
|
if (common.length > word.length) {
|
|
38624
38740
|
const suffix = common.slice(word.length);
|
|
38625
38741
|
this.buffer = this.buffer.slice(0, this.cursor) + suffix + this.buffer.slice(this.cursor);
|
|
@@ -38627,7 +38743,7 @@ var Terminal = class {
|
|
|
38627
38743
|
this.redraw();
|
|
38628
38744
|
return;
|
|
38629
38745
|
}
|
|
38630
|
-
this.write("\r\n" + formatColumns(
|
|
38746
|
+
this.write("\r\n" + formatColumns(candidates2, this.columns) + "\r\n");
|
|
38631
38747
|
this.redraw();
|
|
38632
38748
|
}
|
|
38633
38749
|
completeCommand(word) {
|