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.js
CHANGED
|
@@ -605,32 +605,32 @@ var init_variables = __esm({
|
|
|
605
605
|
return this.find(name) !== void 0;
|
|
606
606
|
}
|
|
607
607
|
get(name) {
|
|
608
|
-
const
|
|
609
|
-
if (!
|
|
610
|
-
if (
|
|
611
|
-
return
|
|
608
|
+
const found2 = this.find(name);
|
|
609
|
+
if (!found2) return void 0;
|
|
610
|
+
if (found2.entry.array) return found2.entry.array[0] ?? "";
|
|
611
|
+
return found2.entry.value;
|
|
612
612
|
}
|
|
613
613
|
entry(name) {
|
|
614
614
|
return this.find(name)?.entry;
|
|
615
615
|
}
|
|
616
616
|
getArray(name) {
|
|
617
|
-
const
|
|
618
|
-
if (!
|
|
619
|
-
return
|
|
617
|
+
const found2 = this.find(name);
|
|
618
|
+
if (!found2) return void 0;
|
|
619
|
+
return found2.entry.array ?? [found2.entry.value];
|
|
620
620
|
}
|
|
621
621
|
isArray(name) {
|
|
622
622
|
return this.find(name)?.entry.array !== void 0;
|
|
623
623
|
}
|
|
624
624
|
set(name, value, attrs = {}) {
|
|
625
|
-
const
|
|
626
|
-
if (
|
|
625
|
+
const found2 = this.find(name);
|
|
626
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
627
627
|
let next = value;
|
|
628
|
-
if (
|
|
629
|
-
if (
|
|
630
|
-
if (
|
|
631
|
-
|
|
632
|
-
delete
|
|
633
|
-
Object.assign(
|
|
628
|
+
if (found2?.entry.upper || attrs.upper) next = next.toUpperCase();
|
|
629
|
+
if (found2?.entry.lower || attrs.lower) next = next.toLowerCase();
|
|
630
|
+
if (found2) {
|
|
631
|
+
found2.entry.value = next;
|
|
632
|
+
delete found2.entry.array;
|
|
633
|
+
Object.assign(found2.entry, attrs);
|
|
634
634
|
} else {
|
|
635
635
|
this.scopes[this.scopes.length - 1].set(name, { value: next, ...attrs });
|
|
636
636
|
}
|
|
@@ -640,28 +640,28 @@ var init_variables = __esm({
|
|
|
640
640
|
this.scopes[this.scopes.length - 1].set(name, { value, ...attrs });
|
|
641
641
|
}
|
|
642
642
|
setArray(name, values, attrs = {}) {
|
|
643
|
-
const
|
|
644
|
-
if (
|
|
645
|
-
if (
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
Object.assign(
|
|
643
|
+
const found2 = this.find(name);
|
|
644
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
645
|
+
if (found2) {
|
|
646
|
+
found2.entry.array = values.slice();
|
|
647
|
+
found2.entry.value = values[0] ?? "";
|
|
648
|
+
Object.assign(found2.entry, attrs);
|
|
649
649
|
} else {
|
|
650
650
|
this.scopes[this.scopes.length - 1].set(name, { value: values[0] ?? "", array: values.slice(), ...attrs });
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
653
|
setIndex(name, index, value) {
|
|
654
|
-
const
|
|
655
|
-
if (
|
|
656
|
-
const arr =
|
|
654
|
+
const found2 = this.find(name);
|
|
655
|
+
if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
|
|
656
|
+
const arr = found2?.entry.array ?? (found2 ? [found2.entry.value] : []);
|
|
657
657
|
while (arr.length < index) arr.push("");
|
|
658
658
|
arr[index] = value;
|
|
659
659
|
this.setArray(name, arr);
|
|
660
660
|
}
|
|
661
661
|
append(name, value) {
|
|
662
|
-
const
|
|
663
|
-
if (
|
|
664
|
-
this.setArray(name, [...
|
|
662
|
+
const found2 = this.find(name);
|
|
663
|
+
if (found2?.entry.array) {
|
|
664
|
+
this.setArray(name, [...found2.entry.array, value]);
|
|
665
665
|
return;
|
|
666
666
|
}
|
|
667
667
|
this.set(name, (this.get(name) ?? "") + value);
|
|
@@ -678,13 +678,13 @@ var init_variables = __esm({
|
|
|
678
678
|
return false;
|
|
679
679
|
}
|
|
680
680
|
export(name, exported = true) {
|
|
681
|
-
const
|
|
682
|
-
if (
|
|
681
|
+
const found2 = this.find(name);
|
|
682
|
+
if (found2) found2.entry.exported = exported;
|
|
683
683
|
else this.scopes[this.scopes.length - 1].set(name, { value: "", exported });
|
|
684
684
|
}
|
|
685
685
|
markReadonly(name) {
|
|
686
|
-
const
|
|
687
|
-
if (
|
|
686
|
+
const found2 = this.find(name);
|
|
687
|
+
if (found2) found2.entry.readonly = true;
|
|
688
688
|
else this.scopes[this.scopes.length - 1].set(name, { value: "", readonly: true });
|
|
689
689
|
}
|
|
690
690
|
names() {
|
|
@@ -2930,8 +2930,8 @@ async function builtinSource({ shell, argv, io }) {
|
|
|
2930
2930
|
}
|
|
2931
2931
|
let path = resolve(shell.cwd, target);
|
|
2932
2932
|
if (!target.includes("/")) {
|
|
2933
|
-
const
|
|
2934
|
-
if (
|
|
2933
|
+
const found2 = shell.kernel.which(target, shell.cwd, shell.vars.environment(), shell.cred);
|
|
2934
|
+
if (found2) path = found2;
|
|
2935
2935
|
}
|
|
2936
2936
|
let text2;
|
|
2937
2937
|
try {
|
|
@@ -3565,32 +3565,32 @@ function builtinType({ shell, argv, io }) {
|
|
|
3565
3565
|
const names = args.filter((a) => !a.startsWith("-"));
|
|
3566
3566
|
let status = 0;
|
|
3567
3567
|
for (const name of names) {
|
|
3568
|
-
const
|
|
3568
|
+
const found2 = [];
|
|
3569
3569
|
if (shell.aliases.has(name)) {
|
|
3570
|
-
if (typeOnly)
|
|
3571
|
-
else if (!pathOnly)
|
|
3570
|
+
if (typeOnly) found2.push("alias");
|
|
3571
|
+
else if (!pathOnly) found2.push(`${name} is aliased to \`${shell.aliases.get(name)}'`);
|
|
3572
3572
|
}
|
|
3573
3573
|
if (shell.functions.has(name)) {
|
|
3574
|
-
if (typeOnly)
|
|
3575
|
-
else if (!pathOnly)
|
|
3574
|
+
if (typeOnly) found2.push("function");
|
|
3575
|
+
else if (!pathOnly) found2.push(`${name} is a function`);
|
|
3576
3576
|
}
|
|
3577
3577
|
if (isBuiltinName(name)) {
|
|
3578
|
-
if (typeOnly)
|
|
3579
|
-
else if (!pathOnly)
|
|
3578
|
+
if (typeOnly) found2.push("builtin");
|
|
3579
|
+
else if (!pathOnly) found2.push(`${name} is a shell builtin`);
|
|
3580
3580
|
}
|
|
3581
3581
|
const path = shell.kernel.which(name, shell.cwd, shell.vars.environment(), shell.cred);
|
|
3582
3582
|
if (path) {
|
|
3583
|
-
if (typeOnly)
|
|
3584
|
-
else if (pathOnly)
|
|
3585
|
-
else
|
|
3583
|
+
if (typeOnly) found2.push("file");
|
|
3584
|
+
else if (pathOnly) found2.push(path);
|
|
3585
|
+
else found2.push(`${name} is ${path}`);
|
|
3586
3586
|
}
|
|
3587
|
-
if (
|
|
3587
|
+
if (found2.length === 0) {
|
|
3588
3588
|
if (!pathOnly && !typeOnly) io.stderr.write(`type: ${name}: not found
|
|
3589
3589
|
`);
|
|
3590
3590
|
status = 1;
|
|
3591
3591
|
continue;
|
|
3592
3592
|
}
|
|
3593
|
-
for (const line of all ?
|
|
3593
|
+
for (const line of all ? found2 : [found2[0]]) io.stdout.write(line + "\n");
|
|
3594
3594
|
}
|
|
3595
3595
|
return status;
|
|
3596
3596
|
}
|
|
@@ -5947,9 +5947,9 @@ function parseArgs(argv, specs, opts = {}) {
|
|
|
5947
5947
|
const resolveLong = (name) => {
|
|
5948
5948
|
const exact = byLong.get(name);
|
|
5949
5949
|
if (exact) return exact;
|
|
5950
|
-
const
|
|
5951
|
-
if (
|
|
5952
|
-
if (
|
|
5950
|
+
const candidates2 = [...byLong.keys()].filter((k) => k.startsWith(name));
|
|
5951
|
+
if (candidates2.length === 1) return byLong.get(candidates2[0]);
|
|
5952
|
+
if (candidates2.length > 1) throw new UsageError(`option '--${name}' is ambiguous`);
|
|
5953
5953
|
return void 0;
|
|
5954
5954
|
};
|
|
5955
5955
|
for (; i < argv.length; i++) {
|
|
@@ -6468,19 +6468,19 @@ var WasiHost = class {
|
|
|
6468
6468
|
}
|
|
6469
6469
|
// ── descriptors ──────────────────────────────────────────────────────────
|
|
6470
6470
|
get(fd) {
|
|
6471
|
-
const
|
|
6472
|
-
if (!
|
|
6473
|
-
return
|
|
6471
|
+
const found2 = this.fds.get(fd);
|
|
6472
|
+
if (!found2) throw new WasiError(WASI_EBADF);
|
|
6473
|
+
return found2;
|
|
6474
6474
|
}
|
|
6475
6475
|
dir(fd) {
|
|
6476
|
-
const
|
|
6477
|
-
if (
|
|
6478
|
-
return
|
|
6476
|
+
const found2 = this.get(fd);
|
|
6477
|
+
if (found2.kind !== "dir") throw new WasiError(WASI_ENOTDIR);
|
|
6478
|
+
return found2;
|
|
6479
6479
|
}
|
|
6480
6480
|
file(fd) {
|
|
6481
|
-
const
|
|
6482
|
-
if (
|
|
6483
|
-
return
|
|
6481
|
+
const found2 = this.get(fd);
|
|
6482
|
+
if (found2.kind !== "file") throw new WasiError(WASI_EBADF);
|
|
6483
|
+
return found2;
|
|
6484
6484
|
}
|
|
6485
6485
|
/**
|
|
6486
6486
|
* Resolve a guest path against a directory descriptor.
|
|
@@ -7425,13 +7425,13 @@ var Kernel = class {
|
|
|
7425
7425
|
* Find `name` the way `execvp` does. Returns null when nothing matches.
|
|
7426
7426
|
*/
|
|
7427
7427
|
resolveExecutable(name, cwd, env2, cred = ROOT_CRED) {
|
|
7428
|
-
const
|
|
7428
|
+
const candidates2 = [];
|
|
7429
7429
|
if (name.includes("/")) {
|
|
7430
|
-
|
|
7430
|
+
candidates2.push(resolve(cwd, name));
|
|
7431
7431
|
} else {
|
|
7432
|
-
for (const dir3 of this.pathDirs(env2))
|
|
7432
|
+
for (const dir3 of this.pathDirs(env2)) candidates2.push(join(dir3, name));
|
|
7433
7433
|
}
|
|
7434
|
-
for (const candidate of
|
|
7434
|
+
for (const candidate of candidates2) {
|
|
7435
7435
|
let real;
|
|
7436
7436
|
try {
|
|
7437
7437
|
real = this.vfs.realpath(candidate, cred);
|
|
@@ -8407,10 +8407,50 @@ function isBrowser() {
|
|
|
8407
8407
|
}
|
|
8408
8408
|
function browserBlocked(hostname, message) {
|
|
8409
8409
|
return new Error(
|
|
8410
|
-
`${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.
|
|
8410
|
+
`${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.`
|
|
8411
8411
|
);
|
|
8412
8412
|
}
|
|
8413
8413
|
|
|
8414
|
+
// src/net/discover-egress.ts
|
|
8415
|
+
var EGRESS_PATH = "/__sandboxedjs__/egress";
|
|
8416
|
+
var EGRESS_MARKER = { sandboxedjs: "egress", protocol: 1 };
|
|
8417
|
+
var CLI_PORT = 4181;
|
|
8418
|
+
var found = null;
|
|
8419
|
+
var PROBE_TIMEOUT_MS = 1500;
|
|
8420
|
+
async function isEgress(url, fetchImpl) {
|
|
8421
|
+
const control = new AbortController();
|
|
8422
|
+
const timer = setTimeout(() => control.abort(), PROBE_TIMEOUT_MS);
|
|
8423
|
+
try {
|
|
8424
|
+
const answer = await fetchImpl(url, { method: "GET", signal: control.signal });
|
|
8425
|
+
if (!answer.ok) return false;
|
|
8426
|
+
const payload = await answer.json();
|
|
8427
|
+
return payload?.sandboxedjs === EGRESS_MARKER.sandboxedjs;
|
|
8428
|
+
} catch {
|
|
8429
|
+
return false;
|
|
8430
|
+
} finally {
|
|
8431
|
+
clearTimeout(timer);
|
|
8432
|
+
}
|
|
8433
|
+
}
|
|
8434
|
+
function candidates() {
|
|
8435
|
+
const origin = globalThis.location?.origin;
|
|
8436
|
+
const list = [];
|
|
8437
|
+
if (origin && /^https?:/.test(origin)) list.push(`${origin}${EGRESS_PATH}`);
|
|
8438
|
+
list.push(`http://127.0.0.1:${CLI_PORT}/`);
|
|
8439
|
+
return list;
|
|
8440
|
+
}
|
|
8441
|
+
async function discoverEgress(fetchImpl = fetch) {
|
|
8442
|
+
if (!isBrowser()) return null;
|
|
8443
|
+
if (!found) {
|
|
8444
|
+
found = (async () => {
|
|
8445
|
+
for (const candidate of candidates()) {
|
|
8446
|
+
if (await isEgress(candidate, fetchImpl)) return candidate;
|
|
8447
|
+
}
|
|
8448
|
+
return null;
|
|
8449
|
+
})();
|
|
8450
|
+
}
|
|
8451
|
+
return await found;
|
|
8452
|
+
}
|
|
8453
|
+
|
|
8414
8454
|
// src/net/policy.ts
|
|
8415
8455
|
function isLoopbackHostname(hostname) {
|
|
8416
8456
|
const host2 = hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
@@ -8453,7 +8493,8 @@ function policedFetch(policy, fetchImpl) {
|
|
|
8453
8493
|
if (!outboundAllowed(policy, url)) {
|
|
8454
8494
|
throw Object.assign(new TypeError("fetch failed"), { cause: outboundBlockedError(url) });
|
|
8455
8495
|
}
|
|
8456
|
-
|
|
8496
|
+
const proxy = policy.proxy ?? await discoverEgress(fetchImpl);
|
|
8497
|
+
if (proxy) return await fetchThroughProxy(proxy, fetchImpl, input, init);
|
|
8457
8498
|
try {
|
|
8458
8499
|
return await fetchImpl(input, init);
|
|
8459
8500
|
} catch (error) {
|
|
@@ -8989,7 +9030,7 @@ var Lexer = class _Lexer {
|
|
|
8989
9030
|
const quoted = /['"\\]/.test(rawTag);
|
|
8990
9031
|
const tag2 = rawTag.replace(/['"\\]/g, "");
|
|
8991
9032
|
const lines = [];
|
|
8992
|
-
let
|
|
9033
|
+
let found2 = false;
|
|
8993
9034
|
while (this.pos < this.src.length) {
|
|
8994
9035
|
let eol = this.src.indexOf("\n", this.pos);
|
|
8995
9036
|
if (eol < 0) eol = this.src.length;
|
|
@@ -8997,13 +9038,13 @@ var Lexer = class _Lexer {
|
|
|
8997
9038
|
this.pos = eol + 1;
|
|
8998
9039
|
const compare = stripTabs ? rawLine.replace(/^\t+/, "") : rawLine;
|
|
8999
9040
|
if (compare === tag2) {
|
|
9000
|
-
|
|
9041
|
+
found2 = true;
|
|
9001
9042
|
break;
|
|
9002
9043
|
}
|
|
9003
9044
|
lines.push(stripTabs ? rawLine.replace(/^\t+/, "") : rawLine);
|
|
9004
9045
|
if (eol >= this.src.length) break;
|
|
9005
9046
|
}
|
|
9006
|
-
if (!
|
|
9047
|
+
if (!found2) {
|
|
9007
9048
|
throw new IncompleteInputError(`here-document delimited by end-of-file (wanted \`${tag2}')`, opToken.pos);
|
|
9008
9049
|
}
|
|
9009
9050
|
opToken.heredoc = { tag: tag2, stripTabs, quoted, body: lines.length ? lines.join("\n") + "\n" : "" };
|
|
@@ -14458,8 +14499,8 @@ var Interpreter = class {
|
|
|
14458
14499
|
for (let i = this.locals.length - 1; i >= 0; i--) {
|
|
14459
14500
|
const scope = this.locals[i];
|
|
14460
14501
|
if (scope.has(name)) {
|
|
14461
|
-
const
|
|
14462
|
-
return
|
|
14502
|
+
const found2 = scope.get(name);
|
|
14503
|
+
return found2 instanceof Map ? Value.uninitialized : found2;
|
|
14463
14504
|
}
|
|
14464
14505
|
}
|
|
14465
14506
|
if (name === "NF") {
|
|
@@ -14491,8 +14532,8 @@ var Interpreter = class {
|
|
|
14491
14532
|
for (let i = this.locals.length - 1; i >= 0; i--) {
|
|
14492
14533
|
const scope = this.locals[i];
|
|
14493
14534
|
if (scope.has(name)) {
|
|
14494
|
-
const
|
|
14495
|
-
if (
|
|
14535
|
+
const found2 = scope.get(name);
|
|
14536
|
+
if (found2 instanceof Map) return found2;
|
|
14496
14537
|
const created = /* @__PURE__ */ new Map();
|
|
14497
14538
|
scope.set(name, created);
|
|
14498
14539
|
return created;
|
|
@@ -17570,7 +17611,7 @@ async function performRequest(ctx, url, init) {
|
|
|
17570
17611
|
`outbound network access to ${url.hostname} is disabled for this container (enable with network: { allowOutbound: true })`
|
|
17571
17612
|
);
|
|
17572
17613
|
}
|
|
17573
|
-
const proxy = ctx.kernel.net.proxy;
|
|
17614
|
+
const proxy = ctx.kernel.net.proxy ?? await discoverEgress();
|
|
17574
17615
|
if (proxy) {
|
|
17575
17616
|
const result = await proxyExchange(proxy, {
|
|
17576
17617
|
url: url.toString(),
|
|
@@ -18541,14 +18582,14 @@ var apropos = defineCommand({
|
|
|
18541
18582
|
return 1;
|
|
18542
18583
|
}
|
|
18543
18584
|
const patterns = ctx.args.map((a) => new RegExp(a, "i"));
|
|
18544
|
-
let
|
|
18585
|
+
let found2 = 0;
|
|
18545
18586
|
for (const command of ctx.kernel.commands.all()) {
|
|
18546
18587
|
const haystack = `${command.name} ${command.summary ?? ""}`;
|
|
18547
18588
|
if (!patterns.some((p) => p.test(haystack))) continue;
|
|
18548
|
-
|
|
18589
|
+
found2++;
|
|
18549
18590
|
ctx.line(`${command.name} (1)${" ".repeat(Math.max(1, 16 - command.name.length))}- ${command.summary ?? ""}`);
|
|
18550
18591
|
}
|
|
18551
|
-
if (
|
|
18592
|
+
if (found2 === 0) {
|
|
18552
18593
|
ctx.line(`${ctx.args.join(" ")}: nothing appropriate.`);
|
|
18553
18594
|
return 1;
|
|
18554
18595
|
}
|
|
@@ -19572,8 +19613,8 @@ ${prelude}${preloadRequires(preloads)}${source}
|
|
|
19572
19613
|
}
|
|
19573
19614
|
function resolveScript(ctx, operand) {
|
|
19574
19615
|
const base2 = ctx.path(operand);
|
|
19575
|
-
const
|
|
19576
|
-
for (const candidate of
|
|
19616
|
+
const candidates2 = [base2, `${base2}.js`, `${base2}.mjs`, `${base2}.cjs`, `${base2}.json`];
|
|
19617
|
+
for (const candidate of candidates2) {
|
|
19577
19618
|
try {
|
|
19578
19619
|
const st = ctx.vfs.stat(candidate, { cred: ctx.cred });
|
|
19579
19620
|
if (st.isFile()) return ctx.vfs.realpath(candidate, ctx.cred);
|
|
@@ -21040,7 +21081,7 @@ var wheels_default = {
|
|
|
21040
21081
|
|
|
21041
21082
|
// package.json
|
|
21042
21083
|
var package_default = {
|
|
21043
|
-
version: "0.2.
|
|
21084
|
+
version: "0.2.7"};
|
|
21044
21085
|
|
|
21045
21086
|
// src/python/extension-abi.ts
|
|
21046
21087
|
var EXTENSION_ABI = {
|
|
@@ -22705,8 +22746,12 @@ function createHostAbiServer(proc) {
|
|
|
22705
22746
|
}
|
|
22706
22747
|
case Op.resolve: {
|
|
22707
22748
|
const sockets = proc.sockets;
|
|
22749
|
+
const name = r.string();
|
|
22750
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
22751
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
22752
|
+
}
|
|
22708
22753
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
22709
|
-
const address = sockets.outbound.resolve(
|
|
22754
|
+
const address = sockets.outbound.resolve(name);
|
|
22710
22755
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
22711
22756
|
}
|
|
22712
22757
|
case Op.send: {
|
|
@@ -23908,7 +23953,7 @@ function explain(name, constraints, chosenVersion, available2 = []) {
|
|
|
23908
23953
|
return lines;
|
|
23909
23954
|
}
|
|
23910
23955
|
async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, rejected = { versions: /* @__PURE__ */ new Set(), sourceAvailable: false }) {
|
|
23911
|
-
const
|
|
23956
|
+
const candidates2 = [];
|
|
23912
23957
|
if (prebuilt) assertIndexUsable(prebuilt);
|
|
23913
23958
|
for (const wheel of prebuilt?.wheels ?? []) {
|
|
23914
23959
|
if (normalize2(wheel.name) !== normalize2(name)) continue;
|
|
@@ -23917,7 +23962,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23917
23962
|
`${wheel.filename} in the wheel index was built for ABI ${wheel.abiId}, but this runtime implements ${EXTENSION_ABI.abiId}; rebuild it`
|
|
23918
23963
|
);
|
|
23919
23964
|
}
|
|
23920
|
-
|
|
23965
|
+
candidates2.push({
|
|
23921
23966
|
name: normalize2(wheel.name),
|
|
23922
23967
|
version: wheel.version,
|
|
23923
23968
|
kind: "sbx-wasm",
|
|
@@ -23928,13 +23973,13 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23928
23973
|
indexedRequires: wheel.requires
|
|
23929
23974
|
});
|
|
23930
23975
|
}
|
|
23931
|
-
|
|
23932
|
-
if (isBuiltinOnly(normalize2(name))) return
|
|
23976
|
+
candidates2.push(...builtinCandidates(normalize2(name)));
|
|
23977
|
+
if (isBuiltinOnly(normalize2(name))) return candidates2;
|
|
23933
23978
|
let index;
|
|
23934
23979
|
try {
|
|
23935
23980
|
index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
|
|
23936
23981
|
} catch (error) {
|
|
23937
|
-
if (
|
|
23982
|
+
if (candidates2.length > 0) return candidates2;
|
|
23938
23983
|
throw error;
|
|
23939
23984
|
}
|
|
23940
23985
|
for (const [version, files] of Object.entries(index.releases ?? {})) {
|
|
@@ -23947,7 +23992,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23947
23992
|
rejected.versions.add(version);
|
|
23948
23993
|
continue;
|
|
23949
23994
|
}
|
|
23950
|
-
|
|
23995
|
+
candidates2.push({
|
|
23951
23996
|
name: normalize2(name),
|
|
23952
23997
|
version,
|
|
23953
23998
|
kind,
|
|
@@ -23958,7 +24003,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
|
|
|
23958
24003
|
});
|
|
23959
24004
|
}
|
|
23960
24005
|
}
|
|
23961
|
-
return
|
|
24006
|
+
return candidates2;
|
|
23962
24007
|
}
|
|
23963
24008
|
function newest(versions) {
|
|
23964
24009
|
return versions.reduce((a, b) => compareVersions(b, a, ">") ? b : a);
|
|
@@ -24255,17 +24300,17 @@ function createProcessService(ctx) {
|
|
|
24255
24300
|
return proc.pid;
|
|
24256
24301
|
},
|
|
24257
24302
|
async wait(pid, options) {
|
|
24258
|
-
const
|
|
24259
|
-
if (
|
|
24303
|
+
const candidates2 = pid > 0 ? [children.get(pid)].filter((p) => p !== void 0) : [...children.values()];
|
|
24304
|
+
if (candidates2.length === 0) throw new PosixError(Errno.ECHILD);
|
|
24260
24305
|
const reap = (proc) => {
|
|
24261
24306
|
children.delete(proc.pid);
|
|
24262
24307
|
return { pid: proc.pid, status: waitStatus(proc) };
|
|
24263
24308
|
};
|
|
24264
|
-
const done =
|
|
24309
|
+
const done = candidates2.find(exited);
|
|
24265
24310
|
if (done) return reap(done);
|
|
24266
24311
|
if (options & WNOHANG) return { pid: 0, status: 0 };
|
|
24267
|
-
await Promise.race(
|
|
24268
|
-
const finished =
|
|
24312
|
+
await Promise.race(candidates2.map((proc) => proc.wait()));
|
|
24313
|
+
const finished = candidates2.find(exited);
|
|
24269
24314
|
if (!finished) throw new PosixError(Errno.ECHILD);
|
|
24270
24315
|
return reap(finished);
|
|
24271
24316
|
},
|
|
@@ -24833,6 +24878,77 @@ if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1":
|
|
|
24833
24878
|
sys.meta_path.insert(0, _SbxTruststoreHook())
|
|
24834
24879
|
|
|
24835
24880
|
|
|
24881
|
+
# Literal addresses are answered here rather than through the host.
|
|
24882
|
+
#
|
|
24883
|
+
# The container's resolver is a host call, and a container with no outbound
|
|
24884
|
+
# sockets configured has no resolver to call: it answers ENOSYS. That is the
|
|
24885
|
+
# right answer for a name, but the egress hop below dials 127.0.0.1, and
|
|
24886
|
+
# http.client calls getaddrinfo even for an address that needs no resolving --
|
|
24887
|
+
# so every request through the egress died with "Function not implemented"
|
|
24888
|
+
# before it reached the endpoint. A numeric address (and loopback by its usual
|
|
24889
|
+
# names) is now formed here, which is what a resolver would have returned.
|
|
24890
|
+
def _sbx_local_addresses():
|
|
24891
|
+
import socket as _socket_module
|
|
24892
|
+
import _socket as _socket_native
|
|
24893
|
+
|
|
24894
|
+
# The native entry point, not socket.getaddrinfo: the stdlib wrapper
|
|
24895
|
+
# delegates to _socket, so wrapping the wrapper and replacing _socket with
|
|
24896
|
+
# the wrapper makes the two call each other forever.
|
|
24897
|
+
_real_getaddrinfo = _socket_native.getaddrinfo
|
|
24898
|
+
|
|
24899
|
+
_literals = {"localhost": "127.0.0.1", "localhost.localdomain": "127.0.0.1",
|
|
24900
|
+
"ip6-localhost": "127.0.0.1"}
|
|
24901
|
+
|
|
24902
|
+
def _literal(host):
|
|
24903
|
+
"""The address host already is, or None when it needs a resolver."""
|
|
24904
|
+
if isinstance(host, (bytes, bytearray)):
|
|
24905
|
+
host = bytes(host).decode("ascii", "replace")
|
|
24906
|
+
if host is None:
|
|
24907
|
+
return None
|
|
24908
|
+
host = _literals.get(host.lower(), host)
|
|
24909
|
+
parts = host.split(".")
|
|
24910
|
+
if len(parts) != 4:
|
|
24911
|
+
return None
|
|
24912
|
+
for part in parts:
|
|
24913
|
+
if not part.isdigit() or len(part) > 3 or int(part) > 255:
|
|
24914
|
+
return None
|
|
24915
|
+
return host
|
|
24916
|
+
|
|
24917
|
+
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
|
|
24918
|
+
address = _literal(host)
|
|
24919
|
+
if address is None:
|
|
24920
|
+
return _real_getaddrinfo(host, port, family, type, proto, flags)
|
|
24921
|
+
if isinstance(port, (bytes, bytearray)):
|
|
24922
|
+
port = bytes(port).decode("ascii", "replace")
|
|
24923
|
+
if isinstance(port, str):
|
|
24924
|
+
port = int(port) if port.isdigit() else _socket_module.getservbyname(port)
|
|
24925
|
+
if port is None:
|
|
24926
|
+
port = 0
|
|
24927
|
+
if family not in (0, _socket_module.AF_UNSPEC, _socket_module.AF_INET):
|
|
24928
|
+
raise _socket_module.gaierror(
|
|
24929
|
+
_socket_module.EAI_FAMILY, "only AF_INET is supported in this container"
|
|
24930
|
+
)
|
|
24931
|
+
kind = type or _socket_module.SOCK_STREAM
|
|
24932
|
+
protocol = proto or (_socket_module.IPPROTO_TCP
|
|
24933
|
+
if kind == _socket_module.SOCK_STREAM else 0)
|
|
24934
|
+
return [(_socket_module.AF_INET, kind, protocol, "", (address, int(port)))]
|
|
24935
|
+
|
|
24936
|
+
def gethostbyname(host):
|
|
24937
|
+
return getaddrinfo(host, 0)[0][4][0]
|
|
24938
|
+
|
|
24939
|
+
def gethostbyname_ex(host):
|
|
24940
|
+
return (host, [], [gethostbyname(host)])
|
|
24941
|
+
|
|
24942
|
+
_socket_module.getaddrinfo = getaddrinfo
|
|
24943
|
+
_socket_module.gethostbyname = gethostbyname
|
|
24944
|
+
_socket_module.gethostbyname_ex = gethostbyname_ex
|
|
24945
|
+
_socket_native.getaddrinfo = getaddrinfo
|
|
24946
|
+
_socket_native.gethostbyname = gethostbyname
|
|
24947
|
+
_socket_native.gethostbyname_ex = gethostbyname_ex
|
|
24948
|
+
|
|
24949
|
+
|
|
24950
|
+
_sbx_local_addresses()
|
|
24951
|
+
|
|
24836
24952
|
_egress = None if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1" else os.environ.get("SBX_HTTP_EGRESS")
|
|
24837
24953
|
if _egress:
|
|
24838
24954
|
import http.client
|
|
@@ -26422,9 +26538,9 @@ function resolveVersion(metadata, range) {
|
|
|
26422
26538
|
const tag2 = metadata["dist-tags"]?.[range];
|
|
26423
26539
|
if (tag2) return tag2;
|
|
26424
26540
|
if (valid(range) && metadata.versions[range]) return range;
|
|
26425
|
-
const
|
|
26426
|
-
if (!
|
|
26427
|
-
return
|
|
26541
|
+
const found2 = maxSatisfying(Object.keys(metadata.versions), range === "latest" ? "*" : range, { includePrerelease: false });
|
|
26542
|
+
if (!found2) throw new Error(`No matching version found for ${metadata.name}@${range}`);
|
|
26543
|
+
return found2;
|
|
26428
26544
|
}
|
|
26429
26545
|
function verifyIntegrity(data, integrity, shasum, identity) {
|
|
26430
26546
|
if (integrity) {
|
|
@@ -26886,23 +27002,23 @@ var npm = defineCommand({
|
|
|
26886
27002
|
case "uninstall":
|
|
26887
27003
|
case "remove":
|
|
26888
27004
|
case "rm": {
|
|
26889
|
-
const
|
|
27005
|
+
const found2 = readManifest(ctx, root);
|
|
26890
27006
|
for (const name of rest.filter((a) => !a.startsWith("-"))) {
|
|
26891
27007
|
const target = join(root, "node_modules", name);
|
|
26892
27008
|
if (ctx.vfs.lexists(target)) ctx.vfs.rmrf(target, ctx.cred);
|
|
26893
|
-
if (
|
|
26894
|
-
delete
|
|
26895
|
-
delete
|
|
27009
|
+
if (found2) {
|
|
27010
|
+
delete found2.manifest.dependencies?.[name];
|
|
27011
|
+
delete found2.manifest.devDependencies?.[name];
|
|
26896
27012
|
}
|
|
26897
27013
|
ctx.line(`removed ${name}`);
|
|
26898
27014
|
}
|
|
26899
|
-
if (
|
|
27015
|
+
if (found2) writeManifest(ctx, found2.path, found2.manifest);
|
|
26900
27016
|
return 0;
|
|
26901
27017
|
}
|
|
26902
27018
|
case "ls":
|
|
26903
27019
|
case "list": {
|
|
26904
|
-
const
|
|
26905
|
-
ctx.line(`${
|
|
27020
|
+
const found2 = readManifest(ctx, root);
|
|
27021
|
+
ctx.line(`${found2?.manifest.name ?? basename(root)}@${found2?.manifest.version ?? "1.0.0"} ${root}`);
|
|
26906
27022
|
const modules = join(root, "node_modules");
|
|
26907
27023
|
if (!ctx.vfs.lexists(modules)) return 0;
|
|
26908
27024
|
const names = ctx.vfs.readdir(modules, ctx.cred).filter((n) => !n.startsWith("."));
|
|
@@ -26924,29 +27040,29 @@ var npm = defineCommand({
|
|
|
26924
27040
|
case "build": {
|
|
26925
27041
|
const scriptName = subcommand === "run" || subcommand === "run-script" ? rest[0] : subcommand;
|
|
26926
27042
|
const scriptArgs = subcommand === "run" || subcommand === "run-script" ? rest.slice(1) : rest;
|
|
26927
|
-
const
|
|
26928
|
-
if (!
|
|
27043
|
+
const found2 = readManifest(ctx, root);
|
|
27044
|
+
if (!found2) return ctx.fail("could not read package.json", 1);
|
|
26929
27045
|
if (scriptName === void 0) {
|
|
26930
|
-
ctx.line("Lifecycle scripts included in " + (
|
|
26931
|
-
for (const [name, body] of Object.entries(
|
|
27046
|
+
ctx.line("Lifecycle scripts included in " + (found2.manifest.name ?? "app") + ":");
|
|
27047
|
+
for (const [name, body] of Object.entries(found2.manifest.scripts ?? {})) {
|
|
26932
27048
|
ctx.line(` ${name}`);
|
|
26933
27049
|
ctx.line(` ${body}`);
|
|
26934
27050
|
}
|
|
26935
27051
|
return 0;
|
|
26936
27052
|
}
|
|
26937
|
-
const script =
|
|
27053
|
+
const script = found2.manifest.scripts?.[scriptName];
|
|
26938
27054
|
if (script === void 0) {
|
|
26939
|
-
if (scriptName === "start" &&
|
|
26940
|
-
return await runScript(ctx, root, `node ${
|
|
27055
|
+
if (scriptName === "start" && found2.manifest.main) {
|
|
27056
|
+
return await runScript(ctx, root, `node ${found2.manifest.main}`, scriptArgs, found2.manifest);
|
|
26941
27057
|
}
|
|
26942
27058
|
ctx.warn(`Missing script: "${scriptName}"`);
|
|
26943
27059
|
return 1;
|
|
26944
27060
|
}
|
|
26945
27061
|
ctx.line("");
|
|
26946
|
-
ctx.line(`> ${
|
|
27062
|
+
ctx.line(`> ${found2.manifest.name ?? "app"}@${found2.manifest.version ?? "1.0.0"} ${scriptName}`);
|
|
26947
27063
|
ctx.line(`> ${script}`);
|
|
26948
27064
|
ctx.line("");
|
|
26949
|
-
return await runScript(ctx, root, script, scriptArgs,
|
|
27065
|
+
return await runScript(ctx, root, script, scriptArgs, found2.manifest);
|
|
26950
27066
|
}
|
|
26951
27067
|
case "exec":
|
|
26952
27068
|
return await runScript(ctx, root, rest.join(" "), [], readManifest(ctx, root)?.manifest ?? {});
|
|
@@ -29382,23 +29498,23 @@ var CommonJsEngine = class {
|
|
|
29382
29498
|
const builtin = this.builtin(specifier);
|
|
29383
29499
|
if (builtin.found) return specifier;
|
|
29384
29500
|
if (specifier.startsWith("#")) {
|
|
29385
|
-
const
|
|
29386
|
-
if (
|
|
29501
|
+
const found2 = this.resolveImports(specifier, importer, kind);
|
|
29502
|
+
if (found2) return found2;
|
|
29387
29503
|
throw this.moduleNotFound(specifier, importer);
|
|
29388
29504
|
}
|
|
29389
29505
|
const baseDir = dirname(importer);
|
|
29390
29506
|
if (specifier.startsWith("/") || specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
29391
29507
|
const resolved = specifier.startsWith("/") ? clean(specifier) : resolve(baseDir, specifier);
|
|
29392
|
-
const
|
|
29393
|
-
if (
|
|
29508
|
+
const found2 = this.resolvePath(resolved, kind);
|
|
29509
|
+
if (found2) return found2;
|
|
29394
29510
|
} else {
|
|
29395
29511
|
const aliased = this.aliasFor(specifier);
|
|
29396
29512
|
if (aliased) {
|
|
29397
29513
|
const substituted = this.resolvePackage(aliased, baseDir, kind);
|
|
29398
29514
|
if (substituted) return substituted;
|
|
29399
29515
|
}
|
|
29400
|
-
const
|
|
29401
|
-
if (
|
|
29516
|
+
const found2 = this.resolvePackage(specifier, baseDir, kind);
|
|
29517
|
+
if (found2) return found2;
|
|
29402
29518
|
}
|
|
29403
29519
|
throw this.moduleNotFound(specifier, importer);
|
|
29404
29520
|
}
|
|
@@ -29564,8 +29680,8 @@ ${code}
|
|
|
29564
29680
|
continue;
|
|
29565
29681
|
}
|
|
29566
29682
|
for (const target of targets ?? []) {
|
|
29567
|
-
const
|
|
29568
|
-
if (
|
|
29683
|
+
const found2 = this.resolvePath(resolve(root, target), kind);
|
|
29684
|
+
if (found2) return found2;
|
|
29569
29685
|
}
|
|
29570
29686
|
}
|
|
29571
29687
|
return null;
|
|
@@ -29574,8 +29690,8 @@ ${code}
|
|
|
29574
29690
|
for (const field of ENTRY_FIELDS[kind]) {
|
|
29575
29691
|
const value = manifest?.[field];
|
|
29576
29692
|
if (typeof value === "string") {
|
|
29577
|
-
const
|
|
29578
|
-
if (
|
|
29693
|
+
const found2 = this.resolvePath(resolve(root, value), kind);
|
|
29694
|
+
if (found2) return found2;
|
|
29579
29695
|
}
|
|
29580
29696
|
}
|
|
29581
29697
|
return this.resolveIndex(root);
|
|
@@ -29598,8 +29714,8 @@ ${code}
|
|
|
29598
29714
|
continue;
|
|
29599
29715
|
}
|
|
29600
29716
|
for (const target of targets ?? []) {
|
|
29601
|
-
const
|
|
29602
|
-
if (
|
|
29717
|
+
const found2 = target.startsWith(".") ? this.resolvePath(resolve(root, target), kind) : this.resolvePackage(target, root, kind);
|
|
29718
|
+
if (found2) return found2;
|
|
29603
29719
|
}
|
|
29604
29720
|
}
|
|
29605
29721
|
return null;
|
|
@@ -36233,12 +36349,12 @@ async function loadNodeRolldownMemfsBinding() {
|
|
|
36233
36349
|
function resolveWorkerPath(node2) {
|
|
36234
36350
|
const { dirname: dirname3, existsSync, fileURLToPath: fileURLToPath2, join: join3 } = node2;
|
|
36235
36351
|
const here = dirname3(fileURLToPath2(import.meta.url));
|
|
36236
|
-
const
|
|
36352
|
+
const candidates2 = [
|
|
36237
36353
|
join3(here, WORKER_FILE),
|
|
36238
36354
|
/* src/tools → dist, for a checkout that has been built. */
|
|
36239
36355
|
join3(here, "..", "..", "dist", WORKER_FILE)
|
|
36240
36356
|
];
|
|
36241
|
-
return
|
|
36357
|
+
return candidates2.find((candidate) => existsSync(candidate)) ?? null;
|
|
36242
36358
|
}
|
|
36243
36359
|
function resolveSubpath(node2, require2, packageName, subpath) {
|
|
36244
36360
|
const { dirname: dirname3, join: join3, pathToFileURL: pathToFileURL2, readFileSync } = node2;
|
|
@@ -38592,17 +38708,17 @@ var Terminal = class {
|
|
|
38592
38708
|
const match2 = /(\S*)$/.exec(left);
|
|
38593
38709
|
const word = match2?.[1] ?? "";
|
|
38594
38710
|
const isFirstWord = left.slice(0, left.length - word.length).trim() === "";
|
|
38595
|
-
const
|
|
38596
|
-
if (
|
|
38597
|
-
if (
|
|
38598
|
-
const completion =
|
|
38711
|
+
const candidates2 = isFirstWord && !word.includes("/") ? this.completeCommand(word) : this.completePath(word);
|
|
38712
|
+
if (candidates2.length === 0) return;
|
|
38713
|
+
if (candidates2.length === 1) {
|
|
38714
|
+
const completion = candidates2[0];
|
|
38599
38715
|
const suffix = completion.slice(word.length);
|
|
38600
38716
|
this.buffer = this.buffer.slice(0, this.cursor) + suffix + this.buffer.slice(this.cursor);
|
|
38601
38717
|
this.cursor += suffix.length;
|
|
38602
38718
|
this.redraw();
|
|
38603
38719
|
return;
|
|
38604
38720
|
}
|
|
38605
|
-
const common = longestCommonPrefix(
|
|
38721
|
+
const common = longestCommonPrefix(candidates2);
|
|
38606
38722
|
if (common.length > word.length) {
|
|
38607
38723
|
const suffix = common.slice(word.length);
|
|
38608
38724
|
this.buffer = this.buffer.slice(0, this.cursor) + suffix + this.buffer.slice(this.cursor);
|
|
@@ -38610,7 +38726,7 @@ var Terminal = class {
|
|
|
38610
38726
|
this.redraw();
|
|
38611
38727
|
return;
|
|
38612
38728
|
}
|
|
38613
|
-
this.write("\r\n" + formatColumns(
|
|
38729
|
+
this.write("\r\n" + formatColumns(candidates2, this.columns) + "\r\n");
|
|
38614
38730
|
this.redraw();
|
|
38615
38731
|
}
|
|
38616
38732
|
completeCommand(word) {
|