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/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 found = this.find(name);
626
- if (!found) return void 0;
627
- if (found.entry.array) return found.entry.array[0] ?? "";
628
- return found.entry.value;
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 found = this.find(name);
635
- if (!found) return void 0;
636
- return found.entry.array ?? [found.entry.value];
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 found = this.find(name);
643
- if (found?.entry.readonly) throw new ReadonlyVariableError(name);
642
+ const found2 = this.find(name);
643
+ if (found2?.entry.readonly) throw new ReadonlyVariableError(name);
644
644
  let next = value;
645
- if (found?.entry.upper || attrs.upper) next = next.toUpperCase();
646
- if (found?.entry.lower || attrs.lower) next = next.toLowerCase();
647
- if (found) {
648
- found.entry.value = next;
649
- delete found.entry.array;
650
- Object.assign(found.entry, attrs);
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 found = this.find(name);
661
- if (found?.entry.readonly) throw new ReadonlyVariableError(name);
662
- if (found) {
663
- found.entry.array = values.slice();
664
- found.entry.value = values[0] ?? "";
665
- Object.assign(found.entry, attrs);
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 found = this.find(name);
672
- if (found?.entry.readonly) throw new ReadonlyVariableError(name);
673
- const arr = found?.entry.array ?? (found ? [found.entry.value] : []);
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 found = this.find(name);
680
- if (found?.entry.array) {
681
- this.setArray(name, [...found.entry.array, value]);
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 found = this.find(name);
699
- if (found) found.entry.exported = exported;
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 found = this.find(name);
704
- if (found) found.entry.readonly = true;
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 found = shell.kernel.which(target, shell.cwd, shell.vars.environment(), shell.cred);
2951
- if (found) path = found;
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 found = [];
3585
+ const found2 = [];
3586
3586
  if (shell.aliases.has(name)) {
3587
- if (typeOnly) found.push("alias");
3588
- else if (!pathOnly) found.push(`${name} is aliased to \`${shell.aliases.get(name)}'`);
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) found.push("function");
3592
- else if (!pathOnly) found.push(`${name} is a function`);
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) found.push("builtin");
3596
- else if (!pathOnly) found.push(`${name} is a shell builtin`);
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) found.push("file");
3601
- else if (pathOnly) found.push(path);
3602
- else found.push(`${name} is ${path}`);
3600
+ if (typeOnly) found2.push("file");
3601
+ else if (pathOnly) found2.push(path);
3602
+ else found2.push(`${name} is ${path}`);
3603
3603
  }
3604
- if (found.length === 0) {
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 ? found : [found[0]]) io.stdout.write(line + "\n");
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 candidates = [...byLong.keys()].filter((k) => k.startsWith(name));
5968
- if (candidates.length === 1) return byLong.get(candidates[0]);
5969
- if (candidates.length > 1) throw new UsageError(`option '--${name}' is ambiguous`);
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 found = this.fds.get(fd);
6489
- if (!found) throw new WasiError(WASI_EBADF);
6490
- return found;
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 found = this.get(fd);
6494
- if (found.kind !== "dir") throw new WasiError(WASI_ENOTDIR);
6495
- return found;
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 found = this.get(fd);
6499
- if (found.kind !== "file") throw new WasiError(WASI_EBADF);
6500
- return found;
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 candidates = [];
7445
+ const candidates2 = [];
7446
7446
  if (name.includes("/")) {
7447
- candidates.push(resolve(cwd, name));
7447
+ candidates2.push(resolve(cwd, name));
7448
7448
  } else {
7449
- for (const dir3 of this.pathDirs(env2)) candidates.push(join(dir3, name));
7449
+ for (const dir3 of this.pathDirs(env2)) candidates2.push(join(dir3, name));
7450
7450
  }
7451
- for (const candidate of candidates) {
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. Give the container a proxy that makes the request for it \u2014 network: { proxy }, and \`npx sandboxedjs-egress\` is one \u2014 or run the container on a server.`
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
- if (policy.proxy) return await fetchThroughProxy(policy.proxy, fetchImpl, input, init);
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 found = false;
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
- found = true;
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 (!found) {
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 found = scope.get(name);
14479
- return found instanceof Map ? Value.uninitialized : found;
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 found = scope.get(name);
14512
- if (found instanceof Map) return found;
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 found = 0;
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
- found++;
18606
+ found2++;
18566
18607
  ctx.line(`${command.name} (1)${" ".repeat(Math.max(1, 16 - command.name.length))}- ${command.summary ?? ""}`);
18567
18608
  }
18568
- if (found === 0) {
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 candidates = [base2, `${base2}.js`, `${base2}.mjs`, `${base2}.cjs`, `${base2}.json`];
19593
- for (const candidate of candidates) {
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.5"};
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(r.string());
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 candidates = [];
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
- candidates.push({
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
- candidates.push(...builtinCandidates(normalize2(name)));
23949
- if (isBuiltinOnly(normalize2(name))) return candidates;
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 (candidates.length > 0) return candidates;
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
- candidates.push({
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 candidates;
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 candidates = pid > 0 ? [children.get(pid)].filter((p) => p !== void 0) : [...children.values()];
24276
- if (candidates.length === 0) throw new PosixError(Errno.ECHILD);
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 = candidates.find(exited);
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(candidates.map((proc) => proc.wait()));
24285
- const finished = candidates.find(exited);
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 found = semver.maxSatisfying(Object.keys(metadata.versions), range === "latest" ? "*" : range, { includePrerelease: false });
26443
- if (!found) throw new Error(`No matching version found for ${metadata.name}@${range}`);
26444
- return found;
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 found = readManifest(ctx, root);
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 (found) {
26911
- delete found.manifest.dependencies?.[name];
26912
- delete found.manifest.devDependencies?.[name];
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 (found) writeManifest(ctx, found.path, found.manifest);
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 found = readManifest(ctx, root);
26922
- ctx.line(`${found?.manifest.name ?? basename(root)}@${found?.manifest.version ?? "1.0.0"} ${root}`);
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 found = readManifest(ctx, root);
26945
- if (!found) return ctx.fail("could not read package.json", 1);
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 " + (found.manifest.name ?? "app") + ":");
26948
- for (const [name, body] of Object.entries(found.manifest.scripts ?? {})) {
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 = found.manifest.scripts?.[scriptName];
27070
+ const script = found2.manifest.scripts?.[scriptName];
26955
27071
  if (script === void 0) {
26956
- if (scriptName === "start" && found.manifest.main) {
26957
- return await runScript(ctx, root, `node ${found.manifest.main}`, scriptArgs, found.manifest);
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(`> ${found.manifest.name ?? "app"}@${found.manifest.version ?? "1.0.0"} ${scriptName}`);
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, found.manifest);
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 found = this.resolveImports(specifier, importer, kind);
29403
- if (found) return found;
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 found = this.resolvePath(resolved, kind);
29410
- if (found) return found;
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 found = this.resolvePackage(specifier, baseDir, kind);
29418
- if (found) return found;
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 found = this.resolvePath(resolve(root, target), kind);
29585
- if (found) return found;
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 found = this.resolvePath(resolve(root, value), kind);
29595
- if (found) return found;
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 found = target.startsWith(".") ? this.resolvePath(resolve(root, target), kind) : this.resolvePackage(target, root, kind);
29619
- if (found) return found;
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 candidates = [
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 candidates.find((candidate) => existsSync(candidate)) ?? null;
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 candidates = isFirstWord && !word.includes("/") ? this.completeCommand(word) : this.completePath(word);
38613
- if (candidates.length === 0) return;
38614
- if (candidates.length === 1) {
38615
- const completion = candidates[0];
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(candidates);
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(candidates, this.columns) + "\r\n");
38746
+ this.write("\r\n" + formatColumns(candidates2, this.columns) + "\r\n");
38631
38747
  this.redraw();
38632
38748
  }
38633
38749
  completeCommand(word) {