@paybox-sh/sdk 2.3.0 → 2.4.0

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/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PayboxClient,
4
+ PayboxError,
4
5
  appBaseFrom,
5
6
  configDir,
6
7
  configFile,
@@ -13,11 +14,10 @@ import {
13
14
  pendingFundingToolResponse,
14
15
  refreshTokens,
15
16
  saveConfig
16
- } from "./chunk-YTHYNUMM.js";
17
+ } from "./chunk-ACNRTJGL.js";
17
18
 
18
19
  // src/cli.ts
19
- import { spawnSync } from "node:child_process";
20
- import { readFileSync, rmSync } from "node:fs";
20
+ import { readFileSync as readFileSync2, rmSync as rmSync2 } from "node:fs";
21
21
  import { createRequire } from "node:module";
22
22
  import { Command } from "commander";
23
23
 
@@ -420,12 +420,150 @@ async function pairSigningKey(opts) {
420
420
  throw new Error("timed out waiting for you to pick the number in PayBox");
421
421
  }
422
422
 
423
+ // src/self-update.ts
424
+ import { spawnSync } from "node:child_process";
425
+ import { closeSync, mkdirSync, openSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
426
+ import { constants } from "node:os";
427
+ import { isAbsolute, join, relative } from "node:path";
428
+ var PKG = "@paybox-sh/sdk";
429
+ var DAY_MS = 24 * 60 * 60 * 1e3;
430
+ var LOCK_STALE_MS = 10 * 60 * 1e3;
431
+ var NPM_TIMEOUT_MS = 2 * 60 * 1e3;
432
+ var SEMVER = /^\d+\.\d+\.\d+$/;
433
+ var NO_AUTO_UPDATE = /* @__PURE__ */ new Set(["version", "update", "uninstall"]);
434
+ function isNewer(a, b) {
435
+ const pa = a.split(".").map(Number);
436
+ const pb = b.split(".").map(Number);
437
+ for (let i = 0; i < 3; i++) {
438
+ const x = pa[i] ?? 0;
439
+ const y = pb[i] ?? 0;
440
+ if (x !== y) return x > y;
441
+ }
442
+ return false;
443
+ }
444
+ function registry() {
445
+ return (process.env.PAYBOX_UPDATE_REGISTRY || "https://registry.npmjs.org").replace(/\/+$/, "");
446
+ }
447
+ async function latestVersion() {
448
+ try {
449
+ const res = await fetch(`${registry()}/${PKG}/latest`, { signal: AbortSignal.timeout(3e3) });
450
+ if (!res.ok) return void 0;
451
+ const { version } = await res.json();
452
+ return typeof version === "string" && SEMVER.test(version) ? version : void 0;
453
+ } catch {
454
+ return void 0;
455
+ }
456
+ }
457
+ function installArgs(version) {
458
+ const pinned = `${registry()}/`;
459
+ return ["install", "-g", `${PKG}@${version}`, "--registry", pinned, `--@paybox-sh:registry=${pinned}`];
460
+ }
461
+ function npm(args, stdio) {
462
+ const background = stdio === "pipe";
463
+ const env = Object.fromEntries(
464
+ Object.entries(process.env).filter(([key]) => !(background && /^npm_config_.*registry$/i.test(key)))
465
+ );
466
+ const options = {
467
+ stdio,
468
+ encoding: "utf8",
469
+ timeout: background ? NPM_TIMEOUT_MS : void 0,
470
+ cwd: background ? configDir() : void 0
471
+ };
472
+ if (process.platform !== "win32") return spawnSync("npm", args, { ...options, env });
473
+ return spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", "npm", ...args], {
474
+ ...options,
475
+ env: { ...env, NoDefaultCurrentDirectoryInExePath: "1" }
476
+ });
477
+ }
478
+ function available(latest, current) {
479
+ return `PayBox CLI v${latest} is available (this is v${current}). Run \`paybox update\`.`;
480
+ }
481
+ function globalCli() {
482
+ const root = npm(["root", "-g"], "pipe");
483
+ if (root.status !== 0 || !process.argv[1]) return void 0;
484
+ const pkgDir = join(root.stdout.trim(), PKG);
485
+ try {
486
+ const rel = relative(realpathSync(pkgDir), realpathSync(process.argv[1]));
487
+ return rel && !rel.startsWith("..") && !isAbsolute(rel) ? join(pkgDir, "dist", "cli.js") : void 0;
488
+ } catch {
489
+ return void 0;
490
+ }
491
+ }
492
+ function unlock(lock) {
493
+ try {
494
+ rmSync(lock, { force: true });
495
+ } catch {
496
+ }
497
+ }
498
+ function startCheck(dir) {
499
+ const cache = join(dir, "update-check.json");
500
+ const lock = join(dir, "update.lock");
501
+ try {
502
+ const age = Date.now() - JSON.parse(readFileSync(cache, "utf8")).checkedAt;
503
+ if (age >= 0 && age < DAY_MS) return false;
504
+ } catch {
505
+ }
506
+ try {
507
+ mkdirSync(dir, { recursive: true, mode: 448 });
508
+ closeSync(openSync(lock, "wx"));
509
+ } catch {
510
+ try {
511
+ if (Date.now() - statSync(lock).mtimeMs > LOCK_STALE_MS) unlock(lock);
512
+ } catch {
513
+ }
514
+ return false;
515
+ }
516
+ try {
517
+ writeFileSync(cache, JSON.stringify({ checkedAt: Date.now() }));
518
+ return true;
519
+ } catch {
520
+ unlock(lock);
521
+ return false;
522
+ }
523
+ }
524
+ async function install(current) {
525
+ const latest = await latestVersion();
526
+ if (!latest || !isNewer(latest, current)) return void 0;
527
+ const cli = latest.split(".")[0] === current.split(".")[0] ? globalCli() : void 0;
528
+ if (!cli) {
529
+ console.error(available(latest, current));
530
+ return void 0;
531
+ }
532
+ if (npm(installArgs(latest), "pipe").status !== 0) {
533
+ console.error(`Could not update PayBox CLI to v${latest}; continuing with v${current}. Run \`paybox update\` to see why.`);
534
+ return void 0;
535
+ }
536
+ return { cli, latest };
537
+ }
538
+ async function autoUpdate(command, current) {
539
+ if (NO_AUTO_UPDATE.has(command) || process.env.PAYBOX_NO_AUTO_UPDATE === "1") return;
540
+ const updated = process.env.PAYBOX_AUTO_UPDATED;
541
+ if (updated) {
542
+ if (isNewer(updated, current)) console.error(available(updated, current));
543
+ return;
544
+ }
545
+ const dir = configDir();
546
+ if (!startCheck(dir)) return;
547
+ let next;
548
+ try {
549
+ next = await install(current);
550
+ } finally {
551
+ unlock(join(dir, "update.lock"));
552
+ }
553
+ if (!next) return;
554
+ console.error(`Updated PayBox CLI v${current} \u2192 v${next.latest}.`);
555
+ const child = spawnSync(process.execPath, [next.cli, ...process.argv.slice(2)], {
556
+ stdio: "inherit",
557
+ env: { ...process.env, PAYBOX_AUTO_UPDATED: next.latest }
558
+ });
559
+ process.exit(child.status ?? (child.signal ? 128 + constants.signals[child.signal] : 1));
560
+ }
561
+
423
562
  // src/cli.ts
424
563
  var DEFAULT_BASE_URL = "https://api.paybox.sh";
425
- var PKG = "@paybox-sh/sdk";
426
564
  var VERSION = createRequire(import.meta.url)("../package.json").version;
427
565
  var program = new Command();
428
- program.name("paybox").description("PayBox agent CLI \u2014 vaulted cards, wallets, and secrets for agents").version(VERSION).option("--base-url <url>", "API origin (default https://api.paybox.sh or stored)").option("--json", "machine-readable JSON output");
566
+ program.name("paybox").description("PayBox agent CLI \u2014 vaulted cards, wallets, and secrets for agents").version(VERSION).option("--base-url <url>", "API origin (default https://api.paybox.sh or stored)").option("--json", "machine-readable JSON output").hook("preAction", (_, command) => autoUpdate(command.name(), VERSION));
429
567
  function jsonMode() {
430
568
  return Boolean(program.opts().json);
431
569
  }
@@ -447,7 +585,7 @@ function client() {
447
585
  return PayboxClient.fromConfig({ baseUrl: program.opts().baseUrl });
448
586
  }
449
587
  function readIntent(value) {
450
- const raw = value.startsWith("@") ? readFileSync(value.slice(1), "utf8") : value;
588
+ const raw = value.startsWith("@") ? readFileSync2(value.slice(1), "utf8") : value;
451
589
  return JSON.parse(raw);
452
590
  }
453
591
  function readObject(value) {
@@ -486,22 +624,13 @@ function uuid(value, what, hint) {
486
624
  if (UUID.test(value)) return value;
487
625
  throw new Error(`${what}: got ${JSON.stringify(value)}. ${hint}`);
488
626
  }
489
- function isNewer(a, b) {
490
- const pa = a.split(".").map(Number);
491
- const pb = b.split(".").map(Number);
492
- for (let i = 0; i < 3; i++) {
493
- const x = pa[i] ?? 0;
494
- const y = pb[i] ?? 0;
495
- if (x !== y) return x > y;
496
- }
497
- return false;
498
- }
499
627
  async function run(fn) {
500
628
  try {
501
629
  await fn();
502
630
  } catch (err) {
503
631
  const message = err instanceof Error ? err.message : String(err);
504
- if (jsonMode()) console.log(JSON.stringify({ error: message }, null, 2));
632
+ const reason = err instanceof PayboxError ? err.reason : void 0;
633
+ if (jsonMode()) console.log(JSON.stringify({ error: message, reason }, null, 2));
505
634
  else console.error(message);
506
635
  process.exitCode = 1;
507
636
  }
@@ -773,12 +902,7 @@ program.command("request <id>").description("Poll a request's status").option("-
773
902
  );
774
903
  program.command("version").description("Show the installed CLI version (and whether an update is available)").action(
775
904
  () => run(async () => {
776
- let latest;
777
- try {
778
- const res = await fetch(`https://registry.npmjs.org/${PKG}/latest`);
779
- if (res.ok) latest = (await res.json()).version;
780
- } catch {
781
- }
905
+ const latest = await latestVersion();
782
906
  const updateAvailable = Boolean(latest && isNewer(latest, VERSION));
783
907
  if (jsonMode()) {
784
908
  emit({
@@ -797,13 +921,13 @@ program.command("version").description("Show the installed CLI version (and whet
797
921
  );
798
922
  program.command("update").description("Update the globally-installed paybox CLI to the latest version").option("--print", "print the update command instead of running it").action(
799
923
  (opts) => run(async () => {
800
- const args = ["install", "-g", `${PKG}@latest`];
924
+ const args = installArgs("latest");
801
925
  if (opts.print) {
802
926
  console.log(`npm ${args.join(" ")}`);
803
927
  return;
804
928
  }
805
929
  console.error(`Updating ${PKG} (npm ${args.join(" ")})\u2026`);
806
- const r = spawnSync("npm", args, { stdio: "inherit" });
930
+ const r = npm(args, "inherit");
807
931
  if (r.status !== 0) {
808
932
  console.error(
809
933
  `
@@ -816,7 +940,7 @@ If this isn't a global install: run \`pnpm up ${PKG}\` in your project, or use \
816
940
  program.command("uninstall").description("Remove stored PayBox credentials/config (and show how to remove the CLI)").action(
817
941
  () => run(async () => {
818
942
  const dir = configDir();
819
- rmSync(dir, { recursive: true, force: true });
943
+ rmSync2(dir, { recursive: true, force: true });
820
944
  console.error(`Removed stored config at ${dir}.`);
821
945
  console.error(
822
946
  `The CLI binary is managed by npm \u2014 remove it with: