@stripe/link-cli 0.11.0 → 0.13.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.
Files changed (3) hide show
  1. package/README.md +43 -2
  2. package/dist/cli.js +1651 -556
  3. package/package.json +6 -6
package/dist/cli.js CHANGED
@@ -3095,9 +3095,9 @@ var require_data = __commonJS({
3095
3095
  }
3096
3096
  });
3097
3097
 
3098
- // ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js
3098
+ // ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js
3099
3099
  var require_utils = __commonJS({
3100
- "../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js"(exports, module) {
3100
+ "../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js"(exports, module) {
3101
3101
  "use strict";
3102
3102
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3103
3103
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
@@ -3408,9 +3408,9 @@ var require_utils = __commonJS({
3408
3408
  }
3409
3409
  });
3410
3410
 
3411
- // ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js
3411
+ // ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js
3412
3412
  var require_schemes = __commonJS({
3413
- "../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3413
+ "../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3414
3414
  "use strict";
3415
3415
  var { isUUID } = require_utils();
3416
3416
  var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
@@ -3618,9 +3618,9 @@ var require_schemes = __commonJS({
3618
3618
  }
3619
3619
  });
3620
3620
 
3621
- // ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js
3621
+ // ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js
3622
3622
  var require_fast_uri = __commonJS({
3623
- "../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js"(exports, module) {
3623
+ "../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js"(exports, module) {
3624
3624
  "use strict";
3625
3625
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3626
3626
  var { SCHEMES, getSchemeHandler } = require_schemes();
@@ -3636,7 +3636,12 @@ var require_fast_uri = __commonJS({
3636
3636
  }
3637
3637
  function resolve(baseURI, relativeURI, options) {
3638
3638
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3639
- const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
3639
+ const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
3640
+ const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
3641
+ if (baseMalformed || relativeMalformed) {
3642
+ throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
3643
+ }
3644
+ const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
3640
3645
  schemelessOptions.skipEscape = true;
3641
3646
  return serialize(resolved, schemelessOptions);
3642
3647
  }
@@ -3761,6 +3766,8 @@ var require_fast_uri = __commonJS({
3761
3766
  return uriTokens.join("");
3762
3767
  }
3763
3768
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3769
+ var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
3770
+ var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
3764
3771
  function getParseError(parsed, matches) {
3765
3772
  if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
3766
3773
  return 'URI path must start with "/" when authority is present.';
@@ -3790,6 +3797,25 @@ var require_fast_uri = __commonJS({
3790
3797
  uri = "//" + uri;
3791
3798
  }
3792
3799
  }
3800
+ const authorityMatch = uri.match(AUTHORITY_PREFIX);
3801
+ if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
3802
+ parsed.error = "URI authority must not contain a literal backslash.";
3803
+ malformedAuthorityOrPort = true;
3804
+ }
3805
+ const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
3806
+ if (introducerMatch !== null) {
3807
+ const region = introducerMatch[1];
3808
+ const normalizedRegion = region.replace(/[\t\n\r]/g, "");
3809
+ if (normalizedRegion.length >= 2) {
3810
+ if (normalizedRegion.slice(0, 2) !== "//") {
3811
+ parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
3812
+ malformedAuthorityOrPort = true;
3813
+ } else if (region.length !== normalizedRegion.length) {
3814
+ parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
3815
+ malformedAuthorityOrPort = true;
3816
+ }
3817
+ }
3818
+ }
3793
3819
  const matches = uri.match(URI_PARSE);
3794
3820
  if (matches) {
3795
3821
  parsed.scheme = matches[1];
@@ -3833,7 +3859,7 @@ var require_fast_uri = __commonJS({
3833
3859
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3834
3860
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3835
3861
  try {
3836
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3862
+ parsed.host = new URL("http://" + parsed.host).hostname;
3837
3863
  } catch (e) {
3838
3864
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3839
3865
  }
@@ -7705,9 +7731,9 @@ var require_dist = __commonJS({
7705
7731
  }
7706
7732
  });
7707
7733
 
7708
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/constants.js
7734
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js
7709
7735
  var require_constants = __commonJS({
7710
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/constants.js"(exports, module) {
7736
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js"(exports, module) {
7711
7737
  "use strict";
7712
7738
  var SEMVER_SPEC_VERSION = "2.0.0";
7713
7739
  var MAX_LENGTH = 256;
@@ -7737,9 +7763,9 @@ var require_constants = __commonJS({
7737
7763
  }
7738
7764
  });
7739
7765
 
7740
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/debug.js
7766
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/debug.js
7741
7767
  var require_debug = __commonJS({
7742
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/debug.js"(exports, module) {
7768
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/debug.js"(exports, module) {
7743
7769
  "use strict";
7744
7770
  var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
7745
7771
  };
@@ -7747,9 +7773,9 @@ var require_debug = __commonJS({
7747
7773
  }
7748
7774
  });
7749
7775
 
7750
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/re.js
7776
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/re.js
7751
7777
  var require_re = __commonJS({
7752
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/re.js"(exports, module) {
7778
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/re.js"(exports, module) {
7753
7779
  "use strict";
7754
7780
  var {
7755
7781
  MAX_SAFE_COMPONENT_LENGTH,
@@ -7835,9 +7861,9 @@ var require_re = __commonJS({
7835
7861
  }
7836
7862
  });
7837
7863
 
7838
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/parse-options.js
7864
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/parse-options.js
7839
7865
  var require_parse_options = __commonJS({
7840
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/parse-options.js"(exports, module) {
7866
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/parse-options.js"(exports, module) {
7841
7867
  "use strict";
7842
7868
  var looseOption = Object.freeze({ loose: true });
7843
7869
  var emptyOpts = Object.freeze({});
@@ -7854,9 +7880,9 @@ var require_parse_options = __commonJS({
7854
7880
  }
7855
7881
  });
7856
7882
 
7857
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/identifiers.js
7883
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/identifiers.js
7858
7884
  var require_identifiers = __commonJS({
7859
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/identifiers.js"(exports, module) {
7885
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/identifiers.js"(exports, module) {
7860
7886
  "use strict";
7861
7887
  var numeric = /^[0-9]+$/;
7862
7888
  var compareIdentifiers = (a, b) => {
@@ -7879,15 +7905,27 @@ var require_identifiers = __commonJS({
7879
7905
  }
7880
7906
  });
7881
7907
 
7882
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/semver.js
7908
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/semver.js
7883
7909
  var require_semver = __commonJS({
7884
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/semver.js"(exports, module) {
7910
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/semver.js"(exports, module) {
7885
7911
  "use strict";
7886
7912
  var debug = require_debug();
7887
7913
  var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
7888
7914
  var { safeRe: re, t } = require_re();
7889
7915
  var parseOptions = require_parse_options();
7890
7916
  var { compareIdentifiers } = require_identifiers();
7917
+ var isPrereleaseIdentifier = (prerelease, identifier) => {
7918
+ const identifiers = identifier.split(".");
7919
+ if (identifiers.length > prerelease.length) {
7920
+ return false;
7921
+ }
7922
+ for (let i = 0; i < identifiers.length; i++) {
7923
+ if (compareIdentifiers(prerelease[i], identifiers[i]) !== 0) {
7924
+ return false;
7925
+ }
7926
+ }
7927
+ return true;
7928
+ };
7891
7929
  var SemVer = class _SemVer {
7892
7930
  constructor(version, options) {
7893
7931
  options = parseOptions(options);
@@ -8134,8 +8172,9 @@ var require_semver = __commonJS({
8134
8172
  if (identifierBase === false) {
8135
8173
  prerelease = [identifier];
8136
8174
  }
8137
- if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
8138
- if (isNaN(this.prerelease[1])) {
8175
+ if (isPrereleaseIdentifier(this.prerelease, identifier)) {
8176
+ const prereleaseBase = this.prerelease[identifier.split(".").length];
8177
+ if (isNaN(prereleaseBase)) {
8139
8178
  this.prerelease = prerelease;
8140
8179
  }
8141
8180
  } else {
@@ -8158,9 +8197,9 @@ var require_semver = __commonJS({
8158
8197
  }
8159
8198
  });
8160
8199
 
8161
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/parse.js
8200
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js
8162
8201
  var require_parse = __commonJS({
8163
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/parse.js"(exports, module) {
8202
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js"(exports, module) {
8164
8203
  "use strict";
8165
8204
  var SemVer = require_semver();
8166
8205
  var parse = (version, options, throwErrors = false) => {
@@ -8180,9 +8219,9 @@ var require_parse = __commonJS({
8180
8219
  }
8181
8220
  });
8182
8221
 
8183
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/valid.js
8222
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js
8184
8223
  var require_valid = __commonJS({
8185
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/valid.js"(exports, module) {
8224
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js"(exports, module) {
8186
8225
  "use strict";
8187
8226
  var parse = require_parse();
8188
8227
  var valid = (version, options) => {
@@ -8193,9 +8232,9 @@ var require_valid = __commonJS({
8193
8232
  }
8194
8233
  });
8195
8234
 
8196
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/clean.js
8235
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/clean.js
8197
8236
  var require_clean = __commonJS({
8198
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/clean.js"(exports, module) {
8237
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/clean.js"(exports, module) {
8199
8238
  "use strict";
8200
8239
  var parse = require_parse();
8201
8240
  var clean = (version, options) => {
@@ -8206,9 +8245,9 @@ var require_clean = __commonJS({
8206
8245
  }
8207
8246
  });
8208
8247
 
8209
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/inc.js
8248
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/inc.js
8210
8249
  var require_inc = __commonJS({
8211
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/inc.js"(exports, module) {
8250
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/inc.js"(exports, module) {
8212
8251
  "use strict";
8213
8252
  var SemVer = require_semver();
8214
8253
  var inc = (version, release, options, identifier, identifierBase) => {
@@ -8230,9 +8269,9 @@ var require_inc = __commonJS({
8230
8269
  }
8231
8270
  });
8232
8271
 
8233
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/diff.js
8272
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/diff.js
8234
8273
  var require_diff = __commonJS({
8235
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/diff.js"(exports, module) {
8274
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/diff.js"(exports, module) {
8236
8275
  "use strict";
8237
8276
  var parse = require_parse();
8238
8277
  var diff = (version1, version2) => {
@@ -8274,9 +8313,9 @@ var require_diff = __commonJS({
8274
8313
  }
8275
8314
  });
8276
8315
 
8277
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/major.js
8316
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/major.js
8278
8317
  var require_major = __commonJS({
8279
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/major.js"(exports, module) {
8318
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/major.js"(exports, module) {
8280
8319
  "use strict";
8281
8320
  var SemVer = require_semver();
8282
8321
  var major = (a, loose) => new SemVer(a, loose).major;
@@ -8284,9 +8323,9 @@ var require_major = __commonJS({
8284
8323
  }
8285
8324
  });
8286
8325
 
8287
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/minor.js
8326
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/minor.js
8288
8327
  var require_minor = __commonJS({
8289
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/minor.js"(exports, module) {
8328
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/minor.js"(exports, module) {
8290
8329
  "use strict";
8291
8330
  var SemVer = require_semver();
8292
8331
  var minor = (a, loose) => new SemVer(a, loose).minor;
@@ -8294,9 +8333,9 @@ var require_minor = __commonJS({
8294
8333
  }
8295
8334
  });
8296
8335
 
8297
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/patch.js
8336
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/patch.js
8298
8337
  var require_patch = __commonJS({
8299
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/patch.js"(exports, module) {
8338
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/patch.js"(exports, module) {
8300
8339
  "use strict";
8301
8340
  var SemVer = require_semver();
8302
8341
  var patch = (a, loose) => new SemVer(a, loose).patch;
@@ -8304,9 +8343,9 @@ var require_patch = __commonJS({
8304
8343
  }
8305
8344
  });
8306
8345
 
8307
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/prerelease.js
8346
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/prerelease.js
8308
8347
  var require_prerelease = __commonJS({
8309
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/prerelease.js"(exports, module) {
8348
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/prerelease.js"(exports, module) {
8310
8349
  "use strict";
8311
8350
  var parse = require_parse();
8312
8351
  var prerelease = (version, options) => {
@@ -8317,9 +8356,9 @@ var require_prerelease = __commonJS({
8317
8356
  }
8318
8357
  });
8319
8358
 
8320
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare.js
8359
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare.js
8321
8360
  var require_compare = __commonJS({
8322
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare.js"(exports, module) {
8361
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare.js"(exports, module) {
8323
8362
  "use strict";
8324
8363
  var SemVer = require_semver();
8325
8364
  var compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
@@ -8327,9 +8366,9 @@ var require_compare = __commonJS({
8327
8366
  }
8328
8367
  });
8329
8368
 
8330
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/rcompare.js
8369
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rcompare.js
8331
8370
  var require_rcompare = __commonJS({
8332
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/rcompare.js"(exports, module) {
8371
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rcompare.js"(exports, module) {
8333
8372
  "use strict";
8334
8373
  var compare = require_compare();
8335
8374
  var rcompare = (a, b, loose) => compare(b, a, loose);
@@ -8337,9 +8376,9 @@ var require_rcompare = __commonJS({
8337
8376
  }
8338
8377
  });
8339
8378
 
8340
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare-loose.js
8379
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-loose.js
8341
8380
  var require_compare_loose = __commonJS({
8342
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare-loose.js"(exports, module) {
8381
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-loose.js"(exports, module) {
8343
8382
  "use strict";
8344
8383
  var compare = require_compare();
8345
8384
  var compareLoose = (a, b) => compare(a, b, true);
@@ -8347,9 +8386,9 @@ var require_compare_loose = __commonJS({
8347
8386
  }
8348
8387
  });
8349
8388
 
8350
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare-build.js
8389
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-build.js
8351
8390
  var require_compare_build = __commonJS({
8352
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/compare-build.js"(exports, module) {
8391
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-build.js"(exports, module) {
8353
8392
  "use strict";
8354
8393
  var SemVer = require_semver();
8355
8394
  var compareBuild = (a, b, loose) => {
@@ -8361,9 +8400,9 @@ var require_compare_build = __commonJS({
8361
8400
  }
8362
8401
  });
8363
8402
 
8364
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/sort.js
8403
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/sort.js
8365
8404
  var require_sort = __commonJS({
8366
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/sort.js"(exports, module) {
8405
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/sort.js"(exports, module) {
8367
8406
  "use strict";
8368
8407
  var compareBuild = require_compare_build();
8369
8408
  var sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose));
@@ -8371,9 +8410,9 @@ var require_sort = __commonJS({
8371
8410
  }
8372
8411
  });
8373
8412
 
8374
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/rsort.js
8413
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rsort.js
8375
8414
  var require_rsort = __commonJS({
8376
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/rsort.js"(exports, module) {
8415
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rsort.js"(exports, module) {
8377
8416
  "use strict";
8378
8417
  var compareBuild = require_compare_build();
8379
8418
  var rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose));
@@ -8381,9 +8420,9 @@ var require_rsort = __commonJS({
8381
8420
  }
8382
8421
  });
8383
8422
 
8384
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/gt.js
8423
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gt.js
8385
8424
  var require_gt = __commonJS({
8386
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/gt.js"(exports, module) {
8425
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gt.js"(exports, module) {
8387
8426
  "use strict";
8388
8427
  var compare = require_compare();
8389
8428
  var gt = (a, b, loose) => compare(a, b, loose) > 0;
@@ -8391,9 +8430,9 @@ var require_gt = __commonJS({
8391
8430
  }
8392
8431
  });
8393
8432
 
8394
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/lt.js
8433
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lt.js
8395
8434
  var require_lt = __commonJS({
8396
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/lt.js"(exports, module) {
8435
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lt.js"(exports, module) {
8397
8436
  "use strict";
8398
8437
  var compare = require_compare();
8399
8438
  var lt = (a, b, loose) => compare(a, b, loose) < 0;
@@ -8401,9 +8440,9 @@ var require_lt = __commonJS({
8401
8440
  }
8402
8441
  });
8403
8442
 
8404
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/eq.js
8443
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/eq.js
8405
8444
  var require_eq = __commonJS({
8406
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/eq.js"(exports, module) {
8445
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/eq.js"(exports, module) {
8407
8446
  "use strict";
8408
8447
  var compare = require_compare();
8409
8448
  var eq = (a, b, loose) => compare(a, b, loose) === 0;
@@ -8411,9 +8450,9 @@ var require_eq = __commonJS({
8411
8450
  }
8412
8451
  });
8413
8452
 
8414
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/neq.js
8453
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/neq.js
8415
8454
  var require_neq = __commonJS({
8416
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/neq.js"(exports, module) {
8455
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/neq.js"(exports, module) {
8417
8456
  "use strict";
8418
8457
  var compare = require_compare();
8419
8458
  var neq = (a, b, loose) => compare(a, b, loose) !== 0;
@@ -8421,9 +8460,9 @@ var require_neq = __commonJS({
8421
8460
  }
8422
8461
  });
8423
8462
 
8424
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/gte.js
8463
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gte.js
8425
8464
  var require_gte = __commonJS({
8426
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/gte.js"(exports, module) {
8465
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gte.js"(exports, module) {
8427
8466
  "use strict";
8428
8467
  var compare = require_compare();
8429
8468
  var gte = (a, b, loose) => compare(a, b, loose) >= 0;
@@ -8431,9 +8470,9 @@ var require_gte = __commonJS({
8431
8470
  }
8432
8471
  });
8433
8472
 
8434
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/lte.js
8473
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lte.js
8435
8474
  var require_lte = __commonJS({
8436
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/lte.js"(exports, module) {
8475
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lte.js"(exports, module) {
8437
8476
  "use strict";
8438
8477
  var compare = require_compare();
8439
8478
  var lte = (a, b, loose) => compare(a, b, loose) <= 0;
@@ -8441,9 +8480,9 @@ var require_lte = __commonJS({
8441
8480
  }
8442
8481
  });
8443
8482
 
8444
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/cmp.js
8483
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/cmp.js
8445
8484
  var require_cmp = __commonJS({
8446
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/cmp.js"(exports, module) {
8485
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/cmp.js"(exports, module) {
8447
8486
  "use strict";
8448
8487
  var eq = require_eq();
8449
8488
  var neq = require_neq();
@@ -8491,9 +8530,9 @@ var require_cmp = __commonJS({
8491
8530
  }
8492
8531
  });
8493
8532
 
8494
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/coerce.js
8533
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/coerce.js
8495
8534
  var require_coerce = __commonJS({
8496
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/coerce.js"(exports, module) {
8535
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/coerce.js"(exports, module) {
8497
8536
  "use strict";
8498
8537
  var SemVer = require_semver();
8499
8538
  var parse = require_parse();
@@ -8537,9 +8576,9 @@ var require_coerce = __commonJS({
8537
8576
  }
8538
8577
  });
8539
8578
 
8540
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/truncate.js
8579
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/truncate.js
8541
8580
  var require_truncate = __commonJS({
8542
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/truncate.js"(exports, module) {
8581
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/truncate.js"(exports, module) {
8543
8582
  "use strict";
8544
8583
  var parse = require_parse();
8545
8584
  var constants2 = require_constants();
@@ -8578,9 +8617,9 @@ var require_truncate = __commonJS({
8578
8617
  }
8579
8618
  });
8580
8619
 
8581
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/lrucache.js
8620
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/lrucache.js
8582
8621
  var require_lrucache = __commonJS({
8583
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/internal/lrucache.js"(exports, module) {
8622
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/lrucache.js"(exports, module) {
8584
8623
  "use strict";
8585
8624
  var LRUCache = class {
8586
8625
  constructor() {
@@ -8616,9 +8655,9 @@ var require_lrucache = __commonJS({
8616
8655
  }
8617
8656
  });
8618
8657
 
8619
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/range.js
8658
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/range.js
8620
8659
  var require_range = __commonJS({
8621
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/range.js"(exports, module) {
8660
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/range.js"(exports, module) {
8622
8661
  "use strict";
8623
8662
  var SPACE_CHARACTERS = /\s+/g;
8624
8663
  var Range = class _Range {
@@ -8805,20 +8844,22 @@ var require_range = __commonJS({
8805
8844
  return comp;
8806
8845
  };
8807
8846
  var isX = (id) => !id || id.toLowerCase() === "x" || id === "*";
8847
+ var invalidXRangeOrder = (M, m, p) => isX(M) && !isX(m) || isX(m) && p && !isX(p);
8808
8848
  var replaceTildes = (comp, options) => {
8809
8849
  return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" ");
8810
8850
  };
8811
8851
  var replaceTilde = (comp, options) => {
8812
8852
  const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
8853
+ const z13 = options.includePrerelease ? "-0" : "";
8813
8854
  return comp.replace(r, (_, M, m, p, pr) => {
8814
8855
  debug("tilde", comp, _, M, m, p, pr);
8815
8856
  let ret;
8816
8857
  if (isX(M)) {
8817
8858
  ret = "";
8818
8859
  } else if (isX(m)) {
8819
- ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
8860
+ ret = `>=${M}.0.0${z13} <${+M + 1}.0.0-0`;
8820
8861
  } else if (isX(p)) {
8821
- ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
8862
+ ret = `>=${M}.${m}.0${z13} <${M}.${+m + 1}.0-0`;
8822
8863
  } else if (pr) {
8823
8864
  debug("replaceTilde pr", pr);
8824
8865
  ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`;
@@ -8864,9 +8905,9 @@ var require_range = __commonJS({
8864
8905
  debug("no pr");
8865
8906
  if (M === "0") {
8866
8907
  if (m === "0") {
8867
- ret = `>=${M}.${m}.${p}${z13} <${M}.${m}.${+p + 1}-0`;
8908
+ ret = `>=${M}.${m}.${p} <${M}.${m}.${+p + 1}-0`;
8868
8909
  } else {
8869
- ret = `>=${M}.${m}.${p}${z13} <${M}.${+m + 1}.0-0`;
8910
+ ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`;
8870
8911
  }
8871
8912
  } else {
8872
8913
  ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`;
@@ -8885,6 +8926,9 @@ var require_range = __commonJS({
8885
8926
  const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
8886
8927
  return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
8887
8928
  debug("xRange", comp, ret, gtlt, M, m, p, pr);
8929
+ if (invalidXRangeOrder(M, m, p)) {
8930
+ return comp;
8931
+ }
8888
8932
  const xM = isX(M);
8889
8933
  const xm = xM || isX(m);
8890
8934
  const xp = xm || isX(p);
@@ -8996,9 +9040,9 @@ var require_range = __commonJS({
8996
9040
  }
8997
9041
  });
8998
9042
 
8999
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/comparator.js
9043
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/comparator.js
9000
9044
  var require_comparator = __commonJS({
9001
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/classes/comparator.js"(exports, module) {
9045
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/comparator.js"(exports, module) {
9002
9046
  "use strict";
9003
9047
  var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
9004
9048
  var Comparator = class _Comparator {
@@ -9109,9 +9153,9 @@ var require_comparator = __commonJS({
9109
9153
  }
9110
9154
  });
9111
9155
 
9112
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/satisfies.js
9156
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js
9113
9157
  var require_satisfies = __commonJS({
9114
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/satisfies.js"(exports, module) {
9158
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js"(exports, module) {
9115
9159
  "use strict";
9116
9160
  var Range = require_range();
9117
9161
  var satisfies = (version, range, options) => {
@@ -9126,9 +9170,9 @@ var require_satisfies = __commonJS({
9126
9170
  }
9127
9171
  });
9128
9172
 
9129
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/to-comparators.js
9173
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/to-comparators.js
9130
9174
  var require_to_comparators = __commonJS({
9131
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/to-comparators.js"(exports, module) {
9175
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/to-comparators.js"(exports, module) {
9132
9176
  "use strict";
9133
9177
  var Range = require_range();
9134
9178
  var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" "));
@@ -9136,9 +9180,9 @@ var require_to_comparators = __commonJS({
9136
9180
  }
9137
9181
  });
9138
9182
 
9139
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/max-satisfying.js
9183
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/max-satisfying.js
9140
9184
  var require_max_satisfying = __commonJS({
9141
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/max-satisfying.js"(exports, module) {
9185
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/max-satisfying.js"(exports, module) {
9142
9186
  "use strict";
9143
9187
  var SemVer = require_semver();
9144
9188
  var Range = require_range();
@@ -9165,9 +9209,9 @@ var require_max_satisfying = __commonJS({
9165
9209
  }
9166
9210
  });
9167
9211
 
9168
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/min-satisfying.js
9212
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-satisfying.js
9169
9213
  var require_min_satisfying = __commonJS({
9170
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/min-satisfying.js"(exports, module) {
9214
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-satisfying.js"(exports, module) {
9171
9215
  "use strict";
9172
9216
  var SemVer = require_semver();
9173
9217
  var Range = require_range();
@@ -9194,9 +9238,9 @@ var require_min_satisfying = __commonJS({
9194
9238
  }
9195
9239
  });
9196
9240
 
9197
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/min-version.js
9241
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-version.js
9198
9242
  var require_min_version = __commonJS({
9199
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/min-version.js"(exports, module) {
9243
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-version.js"(exports, module) {
9200
9244
  "use strict";
9201
9245
  var SemVer = require_semver();
9202
9246
  var Range = require_range();
@@ -9253,9 +9297,9 @@ var require_min_version = __commonJS({
9253
9297
  }
9254
9298
  });
9255
9299
 
9256
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/valid.js
9300
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/valid.js
9257
9301
  var require_valid2 = __commonJS({
9258
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/valid.js"(exports, module) {
9302
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/valid.js"(exports, module) {
9259
9303
  "use strict";
9260
9304
  var Range = require_range();
9261
9305
  var validRange = (range, options) => {
@@ -9269,9 +9313,9 @@ var require_valid2 = __commonJS({
9269
9313
  }
9270
9314
  });
9271
9315
 
9272
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/outside.js
9316
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/outside.js
9273
9317
  var require_outside = __commonJS({
9274
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/outside.js"(exports, module) {
9318
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/outside.js"(exports, module) {
9275
9319
  "use strict";
9276
9320
  var SemVer = require_semver();
9277
9321
  var Comparator = require_comparator();
@@ -9338,9 +9382,9 @@ var require_outside = __commonJS({
9338
9382
  }
9339
9383
  });
9340
9384
 
9341
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/gtr.js
9385
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/gtr.js
9342
9386
  var require_gtr = __commonJS({
9343
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/gtr.js"(exports, module) {
9387
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/gtr.js"(exports, module) {
9344
9388
  "use strict";
9345
9389
  var outside = require_outside();
9346
9390
  var gtr = (version, range, options) => outside(version, range, ">", options);
@@ -9348,9 +9392,9 @@ var require_gtr = __commonJS({
9348
9392
  }
9349
9393
  });
9350
9394
 
9351
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/ltr.js
9395
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/ltr.js
9352
9396
  var require_ltr = __commonJS({
9353
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/ltr.js"(exports, module) {
9397
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/ltr.js"(exports, module) {
9354
9398
  "use strict";
9355
9399
  var outside = require_outside();
9356
9400
  var ltr = (version, range, options) => outside(version, range, "<", options);
@@ -9358,9 +9402,9 @@ var require_ltr = __commonJS({
9358
9402
  }
9359
9403
  });
9360
9404
 
9361
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/intersects.js
9405
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/intersects.js
9362
9406
  var require_intersects = __commonJS({
9363
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/intersects.js"(exports, module) {
9407
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/intersects.js"(exports, module) {
9364
9408
  "use strict";
9365
9409
  var Range = require_range();
9366
9410
  var intersects = (r1, r2, options) => {
@@ -9372,9 +9416,9 @@ var require_intersects = __commonJS({
9372
9416
  }
9373
9417
  });
9374
9418
 
9375
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/simplify.js
9419
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/simplify.js
9376
9420
  var require_simplify = __commonJS({
9377
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/simplify.js"(exports, module) {
9421
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/simplify.js"(exports, module) {
9378
9422
  "use strict";
9379
9423
  var satisfies = require_satisfies();
9380
9424
  var compare = require_compare();
@@ -9422,9 +9466,9 @@ var require_simplify = __commonJS({
9422
9466
  }
9423
9467
  });
9424
9468
 
9425
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/subset.js
9469
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/subset.js
9426
9470
  var require_subset = __commonJS({
9427
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/ranges/subset.js"(exports, module) {
9471
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/subset.js"(exports, module) {
9428
9472
  "use strict";
9429
9473
  var Range = require_range();
9430
9474
  var Comparator = require_comparator();
@@ -9584,9 +9628,9 @@ var require_subset = __commonJS({
9584
9628
  }
9585
9629
  });
9586
9630
 
9587
- // ../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/index.js
9631
+ // ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/index.js
9588
9632
  var require_semver2 = __commonJS({
9589
- "../../node_modules/.pnpm/semver@7.8.1/node_modules/semver/index.js"(exports, module) {
9633
+ "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/index.js"(exports, module) {
9590
9634
  "use strict";
9591
9635
  var internalRe = require_re();
9592
9636
  var constants2 = require_constants();
@@ -9685,7 +9729,7 @@ var require_semver2 = __commonJS({
9685
9729
  import fs3 from "fs";
9686
9730
  import path5 from "path";
9687
9731
 
9688
- // ../../node_modules/.pnpm/conf@13.1.0/node_modules/conf/dist/source/index.js
9732
+ // ../../node_modules/.pnpm/conf@15.1.0/node_modules/conf/dist/source/index.js
9689
9733
  import { isDeepStrictEqual } from "util";
9690
9734
  import process7 from "process";
9691
9735
  import fs2 from "fs";
@@ -9693,7 +9737,7 @@ import path4 from "path";
9693
9737
  import crypto from "crypto";
9694
9738
  import assert from "assert";
9695
9739
 
9696
- // ../../node_modules/.pnpm/dot-prop@9.0.0/node_modules/dot-prop/index.js
9740
+ // ../../node_modules/.pnpm/dot-prop@10.2.0/node_modules/dot-prop/index.js
9697
9741
  var isObject = (value) => {
9698
9742
  const type = typeof value;
9699
9743
  return value !== null && (type === "object" || type === "function");
@@ -9703,110 +9747,144 @@ var disallowedKeys = /* @__PURE__ */ new Set([
9703
9747
  "prototype",
9704
9748
  "constructor"
9705
9749
  ]);
9706
- var digits = new Set("0123456789");
9707
- function getPathSegments(path7) {
9750
+ var maxDisallowedKeyLength = Math.max(...[...disallowedKeys].map((key) => key.length));
9751
+ var MAX_ARRAY_INDEX = 1e6;
9752
+ var isDigit = (character) => character >= "0" && character <= "9";
9753
+ function shouldCoerceToNumber(segment) {
9754
+ if (segment === "0") {
9755
+ return true;
9756
+ }
9757
+ if (/^[1-9]\d*$/.test(segment)) {
9758
+ const parsedNumber = Number.parseInt(segment, 10);
9759
+ return parsedNumber <= Number.MAX_SAFE_INTEGER && parsedNumber <= MAX_ARRAY_INDEX;
9760
+ }
9761
+ return false;
9762
+ }
9763
+ function processSegment(segment, parts) {
9764
+ if (disallowedKeys.has(segment)) {
9765
+ return false;
9766
+ }
9767
+ if (segment && shouldCoerceToNumber(segment)) {
9768
+ parts.push(Number.parseInt(segment, 10));
9769
+ } else {
9770
+ parts.push(segment);
9771
+ }
9772
+ return true;
9773
+ }
9774
+ function parsePath(path7) {
9775
+ if (typeof path7 !== "string") {
9776
+ throw new TypeError(`Expected a string, got ${typeof path7}`);
9777
+ }
9708
9778
  const parts = [];
9709
9779
  let currentSegment = "";
9780
+ let indexSegment = "";
9781
+ let hadProperty = false;
9710
9782
  let currentPart = "start";
9711
- let isIgnoring = false;
9783
+ let isEscaping = false;
9784
+ let position = 0;
9712
9785
  for (const character of path7) {
9713
- switch (character) {
9714
- case "\\": {
9715
- if (currentPart === "index") {
9716
- throw new Error("Invalid character in an index");
9717
- }
9718
- if (currentPart === "indexEnd") {
9719
- throw new Error("Invalid character after an index");
9720
- }
9721
- if (isIgnoring) {
9722
- currentSegment += character;
9723
- }
9724
- currentPart = "property";
9725
- isIgnoring = !isIgnoring;
9726
- break;
9786
+ position++;
9787
+ if (isEscaping) {
9788
+ currentSegment += character;
9789
+ isEscaping = false;
9790
+ continue;
9791
+ }
9792
+ if (character === "\\") {
9793
+ if (currentPart === "index") {
9794
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
9727
9795
  }
9796
+ if (currentPart === "indexEnd") {
9797
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
9798
+ }
9799
+ isEscaping = true;
9800
+ currentPart = currentPart === "start" ? "property" : currentPart;
9801
+ continue;
9802
+ }
9803
+ switch (character) {
9728
9804
  case ".": {
9729
9805
  if (currentPart === "index") {
9730
- throw new Error("Invalid character in an index");
9806
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
9731
9807
  }
9732
9808
  if (currentPart === "indexEnd") {
9733
9809
  currentPart = "property";
9734
9810
  break;
9735
9811
  }
9736
- if (isIgnoring) {
9737
- isIgnoring = false;
9738
- currentSegment += character;
9739
- break;
9740
- }
9741
- if (disallowedKeys.has(currentSegment)) {
9812
+ if (!processSegment(currentSegment, parts)) {
9742
9813
  return [];
9743
9814
  }
9744
- parts.push(currentSegment);
9745
9815
  currentSegment = "";
9746
9816
  currentPart = "property";
9747
9817
  break;
9748
9818
  }
9749
9819
  case "[": {
9750
9820
  if (currentPart === "index") {
9751
- throw new Error("Invalid character in an index");
9821
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
9752
9822
  }
9753
9823
  if (currentPart === "indexEnd") {
9754
9824
  currentPart = "index";
9755
9825
  break;
9756
9826
  }
9757
- if (isIgnoring) {
9758
- isIgnoring = false;
9759
- currentSegment += character;
9760
- break;
9761
- }
9762
- if (currentPart === "property") {
9763
- if (disallowedKeys.has(currentSegment)) {
9764
- return [];
9765
- }
9766
- parts.push(currentSegment);
9767
- currentSegment = "";
9827
+ if (currentPart === "property" && currentSegment.length <= maxDisallowedKeyLength && disallowedKeys.has(currentSegment)) {
9828
+ return [];
9768
9829
  }
9830
+ hadProperty = currentPart === "property";
9769
9831
  currentPart = "index";
9770
9832
  break;
9771
9833
  }
9772
9834
  case "]": {
9773
- if (currentPart === "index") {
9774
- parts.push(Number.parseInt(currentSegment, 10));
9775
- currentSegment = "";
9776
- currentPart = "indexEnd";
9835
+ if (currentPart === "indexEnd") {
9836
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
9837
+ }
9838
+ if (currentPart !== "index") {
9839
+ if (currentPart === "start") {
9840
+ currentPart = "property";
9841
+ }
9842
+ currentSegment += character;
9777
9843
  break;
9778
9844
  }
9779
- if (currentPart === "indexEnd") {
9780
- throw new Error("Invalid character after an index");
9845
+ if (indexSegment === "") {
9846
+ currentSegment += "[]";
9847
+ currentPart = "property";
9848
+ break;
9781
9849
  }
9850
+ if ((currentSegment !== "" || hadProperty) && !processSegment(currentSegment, parts)) {
9851
+ return [];
9852
+ }
9853
+ currentSegment = "";
9854
+ hadProperty = false;
9855
+ const parsedNumber = Number.parseInt(indexSegment, 10);
9856
+ const isValidInteger = parsedNumber <= MAX_ARRAY_INDEX && indexSegment === String(parsedNumber);
9857
+ parts.push(isValidInteger ? parsedNumber : indexSegment);
9858
+ indexSegment = "";
9859
+ currentPart = "indexEnd";
9860
+ break;
9782
9861
  }
9783
9862
  default: {
9784
- if (currentPart === "index" && !digits.has(character)) {
9785
- throw new Error("Invalid character in an index");
9863
+ if (currentPart === "index") {
9864
+ if (!isDigit(character)) {
9865
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
9866
+ }
9867
+ indexSegment += character;
9868
+ break;
9786
9869
  }
9787
9870
  if (currentPart === "indexEnd") {
9788
- throw new Error("Invalid character after an index");
9871
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
9789
9872
  }
9790
9873
  if (currentPart === "start") {
9791
9874
  currentPart = "property";
9792
9875
  }
9793
- if (isIgnoring) {
9794
- isIgnoring = false;
9795
- currentSegment += "\\";
9796
- }
9797
9876
  currentSegment += character;
9798
9877
  }
9799
9878
  }
9800
9879
  }
9801
- if (isIgnoring) {
9880
+ if (isEscaping) {
9802
9881
  currentSegment += "\\";
9803
9882
  }
9804
9883
  switch (currentPart) {
9805
9884
  case "property": {
9806
- if (disallowedKeys.has(currentSegment)) {
9885
+ if (!processSegment(currentSegment, parts)) {
9807
9886
  return [];
9808
9887
  }
9809
- parts.push(currentSegment);
9810
9888
  break;
9811
9889
  }
9812
9890
  case "index": {
@@ -9819,33 +9897,43 @@ function getPathSegments(path7) {
9819
9897
  }
9820
9898
  return parts;
9821
9899
  }
9822
- function isStringIndex(object, key) {
9823
- if (typeof key !== "number" && Array.isArray(object)) {
9824
- const index = Number.parseInt(key, 10);
9825
- return Number.isInteger(index) && object[index] === object[key];
9900
+ function normalizePath(path7) {
9901
+ if (typeof path7 === "string") {
9902
+ return parsePath(path7);
9826
9903
  }
9827
- return false;
9828
- }
9829
- function assertNotStringIndex(object, key) {
9830
- if (isStringIndex(object, key)) {
9831
- throw new Error("Cannot use string index");
9904
+ if (Array.isArray(path7)) {
9905
+ const normalized = [];
9906
+ for (const [index, segment] of path7.entries()) {
9907
+ if (typeof segment !== "string" && typeof segment !== "number") {
9908
+ throw new TypeError(`Expected a string or number for path segment at index ${index}, got ${typeof segment}`);
9909
+ }
9910
+ if (typeof segment === "number" && !Number.isFinite(segment)) {
9911
+ throw new TypeError(`Path segment at index ${index} must be a finite number, got ${segment}`);
9912
+ }
9913
+ if (disallowedKeys.has(segment)) {
9914
+ return [];
9915
+ }
9916
+ if (typeof segment === "string" && shouldCoerceToNumber(segment)) {
9917
+ normalized.push(Number.parseInt(segment, 10));
9918
+ } else {
9919
+ normalized.push(segment);
9920
+ }
9921
+ }
9922
+ return normalized;
9832
9923
  }
9924
+ return [];
9833
9925
  }
9834
9926
  function getProperty(object, path7, value) {
9835
- if (!isObject(object) || typeof path7 !== "string") {
9927
+ if (!isObject(object) || typeof path7 !== "string" && !Array.isArray(path7)) {
9836
9928
  return value === void 0 ? object : value;
9837
9929
  }
9838
- const pathArray = getPathSegments(path7);
9930
+ const pathArray = normalizePath(path7);
9839
9931
  if (pathArray.length === 0) {
9840
9932
  return value;
9841
9933
  }
9842
9934
  for (let index = 0; index < pathArray.length; index++) {
9843
9935
  const key = pathArray[index];
9844
- if (isStringIndex(object, key)) {
9845
- object = index === pathArray.length - 1 ? void 0 : null;
9846
- } else {
9847
- object = object[key];
9848
- }
9936
+ object = object[key];
9849
9937
  if (object === void 0 || object === null) {
9850
9938
  if (index !== pathArray.length - 1) {
9851
9939
  return value;
@@ -9856,51 +9944,67 @@ function getProperty(object, path7, value) {
9856
9944
  return object === void 0 ? value : object;
9857
9945
  }
9858
9946
  function setProperty(object, path7, value) {
9859
- if (!isObject(object) || typeof path7 !== "string") {
9947
+ if (!isObject(object) || typeof path7 !== "string" && !Array.isArray(path7)) {
9860
9948
  return object;
9861
9949
  }
9862
9950
  const root = object;
9863
- const pathArray = getPathSegments(path7);
9951
+ const pathArray = normalizePath(path7);
9952
+ if (pathArray.length === 0) {
9953
+ return object;
9954
+ }
9864
9955
  for (let index = 0; index < pathArray.length; index++) {
9865
9956
  const key = pathArray[index];
9866
- assertNotStringIndex(object, key);
9867
9957
  if (index === pathArray.length - 1) {
9868
9958
  object[key] = value;
9869
- } else if (!isObject(object[key])) {
9870
- object[key] = typeof pathArray[index + 1] === "number" ? [] : {};
9959
+ continue;
9871
9960
  }
9961
+ const existingValue = object[key];
9962
+ if (isObject(existingValue)) {
9963
+ object = existingValue;
9964
+ continue;
9965
+ }
9966
+ const nextKey = pathArray[index + 1];
9967
+ const shouldCreateArray = typeof nextKey === "number";
9968
+ object[key] = shouldCreateArray ? [] : {};
9872
9969
  object = object[key];
9873
9970
  }
9874
9971
  return root;
9875
9972
  }
9876
9973
  function deleteProperty(object, path7) {
9877
- if (!isObject(object) || typeof path7 !== "string") {
9974
+ if (!isObject(object) || typeof path7 !== "string" && !Array.isArray(path7)) {
9975
+ return false;
9976
+ }
9977
+ const pathArray = normalizePath(path7);
9978
+ if (pathArray.length === 0) {
9878
9979
  return false;
9879
9980
  }
9880
- const pathArray = getPathSegments(path7);
9881
9981
  for (let index = 0; index < pathArray.length; index++) {
9882
9982
  const key = pathArray[index];
9883
- assertNotStringIndex(object, key);
9884
9983
  if (index === pathArray.length - 1) {
9984
+ const existed = Object.hasOwn(object, key);
9985
+ if (!existed) {
9986
+ return false;
9987
+ }
9885
9988
  delete object[key];
9886
9989
  return true;
9887
9990
  }
9888
- object = object[key];
9889
- if (!isObject(object)) {
9991
+ const existingValue = object[key];
9992
+ if (!isObject(existingValue)) {
9890
9993
  return false;
9891
9994
  }
9995
+ object = existingValue;
9892
9996
  }
9893
9997
  }
9894
9998
  function hasProperty(object, path7) {
9895
- if (!isObject(object) || typeof path7 !== "string") {
9999
+ if (!isObject(object) || typeof path7 !== "string" && !Array.isArray(path7)) {
9896
10000
  return false;
9897
10001
  }
9898
- const pathArray = getPathSegments(path7);
10002
+ const pathArray = normalizePath(path7);
9899
10003
  if (pathArray.length === 0) {
9900
10004
  return false;
9901
10005
  }
9902
10006
  for (const key of pathArray) {
9903
- if (!isObject(object) || !(key in object) || isStringIndex(object, key)) {
10007
+ if (!isObject(object) || !(key in object)) {
9904
10008
  return false;
9905
10009
  }
9906
10010
  object = object[key];
@@ -10364,7 +10468,7 @@ function writeFileSync(filePath, data, options = DEFAULT_WRITE_OPTIONS) {
10364
10468
  }
10365
10469
  }
10366
10470
 
10367
- // ../../node_modules/.pnpm/conf@13.1.0/node_modules/conf/dist/source/index.js
10471
+ // ../../node_modules/.pnpm/conf@15.1.0/node_modules/conf/dist/source/index.js
10368
10472
  var import__ = __toESM(require__(), 1);
10369
10473
  var import_ajv_formats = __toESM(require_dist(), 1);
10370
10474
 
@@ -10482,7 +10586,7 @@ var debounceFunction = (inputFunction, options = {}) => {
10482
10586
  };
10483
10587
  var debounce_fn_default = debounceFunction;
10484
10588
 
10485
- // ../../node_modules/.pnpm/conf@13.1.0/node_modules/conf/dist/source/index.js
10589
+ // ../../node_modules/.pnpm/conf@15.1.0/node_modules/conf/dist/source/index.js
10486
10590
  var import_semver = __toESM(require_semver2(), 1);
10487
10591
 
10488
10592
  // ../../node_modules/.pnpm/uint8array-extras@1.5.0/node_modules/uint8array-extras/index.js
@@ -10551,11 +10655,16 @@ function stringToUint8Array(string) {
10551
10655
  }
10552
10656
  var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
10553
10657
 
10554
- // ../../node_modules/.pnpm/conf@13.1.0/node_modules/conf/dist/source/index.js
10555
- var ajvFormats = import_ajv_formats.default.default;
10556
- var encryptionAlgorithm = "aes-256-cbc";
10658
+ // ../../node_modules/.pnpm/conf@15.1.0/node_modules/conf/dist/source/index.js
10659
+ var defaultEncryptionAlgorithm = "aes-256-cbc";
10660
+ var supportedEncryptionAlgorithms = /* @__PURE__ */ new Set([
10661
+ "aes-256-cbc",
10662
+ "aes-256-gcm",
10663
+ "aes-256-ctr"
10664
+ ]);
10665
+ var isSupportedEncryptionAlgorithm = (value) => typeof value === "string" && supportedEncryptionAlgorithms.has(value);
10557
10666
  var createPlainObject = () => /* @__PURE__ */ Object.create(null);
10558
- var isExist = (data) => data !== void 0 && data !== null;
10667
+ var isExist = (data) => data !== void 0;
10559
10668
  var checkValueType = (key, value) => {
10560
10669
  const nonJsonTypes = /* @__PURE__ */ new Set([
10561
10670
  "undefined",
@@ -10574,77 +10683,24 @@ var Conf = class {
10574
10683
  events;
10575
10684
  #validator;
10576
10685
  #encryptionKey;
10686
+ #encryptionAlgorithm;
10577
10687
  #options;
10578
10688
  #defaultValues = {};
10689
+ #isInMigration = false;
10690
+ #watcher;
10691
+ #watchFile;
10692
+ #debouncedChangeHandler;
10579
10693
  constructor(partialOptions = {}) {
10580
- const options = {
10581
- configName: "config",
10582
- fileExtension: "json",
10583
- projectSuffix: "nodejs",
10584
- clearInvalidConfig: false,
10585
- accessPropertiesByDotNotation: true,
10586
- configFileMode: 438,
10587
- ...partialOptions
10588
- };
10589
- if (!options.cwd) {
10590
- if (!options.projectName) {
10591
- throw new Error("Please specify the `projectName` option.");
10592
- }
10593
- options.cwd = envPaths(options.projectName, { suffix: options.projectSuffix }).config;
10594
- }
10694
+ const options = this.#prepareOptions(partialOptions);
10595
10695
  this.#options = options;
10596
- if (options.schema ?? options.ajvOptions ?? options.rootSchema) {
10597
- if (options.schema && typeof options.schema !== "object") {
10598
- throw new TypeError("The `schema` option must be an object.");
10599
- }
10600
- const ajv = new import__.Ajv2020({
10601
- allErrors: true,
10602
- useDefaults: true,
10603
- ...options.ajvOptions
10604
- });
10605
- ajvFormats(ajv);
10606
- const schema = {
10607
- ...options.rootSchema,
10608
- type: "object",
10609
- properties: options.schema
10610
- };
10611
- this.#validator = ajv.compile(schema);
10612
- for (const [key, value] of Object.entries(options.schema ?? {})) {
10613
- if (value?.default) {
10614
- this.#defaultValues[key] = value.default;
10615
- }
10616
- }
10617
- }
10618
- if (options.defaults) {
10619
- this.#defaultValues = {
10620
- ...this.#defaultValues,
10621
- ...options.defaults
10622
- };
10623
- }
10624
- if (options.serialize) {
10625
- this._serialize = options.serialize;
10626
- }
10627
- if (options.deserialize) {
10628
- this._deserialize = options.deserialize;
10629
- }
10696
+ this.#setupValidator(options);
10697
+ this.#applyDefaultValues(options);
10698
+ this.#configureSerialization(options);
10630
10699
  this.events = new EventTarget();
10631
10700
  this.#encryptionKey = options.encryptionKey;
10632
- const fileExtension = options.fileExtension ? `.${options.fileExtension}` : "";
10633
- this.path = path4.resolve(options.cwd, `${options.configName ?? "config"}${fileExtension}`);
10634
- const fileStore = this.store;
10635
- const store = Object.assign(createPlainObject(), options.defaults, fileStore);
10636
- if (options.migrations) {
10637
- if (!options.projectVersion) {
10638
- throw new Error("Please specify the `projectVersion` option.");
10639
- }
10640
- this._migrate(options.migrations, options.projectVersion, options.beforeEachMigration);
10641
- }
10642
- this._validate(store);
10643
- try {
10644
- assert.deepEqual(fileStore, store);
10645
- } catch {
10646
- this.store = store;
10647
- }
10701
+ this.#encryptionAlgorithm = options.encryptionAlgorithm ?? defaultEncryptionAlgorithm;
10702
+ this.path = this.#resolvePath(options);
10703
+ this.#initializeStore(options);
10648
10704
  if (options.watch) {
10649
10705
  this._watch();
10650
10706
  }
@@ -10672,6 +10728,9 @@ var Conf = class {
10672
10728
  if (this.#options.accessPropertiesByDotNotation) {
10673
10729
  setProperty(store, key2, value2);
10674
10730
  } else {
10731
+ if (key2 === "__proto__" || key2 === "constructor" || key2 === "prototype") {
10732
+ return;
10733
+ }
10675
10734
  store[key2] = value2;
10676
10735
  }
10677
10736
  };
@@ -10685,17 +10744,20 @@ var Conf = class {
10685
10744
  }
10686
10745
  this.store = store;
10687
10746
  }
10688
- /**
10689
- Check if an item exists.
10690
-
10691
- @param key - The key of the item to check.
10692
- */
10693
10747
  has(key) {
10694
10748
  if (this.#options.accessPropertiesByDotNotation) {
10695
10749
  return hasProperty(this.store, key);
10696
10750
  }
10697
10751
  return key in this.store;
10698
10752
  }
10753
+ appendToArray(key, value) {
10754
+ checkValueType(key, value);
10755
+ const array = this.#options.accessPropertiesByDotNotation ? this._get(key, []) : key in this.store ? this.store[key] : [];
10756
+ if (!Array.isArray(array)) {
10757
+ throw new TypeError(`The key \`${key}\` is already set to a non-array value`);
10758
+ }
10759
+ this.set(key, [...array, value]);
10760
+ }
10699
10761
  /**
10700
10762
  Reset items to their default values, as defined by the `defaults` or `schema` option.
10701
10763
 
@@ -10725,18 +10787,19 @@ var Conf = class {
10725
10787
  This resets known items to their default values, if defined by the `defaults` or `schema` option.
10726
10788
  */
10727
10789
  clear() {
10728
- this.store = createPlainObject();
10790
+ const newStore = createPlainObject();
10729
10791
  for (const key of Object.keys(this.#defaultValues)) {
10730
- this.reset(key);
10792
+ if (isExist(this.#defaultValues[key])) {
10793
+ checkValueType(key, this.#defaultValues[key]);
10794
+ if (this.#options.accessPropertiesByDotNotation) {
10795
+ setProperty(newStore, key, this.#defaultValues[key]);
10796
+ } else {
10797
+ newStore[key] = this.#defaultValues[key];
10798
+ }
10799
+ }
10731
10800
  }
10801
+ this.store = newStore;
10732
10802
  }
10733
- /**
10734
- Watches the given `key`, calling `callback` on any changes.
10735
-
10736
- @param key - The key to watch.
10737
- @param callback - A callback function that is called on any changes. When a `key` is first set `oldValue` will be `undefined`, and when a key is deleted `newValue` will be `undefined`.
10738
- @returns A function, that when called, will unsubscribe.
10739
- */
10740
10803
  onDidChange(key, callback) {
10741
10804
  if (typeof key !== "string") {
10742
10805
  throw new TypeError(`Expected \`key\` to be of type \`string\`, got ${typeof key}`);
@@ -10744,7 +10807,7 @@ var Conf = class {
10744
10807
  if (typeof callback !== "function") {
10745
10808
  throw new TypeError(`Expected \`callback\` to be of type \`function\`, got ${typeof callback}`);
10746
10809
  }
10747
- return this._handleChange(() => this.get(key), callback);
10810
+ return this._handleValueChange(() => this.get(key), callback);
10748
10811
  }
10749
10812
  /**
10750
10813
  Watches the whole config object, calling `callback` on any changes.
@@ -10756,56 +10819,171 @@ var Conf = class {
10756
10819
  if (typeof callback !== "function") {
10757
10820
  throw new TypeError(`Expected \`callback\` to be of type \`function\`, got ${typeof callback}`);
10758
10821
  }
10759
- return this._handleChange(() => this.store, callback);
10822
+ return this._handleStoreChange(callback);
10760
10823
  }
10761
10824
  get size() {
10762
- return Object.keys(this.store).length;
10825
+ const entries = Object.keys(this.store);
10826
+ return entries.filter((key) => !this._isReservedKeyPath(key)).length;
10763
10827
  }
10828
+ /**
10829
+ Get all the config as an object or replace the current config with an object.
10830
+
10831
+ @example
10832
+ ```
10833
+ console.log(config.store);
10834
+ //=> {name: 'John', age: 30}
10835
+ ```
10836
+
10837
+ @example
10838
+ ```
10839
+ config.store = {
10840
+ hello: 'world'
10841
+ };
10842
+ ```
10843
+ */
10764
10844
  get store() {
10765
10845
  try {
10766
10846
  const data = fs2.readFileSync(this.path, this.#encryptionKey ? null : "utf8");
10767
- const dataString = this._encryptData(data);
10768
- const deserializedData = this._deserialize(dataString);
10769
- this._validate(deserializedData);
10770
- return Object.assign(createPlainObject(), deserializedData);
10847
+ const dataString = this._decryptData(data);
10848
+ const parseStore = (value) => {
10849
+ const deserializedData = this._deserialize(value);
10850
+ if (!this.#isInMigration) {
10851
+ this._validate(deserializedData);
10852
+ }
10853
+ return Object.assign(createPlainObject(), deserializedData);
10854
+ };
10855
+ return parseStore(dataString);
10771
10856
  } catch (error) {
10772
10857
  if (error?.code === "ENOENT") {
10773
10858
  this._ensureDirectory();
10774
10859
  return createPlainObject();
10775
10860
  }
10776
- if (this.#options.clearInvalidConfig && error.name === "SyntaxError") {
10777
- return createPlainObject();
10861
+ if (this.#options.clearInvalidConfig) {
10862
+ const errorInstance = error;
10863
+ if (errorInstance.name === "SyntaxError") {
10864
+ return createPlainObject();
10865
+ }
10866
+ if (errorInstance.message?.startsWith("Config schema violation:")) {
10867
+ return createPlainObject();
10868
+ }
10869
+ if (errorInstance.message === "Failed to decrypt config data.") {
10870
+ return createPlainObject();
10871
+ }
10778
10872
  }
10779
10873
  throw error;
10780
10874
  }
10781
10875
  }
10782
10876
  set store(value) {
10783
10877
  this._ensureDirectory();
10784
- this._validate(value);
10878
+ if (!hasProperty(value, INTERNAL_KEY)) {
10879
+ try {
10880
+ const data = fs2.readFileSync(this.path, this.#encryptionKey ? null : "utf8");
10881
+ const dataString = this._decryptData(data);
10882
+ const currentStore = this._deserialize(dataString);
10883
+ if (hasProperty(currentStore, INTERNAL_KEY)) {
10884
+ setProperty(value, INTERNAL_KEY, getProperty(currentStore, INTERNAL_KEY));
10885
+ }
10886
+ } catch {
10887
+ }
10888
+ }
10889
+ if (!this.#isInMigration) {
10890
+ this._validate(value);
10891
+ }
10785
10892
  this._write(value);
10786
10893
  this.events.dispatchEvent(new Event("change"));
10787
10894
  }
10788
10895
  *[Symbol.iterator]() {
10789
10896
  for (const [key, value] of Object.entries(this.store)) {
10790
- yield [key, value];
10897
+ if (!this._isReservedKeyPath(key)) {
10898
+ yield [key, value];
10899
+ }
10791
10900
  }
10792
10901
  }
10793
- _encryptData(data) {
10794
- if (!this.#encryptionKey) {
10902
+ /**
10903
+ Close the file watcher if one exists. This is useful in tests to prevent the process from hanging.
10904
+ */
10905
+ _closeWatcher() {
10906
+ if (this.#watcher) {
10907
+ this.#watcher.close();
10908
+ this.#watcher = void 0;
10909
+ }
10910
+ if (this.#watchFile) {
10911
+ fs2.unwatchFile(this.path);
10912
+ this.#watchFile = false;
10913
+ }
10914
+ this.#debouncedChangeHandler = void 0;
10915
+ }
10916
+ _decryptData(data) {
10917
+ const encryptionKey = this.#encryptionKey;
10918
+ if (!encryptionKey) {
10795
10919
  return typeof data === "string" ? data : uint8ArrayToString(data);
10796
10920
  }
10797
- try {
10798
- const initializationVector = data.slice(0, 16);
10799
- const password = crypto.pbkdf2Sync(this.#encryptionKey, initializationVector.toString(), 1e4, 32, "sha512");
10921
+ const encryptionAlgorithm = this.#encryptionAlgorithm;
10922
+ const authenticationTagLength = encryptionAlgorithm === "aes-256-gcm" ? 16 : 0;
10923
+ const separatorCodePoint = ":".codePointAt(0);
10924
+ const separatorByte = typeof data === "string" ? data.codePointAt(16) : data[16];
10925
+ const hasSeparator = separatorCodePoint !== void 0 && separatorByte === separatorCodePoint;
10926
+ if (!hasSeparator) {
10927
+ if (encryptionAlgorithm === "aes-256-cbc") {
10928
+ return typeof data === "string" ? data : uint8ArrayToString(data);
10929
+ }
10930
+ throw new Error("Failed to decrypt config data.");
10931
+ }
10932
+ const getEncryptedPayload = (dataUpdate2) => {
10933
+ if (authenticationTagLength === 0) {
10934
+ return { ciphertext: dataUpdate2 };
10935
+ }
10936
+ const authenticationTagStart = dataUpdate2.length - authenticationTagLength;
10937
+ if (authenticationTagStart < 0) {
10938
+ throw new Error("Invalid authentication tag length.");
10939
+ }
10940
+ return {
10941
+ ciphertext: dataUpdate2.slice(0, authenticationTagStart),
10942
+ authenticationTag: dataUpdate2.slice(authenticationTagStart)
10943
+ };
10944
+ };
10945
+ const initializationVector = data.slice(0, 16);
10946
+ const slice = data.slice(17);
10947
+ const dataUpdate = typeof slice === "string" ? stringToUint8Array(slice) : slice;
10948
+ const decrypt = (salt) => {
10949
+ const { ciphertext, authenticationTag } = getEncryptedPayload(dataUpdate);
10950
+ const password = crypto.pbkdf2Sync(encryptionKey, salt, 1e4, 32, "sha512");
10800
10951
  const decipher = crypto.createDecipheriv(encryptionAlgorithm, password, initializationVector);
10801
- const slice = data.slice(17);
10802
- const dataUpdate = typeof slice === "string" ? stringToUint8Array(slice) : slice;
10803
- return uint8ArrayToString(concatUint8Arrays([decipher.update(dataUpdate), decipher.final()]));
10952
+ if (authenticationTag) {
10953
+ decipher.setAuthTag(authenticationTag);
10954
+ }
10955
+ return uint8ArrayToString(concatUint8Arrays([decipher.update(ciphertext), decipher.final()]));
10956
+ };
10957
+ try {
10958
+ return decrypt(initializationVector);
10804
10959
  } catch {
10960
+ try {
10961
+ return decrypt(initializationVector.toString());
10962
+ } catch {
10963
+ }
10964
+ }
10965
+ if (encryptionAlgorithm === "aes-256-cbc") {
10966
+ return typeof data === "string" ? data : uint8ArrayToString(data);
10805
10967
  }
10806
- return data.toString();
10968
+ throw new Error("Failed to decrypt config data.");
10807
10969
  }
10808
- _handleChange(getter, callback) {
10970
+ _handleStoreChange(callback) {
10971
+ let currentValue = this.store;
10972
+ const onChange = () => {
10973
+ const oldValue = currentValue;
10974
+ const newValue = this.store;
10975
+ if (isDeepStrictEqual(newValue, oldValue)) {
10976
+ return;
10977
+ }
10978
+ currentValue = newValue;
10979
+ callback.call(this, newValue, oldValue);
10980
+ };
10981
+ this.events.addEventListener("change", onChange);
10982
+ return () => {
10983
+ this.events.removeEventListener("change", onChange);
10984
+ };
10985
+ }
10986
+ _handleValueChange(getter, callback) {
10809
10987
  let currentValue = getter();
10810
10988
  const onChange = () => {
10811
10989
  const oldValue = currentValue;
@@ -10839,11 +11017,17 @@ var Conf = class {
10839
11017
  }
10840
11018
  _write(value) {
10841
11019
  let data = this._serialize(value);
10842
- if (this.#encryptionKey) {
11020
+ const encryptionKey = this.#encryptionKey;
11021
+ if (encryptionKey) {
10843
11022
  const initializationVector = crypto.randomBytes(16);
10844
- const password = crypto.pbkdf2Sync(this.#encryptionKey, initializationVector.toString(), 1e4, 32, "sha512");
10845
- const cipher = crypto.createCipheriv(encryptionAlgorithm, password, initializationVector);
10846
- data = concatUint8Arrays([initializationVector, stringToUint8Array(":"), cipher.update(stringToUint8Array(data)), cipher.final()]);
11023
+ const password = crypto.pbkdf2Sync(encryptionKey, initializationVector, 1e4, 32, "sha512");
11024
+ const cipher = crypto.createCipheriv(this.#encryptionAlgorithm, password, initializationVector);
11025
+ const encryptedData = concatUint8Arrays([cipher.update(stringToUint8Array(data)), cipher.final()]);
11026
+ const encryptedParts = [initializationVector, stringToUint8Array(":"), encryptedData];
11027
+ if (this.#encryptionAlgorithm === "aes-256-gcm") {
11028
+ encryptedParts.push(cipher.getAuthTag());
11029
+ }
11030
+ data = concatUint8Arrays(encryptedParts);
10847
11031
  }
10848
11032
  if (process7.env.SNAP) {
10849
11033
  fs2.writeFileSync(this.path, data, { mode: this.#options.configFileMode });
@@ -10864,20 +11048,36 @@ var Conf = class {
10864
11048
  if (!fs2.existsSync(this.path)) {
10865
11049
  this._write(createPlainObject());
10866
11050
  }
10867
- if (process7.platform === "win32") {
10868
- fs2.watch(this.path, { persistent: false }, debounce_fn_default(() => {
11051
+ if (process7.platform === "win32" || process7.platform === "darwin") {
11052
+ this.#debouncedChangeHandler ??= debounce_fn_default(() => {
10869
11053
  this.events.dispatchEvent(new Event("change"));
10870
- }, { wait: 100 }));
11054
+ }, { wait: 100 });
11055
+ const directory = path4.dirname(this.path);
11056
+ const basename = path4.basename(this.path);
11057
+ this.#watcher = fs2.watch(directory, { persistent: false, encoding: "utf8" }, (_eventType, filename) => {
11058
+ if (filename && filename !== basename) {
11059
+ return;
11060
+ }
11061
+ if (typeof this.#debouncedChangeHandler === "function") {
11062
+ this.#debouncedChangeHandler();
11063
+ }
11064
+ });
10871
11065
  } else {
10872
- fs2.watchFile(this.path, { persistent: false }, debounce_fn_default(() => {
11066
+ this.#debouncedChangeHandler ??= debounce_fn_default(() => {
10873
11067
  this.events.dispatchEvent(new Event("change"));
10874
- }, { wait: 5e3 }));
11068
+ }, { wait: 1e3 });
11069
+ fs2.watchFile(this.path, { persistent: false }, (_current, _previous) => {
11070
+ if (typeof this.#debouncedChangeHandler === "function") {
11071
+ this.#debouncedChangeHandler();
11072
+ }
11073
+ });
11074
+ this.#watchFile = true;
10875
11075
  }
10876
11076
  }
10877
11077
  _migrate(migrations, versionToMigrate, beforeEachMigration) {
10878
11078
  let previousMigratedVersion = this._get(MIGRATION_KEY, "0.0.0");
10879
11079
  const newerVersions = Object.keys(migrations).filter((candidateVersion) => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate));
10880
- let storeBackup = { ...this.store };
11080
+ let storeBackup = structuredClone(this.store);
10881
11081
  for (const version of newerVersions) {
10882
11082
  try {
10883
11083
  if (beforeEachMigration) {
@@ -10892,10 +11092,11 @@ var Conf = class {
10892
11092
  migration?.(this);
10893
11093
  this._set(MIGRATION_KEY, version);
10894
11094
  previousMigratedVersion = version;
10895
- storeBackup = { ...this.store };
11095
+ storeBackup = structuredClone(this.store);
10896
11096
  } catch (error) {
10897
11097
  this.store = storeBackup;
10898
- throw new Error(`Something went wrong during the migration! Changes applied to the store until this failed migration will be restored. ${error}`);
11098
+ const errorMessage = error instanceof Error ? error.message : String(error);
11099
+ throw new Error(`Something went wrong during the migration! Changes applied to the store until this failed migration will be restored. ${errorMessage}`);
10899
11100
  }
10900
11101
  }
10901
11102
  if (this._isVersionInRangeFormat(previousMigratedVersion) || !import_semver.default.eq(previousMigratedVersion, versionToMigrate)) {
@@ -10903,23 +11104,31 @@ var Conf = class {
10903
11104
  }
10904
11105
  }
10905
11106
  _containsReservedKey(key) {
10906
- if (typeof key === "object") {
10907
- const firsKey = Object.keys(key)[0];
10908
- if (firsKey === INTERNAL_KEY) {
10909
- return true;
10910
- }
11107
+ if (typeof key === "string") {
11108
+ return this._isReservedKeyPath(key);
10911
11109
  }
10912
- if (typeof key !== "string") {
11110
+ if (!key || typeof key !== "object") {
10913
11111
  return false;
10914
11112
  }
10915
- if (this.#options.accessPropertiesByDotNotation) {
10916
- if (key.startsWith(`${INTERNAL_KEY}.`)) {
11113
+ return this._objectContainsReservedKey(key);
11114
+ }
11115
+ _objectContainsReservedKey(value) {
11116
+ if (!value || typeof value !== "object") {
11117
+ return false;
11118
+ }
11119
+ for (const [candidateKey, candidateValue] of Object.entries(value)) {
11120
+ if (this._isReservedKeyPath(candidateKey)) {
11121
+ return true;
11122
+ }
11123
+ if (this._objectContainsReservedKey(candidateValue)) {
10917
11124
  return true;
10918
11125
  }
10919
- return false;
10920
11126
  }
10921
11127
  return false;
10922
11128
  }
11129
+ _isReservedKeyPath(candidate) {
11130
+ return candidate === INTERNAL_KEY || candidate.startsWith(`${INTERNAL_KEY}.`);
11131
+ }
10923
11132
  _isVersionInRangeFormat(version) {
10924
11133
  return import_semver.default.clean(version) === null;
10925
11134
  }
@@ -10946,32 +11155,150 @@ var Conf = class {
10946
11155
  setProperty(store, key, value);
10947
11156
  this.store = store;
10948
11157
  }
10949
- };
10950
-
10951
- // ../sdk/dist/index.js
10952
- var LinkSdkError = class extends Error {
10953
- code;
10954
- cause;
10955
- constructor(message, options) {
10956
- super(message);
10957
- this.name = new.target.name;
10958
- this.code = options?.code ?? "sdk_error";
10959
- this.cause = options?.cause;
10960
- }
10961
- };
10962
- var LinkConfigurationError = class extends LinkSdkError {
10963
- constructor(message, options) {
10964
- super(message, { code: "configuration_error", ...options });
10965
- }
10966
- };
10967
- var LinkAuthenticationError = class extends LinkSdkError {
10968
- constructor(message, options) {
10969
- super(message, { code: "not_authenticated", ...options });
11158
+ #prepareOptions(partialOptions) {
11159
+ const options = {
11160
+ configName: "config",
11161
+ fileExtension: "json",
11162
+ projectSuffix: "nodejs",
11163
+ clearInvalidConfig: false,
11164
+ accessPropertiesByDotNotation: true,
11165
+ configFileMode: 438,
11166
+ ...partialOptions
11167
+ };
11168
+ options.encryptionAlgorithm ??= defaultEncryptionAlgorithm;
11169
+ if (!isSupportedEncryptionAlgorithm(options.encryptionAlgorithm)) {
11170
+ throw new TypeError(`The \`encryptionAlgorithm\` option must be one of: ${[...supportedEncryptionAlgorithms].join(", ")}`);
11171
+ }
11172
+ if (!options.cwd) {
11173
+ if (!options.projectName) {
11174
+ throw new Error("Please specify the `projectName` option.");
11175
+ }
11176
+ options.cwd = envPaths(options.projectName, { suffix: options.projectSuffix }).config;
11177
+ }
11178
+ if (typeof options.fileExtension === "string") {
11179
+ options.fileExtension = options.fileExtension.replace(/^\.+/, "");
11180
+ }
11181
+ return options;
10970
11182
  }
10971
- };
10972
- var LinkTransportError = class extends LinkSdkError {
10973
- constructor(message, options) {
10974
- super(message, { code: "transport_error", ...options });
11183
+ #setupValidator(options) {
11184
+ if (!(options.schema ?? options.ajvOptions ?? options.rootSchema)) {
11185
+ return;
11186
+ }
11187
+ if (options.schema && typeof options.schema !== "object") {
11188
+ throw new TypeError("The `schema` option must be an object.");
11189
+ }
11190
+ const ajvFormats = import_ajv_formats.default.default;
11191
+ const ajv = new import__.Ajv2020({
11192
+ allErrors: true,
11193
+ useDefaults: true,
11194
+ ...options.ajvOptions
11195
+ });
11196
+ ajvFormats(ajv);
11197
+ const schema = {
11198
+ ...options.rootSchema,
11199
+ type: "object",
11200
+ properties: options.schema
11201
+ };
11202
+ this.#validator = ajv.compile(schema);
11203
+ this.#captureSchemaDefaults(options.schema);
11204
+ }
11205
+ #captureSchemaDefaults(schemaConfig) {
11206
+ const schemaEntries = Object.entries(schemaConfig ?? {});
11207
+ for (const [key, schemaDefinition] of schemaEntries) {
11208
+ if (!schemaDefinition || typeof schemaDefinition !== "object") {
11209
+ continue;
11210
+ }
11211
+ if (!Object.hasOwn(schemaDefinition, "default")) {
11212
+ continue;
11213
+ }
11214
+ const { default: defaultValue } = schemaDefinition;
11215
+ if (defaultValue === void 0) {
11216
+ continue;
11217
+ }
11218
+ this.#defaultValues[key] = defaultValue;
11219
+ }
11220
+ }
11221
+ #applyDefaultValues(options) {
11222
+ if (options.defaults) {
11223
+ Object.assign(this.#defaultValues, options.defaults);
11224
+ }
11225
+ }
11226
+ #configureSerialization(options) {
11227
+ if (options.serialize) {
11228
+ this._serialize = options.serialize;
11229
+ }
11230
+ if (options.deserialize) {
11231
+ this._deserialize = options.deserialize;
11232
+ }
11233
+ }
11234
+ #resolvePath(options) {
11235
+ const normalizedFileExtension = typeof options.fileExtension === "string" ? options.fileExtension : void 0;
11236
+ const fileExtension = normalizedFileExtension ? `.${normalizedFileExtension}` : "";
11237
+ return path4.resolve(options.cwd, `${options.configName ?? "config"}${fileExtension}`);
11238
+ }
11239
+ #initializeStore(options) {
11240
+ if (options.migrations) {
11241
+ this.#runMigrations(options);
11242
+ this._validate(this.store);
11243
+ return;
11244
+ }
11245
+ const fileStore = this.store;
11246
+ const storeWithDefaults = Object.assign(createPlainObject(), options.defaults ?? {}, fileStore);
11247
+ this._validate(storeWithDefaults);
11248
+ try {
11249
+ assert.deepEqual(fileStore, storeWithDefaults);
11250
+ } catch {
11251
+ this.store = storeWithDefaults;
11252
+ }
11253
+ }
11254
+ #runMigrations(options) {
11255
+ const { migrations, projectVersion } = options;
11256
+ if (!migrations) {
11257
+ return;
11258
+ }
11259
+ if (!projectVersion) {
11260
+ throw new Error("Please specify the `projectVersion` option.");
11261
+ }
11262
+ this.#isInMigration = true;
11263
+ try {
11264
+ const fileStore = this.store;
11265
+ const storeWithDefaults = Object.assign(createPlainObject(), options.defaults ?? {}, fileStore);
11266
+ try {
11267
+ assert.deepEqual(fileStore, storeWithDefaults);
11268
+ } catch {
11269
+ this._write(storeWithDefaults);
11270
+ }
11271
+ this._migrate(migrations, projectVersion, options.beforeEachMigration);
11272
+ } finally {
11273
+ this.#isInMigration = false;
11274
+ }
11275
+ }
11276
+ };
11277
+
11278
+ // ../sdk/dist/index.js
11279
+ var LinkSdkError = class extends Error {
11280
+ code;
11281
+ cause;
11282
+ constructor(message, options) {
11283
+ super(message);
11284
+ this.name = new.target.name;
11285
+ this.code = options?.code ?? "sdk_error";
11286
+ this.cause = options?.cause;
11287
+ }
11288
+ };
11289
+ var LinkConfigurationError = class extends LinkSdkError {
11290
+ constructor(message, options) {
11291
+ super(message, { code: "configuration_error", ...options });
11292
+ }
11293
+ };
11294
+ var LinkAuthenticationError = class extends LinkSdkError {
11295
+ constructor(message, options) {
11296
+ super(message, { code: "not_authenticated", ...options });
11297
+ }
11298
+ };
11299
+ var LinkTransportError = class extends LinkSdkError {
11300
+ constructor(message, options) {
11301
+ super(message, { code: "transport_error", ...options });
10975
11302
  }
10976
11303
  };
10977
11304
  var LinkAuthorizationDeclinedError = class extends LinkSdkError {
@@ -11394,10 +11721,8 @@ var PaymentMethodsResource = class {
11394
11721
  url: this.paymentDetailsEndpoint
11395
11722
  });
11396
11723
  if (status < 200 || status >= 300) {
11397
- const body2 = data;
11398
- const msg = body2?.error ?? body2?.message ?? (rawBody || "unknown error");
11399
11724
  throw new LinkApiError(
11400
- `Failed to list payment methods (${status}): ${msg}`,
11725
+ `Failed to list payment methods (${status}): ${extractErrorMessage(data, rawBody)}`,
11401
11726
  { status, rawBody, details: data }
11402
11727
  );
11403
11728
  }
@@ -11479,10 +11804,8 @@ var ShippingAddressResource = class {
11479
11804
  url: this.shippingAddressesEndpoint
11480
11805
  });
11481
11806
  if (status < 200 || status >= 300) {
11482
- const body2 = data;
11483
- const msg = body2?.error ?? body2?.message ?? (rawBody || "unknown error");
11484
11807
  throw new LinkApiError(
11485
- `Failed to list shipping addresses (${status}): ${msg}`,
11808
+ `Failed to list shipping addresses (${status}): ${extractErrorMessage(data, rawBody)}`,
11486
11809
  { status, rawBody, details: data }
11487
11810
  );
11488
11811
  }
@@ -11562,6 +11885,13 @@ function normalizeSpendRequest(data) {
11562
11885
  }
11563
11886
  return sr;
11564
11887
  }
11888
+ function getDuplicateSpendRequest(error) {
11889
+ if (!(error instanceof LinkApiError)) return null;
11890
+ const details = error.details;
11891
+ const duplicate = details?.error?.duplicate_spend_request;
11892
+ if (!duplicate || typeof duplicate !== "object") return null;
11893
+ return normalizeSpendRequest(duplicate);
11894
+ }
11565
11895
  function extractApiError(data, rawBody) {
11566
11896
  if (data && typeof data === "object") {
11567
11897
  const body = data;
@@ -11963,15 +12293,9 @@ var UserInfoResource = class {
11963
12293
  url: this.userInfoEndpoint
11964
12294
  });
11965
12295
  if (status < 200 || status >= 300) {
11966
- const body2 = data;
11967
- const msg = body2?.error ?? body2?.message ?? (rawBody || "unknown error");
11968
12296
  throw new LinkApiError(
11969
- `Failed to retrieve user info (${status}): ${msg}`,
11970
- {
11971
- status,
11972
- rawBody,
11973
- details: data
11974
- }
12297
+ `Failed to retrieve user info (${status}): ${extractErrorMessage(data, rawBody)}`,
12298
+ { status, rawBody, details: data }
11975
12299
  );
11976
12300
  }
11977
12301
  const body = data;
@@ -12112,10 +12436,8 @@ var WebBotAuthResource = class {
12112
12436
  body: JSON.stringify({ url })
12113
12437
  });
12114
12438
  if (status < 200 || status >= 300) {
12115
- const body2 = data;
12116
- const msg = body2?.error ?? body2?.message ?? (rawBody || "unknown error");
12117
12439
  throw new LinkApiError(
12118
- `Failed to get web bot auth headers (${status}): ${msg}`,
12440
+ `Failed to get web bot auth headers (${status}): ${extractErrorMessage(data, rawBody)}`,
12119
12441
  { status, rawBody, details: data }
12120
12442
  );
12121
12443
  }
@@ -12280,6 +12602,98 @@ function normalizeScopeInput(scope) {
12280
12602
  return normalized.length > 0 ? normalized.join(" ") : void 0;
12281
12603
  }
12282
12604
 
12605
+ // src/auth/merge-access.ts
12606
+ var DEFAULT_SCOPE_TOKENS = DEFAULT_SCOPE.split(" ");
12607
+ function dedupePreserveOrder(values) {
12608
+ const seen = /* @__PURE__ */ new Set();
12609
+ const deduped = [];
12610
+ for (const value of values) {
12611
+ if (seen.has(value)) {
12612
+ continue;
12613
+ }
12614
+ seen.add(value);
12615
+ deduped.push(value);
12616
+ }
12617
+ return deduped;
12618
+ }
12619
+ function unionPreserveOrder(current, additional) {
12620
+ return dedupePreserveOrder([...current, ...additional]);
12621
+ }
12622
+ function isRecord2(value) {
12623
+ return typeof value === "object" && value !== null && !Array.isArray(value);
12624
+ }
12625
+ function getDetailType(detail) {
12626
+ if (!isRecord2(detail) || typeof detail.type !== "string") {
12627
+ return void 0;
12628
+ }
12629
+ return detail.type;
12630
+ }
12631
+ function getStringArray(value) {
12632
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
12633
+ return null;
12634
+ }
12635
+ return value;
12636
+ }
12637
+ function scopeTokens(scope, fallbackToDefault) {
12638
+ const tokens = (scope ?? "").trim().split(/[\s,]+/).filter(Boolean);
12639
+ if (tokens.length > 0) {
12640
+ return tokens;
12641
+ }
12642
+ return fallbackToDefault ? [...DEFAULT_SCOPE_TOKENS] : [];
12643
+ }
12644
+ function grantedActions(detail) {
12645
+ if (!isRecord2(detail)) {
12646
+ return null;
12647
+ }
12648
+ const actions = getStringArray(detail.actions);
12649
+ return actions ? dedupePreserveOrder(actions) : null;
12650
+ }
12651
+ function computeMergedAccess({
12652
+ requestedScope,
12653
+ requestedAuthorizationDetails,
12654
+ existingScope,
12655
+ existingAuthorizationDetails
12656
+ }) {
12657
+ const requestedTokens = scopeTokens(requestedScope, true);
12658
+ const existingTokens = scopeTokens(existingScope, true);
12659
+ const missingScopes = existingTokens.filter(
12660
+ (token) => !requestedTokens.includes(token)
12661
+ );
12662
+ const mergedScope = unionPreserveOrder(requestedTokens, missingScopes).join(
12663
+ " "
12664
+ );
12665
+ const actionsByType = /* @__PURE__ */ new Map();
12666
+ const seenOpaque = /* @__PURE__ */ new Set();
12667
+ const layout = [];
12668
+ const absorb = (details) => {
12669
+ for (const detail of details) {
12670
+ const type = getDetailType(detail);
12671
+ const actions = grantedActions(detail);
12672
+ if (type && actions) {
12673
+ if (!actionsByType.has(type)) {
12674
+ layout.push({ kind: "actions", type });
12675
+ }
12676
+ actionsByType.set(
12677
+ type,
12678
+ unionPreserveOrder(actionsByType.get(type) ?? [], actions)
12679
+ );
12680
+ } else {
12681
+ const key = JSON.stringify(detail);
12682
+ if (!seenOpaque.has(key)) {
12683
+ seenOpaque.add(key);
12684
+ layout.push({ kind: "opaque", detail });
12685
+ }
12686
+ }
12687
+ }
12688
+ };
12689
+ absorb(requestedAuthorizationDetails ?? []);
12690
+ absorb(existingAuthorizationDetails ?? []);
12691
+ const mergedAuthorizationDetails = layout.map(
12692
+ (entry) => entry.kind === "actions" ? { type: entry.type, actions: actionsByType.get(entry.type) ?? [] } : entry.detail
12693
+ );
12694
+ return { mergedScope, mergedAuthorizationDetails };
12695
+ }
12696
+
12283
12697
  // src/utils/poll-until.ts
12284
12698
  async function* pollUntil(options) {
12285
12699
  const { fn, isTerminal, interval, timeout, maxAttempts } = options;
@@ -12364,6 +12778,8 @@ import { useEffect, useState } from "react";
12364
12778
 
12365
12779
  // src/utils/constants.ts
12366
12780
  var DISPLAY_DELAY_MS = 1500;
12781
+ var RESUME_POLL_INTERVAL_MS = 2e3;
12782
+ var RESUME_TIMEOUT_MS = 6e5;
12367
12783
 
12368
12784
  // src/utils/open-url.ts
12369
12785
  import { spawn } from "child_process";
@@ -12400,6 +12816,7 @@ var Login = ({
12400
12816
  sourceActions,
12401
12817
  authorizationDetails,
12402
12818
  authStorage: authStorage2 = storage,
12819
+ revokeRefreshTokenOnSuccess,
12403
12820
  onComplete
12404
12821
  }) => {
12405
12822
  const storage2 = authStorage2;
@@ -12446,6 +12863,10 @@ var Login = ({
12446
12863
  if (tokens) {
12447
12864
  clearInterval(pollInterval);
12448
12865
  storage2.setAuth(tokens);
12866
+ if (revokeRefreshTokenOnSuccess) {
12867
+ authResource.revokeToken(revokeRefreshTokenOnSuccess).catch(() => {
12868
+ });
12869
+ }
12449
12870
  setStatus("success");
12450
12871
  setTimeout(onComplete, DISPLAY_DELAY_MS);
12451
12872
  }
@@ -12464,7 +12885,14 @@ var Login = ({
12464
12885
  };
12465
12886
  const timeout = setTimeout(startPolling, 1e3);
12466
12887
  return () => clearTimeout(timeout);
12467
- }, [status, deviceCode, authResource, onComplete, storage2]);
12888
+ }, [
12889
+ status,
12890
+ deviceCode,
12891
+ authResource,
12892
+ onComplete,
12893
+ storage2,
12894
+ revokeRefreshTokenOnSuccess
12895
+ ]);
12468
12896
  if (status === "initiating") {
12469
12897
  return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
12470
12898
  /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
@@ -12559,7 +12987,7 @@ function useAsyncAction(action, onComplete) {
12559
12987
  );
12560
12988
  } catch (err) {
12561
12989
  if (cancelled) return;
12562
- const message = err instanceof Error ? err.message : String(err);
12990
+ const message = err instanceof Error ? err.message : JSON.stringify(err);
12563
12991
  setError(message);
12564
12992
  setStatus("error");
12565
12993
  timeoutId = setTimeout(
@@ -12729,6 +13157,39 @@ async function* pollAuthStatus(authResource, storage2, opts, update) {
12729
13157
  for await (const result of pollUntil({
12730
13158
  fn: async () => {
12731
13159
  const pending = storage2.getPendingDeviceAuth();
13160
+ if (pending?.replaces_existing_session) {
13161
+ const previousRefreshToken = storage2.getAuth()?.refresh_token;
13162
+ const tokens = await authResource.pollDeviceAuth(pending.device_code);
13163
+ if (tokens) {
13164
+ storage2.setAuth(tokens);
13165
+ storage2.clearPendingDeviceAuth();
13166
+ if (previousRefreshToken) {
13167
+ try {
13168
+ await authResource.revokeToken(previousRefreshToken);
13169
+ } catch {
13170
+ }
13171
+ }
13172
+ return {
13173
+ authenticated: true,
13174
+ access_token: `${tokens.access_token.substring(0, 20)}...`,
13175
+ token_type: tokens.token_type,
13176
+ credentials_path: storage2.getPath(),
13177
+ ...tokens.scope && { scope: tokens.scope },
13178
+ ...tokens.authorization_details && {
13179
+ authorization_details: tokens.authorization_details
13180
+ },
13181
+ ...update && { update }
13182
+ };
13183
+ }
13184
+ return {
13185
+ authenticated: false,
13186
+ credentials_path: storage2.getPath(),
13187
+ ...update && { update },
13188
+ pending: true,
13189
+ verification_url: pending.verification_url,
13190
+ phrase: pending.phrase
13191
+ };
13192
+ }
12732
13193
  if (pending && !storage2.isAuthenticated()) {
12733
13194
  const tokens = await authResource.pollDeviceAuth(pending.device_code);
12734
13195
  if (tokens) {
@@ -12781,6 +13242,44 @@ async function maybeRevokeAndClearAuth(authResource, storage2) {
12781
13242
  storage2.clearAuth();
12782
13243
  storage2.clearPendingDeviceAuth();
12783
13244
  }
13245
+ async function* startDeviceAuthAndPoll(authResource, storage2, params, opts, warning) {
13246
+ const authRequest = await authResource.initiateDeviceAuth({
13247
+ clientName: params.clientName,
13248
+ scope: params.scope,
13249
+ sourceActions: params.sourceActions,
13250
+ authorizationDetails: params.authorizationDetails
13251
+ });
13252
+ storage2.setPendingDeviceAuth({
13253
+ device_code: authRequest.device_code,
13254
+ interval: authRequest.interval,
13255
+ expires_at: Date.now() + authRequest.expires_in * 1e3,
13256
+ verification_url: authRequest.verification_url_complete,
13257
+ phrase: authRequest.user_code,
13258
+ ...params.replacesExistingSession ? { replaces_existing_session: true } : {}
13259
+ });
13260
+ const warningField = warning ? { warning } : {};
13261
+ if (opts.interval <= 0) {
13262
+ yield sanitizeDeep({
13263
+ ...warningField,
13264
+ verification_url: authRequest.verification_url_complete,
13265
+ phrase: authRequest.user_code,
13266
+ instruction: "Present the verification_url to the user and ask them to approve in the Link app. Then call `auth status --interval 5 --max-attempts 60` to poll until authenticated. Do not wait for the user to reply \u2014 start polling immediately.",
13267
+ _next: {
13268
+ command: "auth status --interval 5 --max-attempts 60",
13269
+ poll_interval_seconds: authRequest.interval,
13270
+ until: "authenticated is true"
13271
+ }
13272
+ });
13273
+ return;
13274
+ }
13275
+ yield sanitizeDeep({
13276
+ ...warningField,
13277
+ verification_url: authRequest.verification_url_complete,
13278
+ phrase: authRequest.user_code,
13279
+ instruction: "Present the verification_url to the user and ask them to approve in the Link app. Polling has started automatically \u2014 no further action needed."
13280
+ });
13281
+ yield* pollAuthStatus(authResource, storage2, opts);
13282
+ }
12784
13283
  function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToken2) {
12785
13284
  const storage2 = authStorage2 ?? storage;
12786
13285
  const cli2 = Cli.create("auth", {
@@ -12858,43 +13357,116 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
12858
13357
  () => ({ authenticated: true, token_type: "Bearer" })
12859
13358
  );
12860
13359
  }
12861
- const authRequest = await authResource.initiateDeviceAuth({
12862
- clientName,
12863
- scope,
12864
- sourceActions: c.options.sourceActions,
12865
- authorizationDetails
12866
- });
12867
- storage2.setPendingDeviceAuth({
12868
- device_code: authRequest.device_code,
12869
- interval: authRequest.interval,
12870
- expires_at: Date.now() + authRequest.expires_in * 1e3,
12871
- verification_url: authRequest.verification_url_complete,
12872
- phrase: authRequest.user_code
12873
- });
12874
- const interval = c.options.interval;
12875
- if (interval <= 0) {
12876
- yield sanitizeDeep({
12877
- verification_url: authRequest.verification_url_complete,
12878
- phrase: authRequest.user_code,
12879
- instruction: "Present the verification_url to the user and ask them to approve in the Link app. Then call `auth status --interval 5 --max-attempts 60` to poll until authenticated. Do not wait for the user to reply \u2014 start polling immediately.",
12880
- _next: {
12881
- command: "auth status --interval 5 --max-attempts 60",
12882
- poll_interval_seconds: authRequest.interval,
12883
- until: "authenticated is true"
12884
- }
13360
+ yield* startDeviceAuthAndPoll(
13361
+ authResource,
13362
+ storage2,
13363
+ {
13364
+ clientName,
13365
+ scope,
13366
+ sourceActions: c.options.sourceActions,
13367
+ authorizationDetails
13368
+ },
13369
+ {
13370
+ interval: c.options.interval,
13371
+ maxAttempts: c.options.maxAttempts,
13372
+ timeout: c.options.timeout
13373
+ }
13374
+ );
13375
+ }
13376
+ });
13377
+ cli2.command("upgrade", {
13378
+ description: "Re-authenticate with Link, merging the requested access with your current access so the new session is a superset",
13379
+ options: loginOptions,
13380
+ outputPolicy: "agent-only",
13381
+ async *run(c) {
13382
+ const clientName = c.options.clientName?.trim();
13383
+ const requestedScope = normalizeScopeInput(c.options.scope);
13384
+ if (!clientName || clientName.length === 0) {
13385
+ return c.error({
13386
+ code: "INVALID_INPUT",
13387
+ message: "client-name must be a non-empty string"
12885
13388
  });
12886
- return;
12887
13389
  }
12888
- yield sanitizeDeep({
12889
- verification_url: authRequest.verification_url_complete,
12890
- phrase: authRequest.user_code,
12891
- instruction: "Present the verification_url to the user and ask them to approve in the Link app. Polling has started automatically \u2014 no further action needed."
12892
- });
12893
- yield* pollAuthStatus(authResource, storage2, {
12894
- interval,
12895
- maxAttempts: c.options.maxAttempts,
12896
- timeout: c.options.timeout
12897
- });
13390
+ if (c.options.scope !== void 0 && !requestedScope) {
13391
+ return c.error({
13392
+ code: "INVALID_INPUT",
13393
+ message: "scope must be a non-empty string when provided"
13394
+ });
13395
+ }
13396
+ let requestedAuthorizationDetails;
13397
+ try {
13398
+ requestedAuthorizationDetails = buildAuthorizationDetails(
13399
+ c.options.sourceActions,
13400
+ parseAuthorizationDetails(c.options.authorizationDetail)
13401
+ );
13402
+ } catch (error) {
13403
+ return c.error({
13404
+ code: "INVALID_INPUT",
13405
+ message: error.message
13406
+ });
13407
+ }
13408
+ let scope = requestedScope;
13409
+ let authorizationDetails = requestedAuthorizationDetails;
13410
+ let previousRefreshToken;
13411
+ let warning;
13412
+ const existingAuth = storage2.getAuth();
13413
+ if (existingAuth?.refresh_token) {
13414
+ try {
13415
+ const refreshed = await authResource.refreshToken(
13416
+ existingAuth.refresh_token
13417
+ );
13418
+ storage2.setAuth(refreshed);
13419
+ previousRefreshToken = refreshed.refresh_token;
13420
+ const merged = computeMergedAccess({
13421
+ requestedScope,
13422
+ requestedAuthorizationDetails,
13423
+ existingScope: refreshed.scope ?? existingAuth.scope,
13424
+ existingAuthorizationDetails: refreshed.authorization_details ?? existingAuth.authorization_details
13425
+ });
13426
+ scope = merged.mergedScope;
13427
+ authorizationDetails = merged.mergedAuthorizationDetails;
13428
+ } catch {
13429
+ storage2.clearAuth();
13430
+ storage2.clearPendingDeviceAuth();
13431
+ warning = "could not refresh the existing session; continuing with only the requested access.";
13432
+ process.stderr.write(`warning: ${warning}
13433
+ `);
13434
+ }
13435
+ } else {
13436
+ warning = "no active session to upgrade; continuing with only the requested access.";
13437
+ process.stderr.write(`warning: ${warning}
13438
+ `);
13439
+ }
13440
+ const replacesExistingSession = previousRefreshToken !== void 0;
13441
+ if (!c.agent && !c.formatExplicit) {
13442
+ return renderInteractive(
13443
+ /* @__PURE__ */ jsx4(
13444
+ Login,
13445
+ {
13446
+ authResource,
13447
+ clientName,
13448
+ scope,
13449
+ authorizationDetails,
13450
+ authStorage: storage2,
13451
+ revokeRefreshTokenOnSuccess: previousRefreshToken,
13452
+ onComplete: () => {
13453
+ }
13454
+ }
13455
+ ),
13456
+ () => ({ authenticated: true, token_type: "Bearer" })
13457
+ );
13458
+ }
13459
+ yield* startDeviceAuthAndPoll(
13460
+ authResource,
13461
+ storage2,
13462
+ { clientName, scope, authorizationDetails, replacesExistingSession },
13463
+ {
13464
+ interval: c.options.interval,
13465
+ maxAttempts: c.options.maxAttempts,
13466
+ timeout: c.options.timeout
13467
+ },
13468
+ warning
13469
+ );
12898
13470
  }
12899
13471
  });
12900
13472
  cli2.command("logout", {
@@ -13032,6 +13604,8 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
13032
13604
  var COLUMN_GAP = " ";
13033
13605
  var SOURCE_ID_MIN = 16;
13034
13606
  var SOURCE_ID_MAX = 48;
13607
+ var NAME_MIN = 12;
13608
+ var NAME_MAX = 30;
13035
13609
  var TYPE_WIDTH = 12;
13036
13610
  var CURRENT_WIDTH = 15;
13037
13611
  var CURRENCY_WIDTH = 8;
@@ -13057,6 +13631,15 @@ function sourceIdWidth(balances) {
13057
13631
  const maxLen = Math.max(...balances.map((b) => (b.source_id ?? "").length));
13058
13632
  return Math.min(SOURCE_ID_MAX, Math.max(SOURCE_ID_MIN, maxLen));
13059
13633
  }
13634
+ function accountName(balance) {
13635
+ const name = balance.name;
13636
+ return typeof name === "string" && name.length > 0 ? name : "-";
13637
+ }
13638
+ function nameWidth(balances) {
13639
+ if (balances.length === 0) return NAME_MIN;
13640
+ const maxLen = Math.max(...balances.map((b) => accountName(b).length));
13641
+ return Math.min(NAME_MAX, Math.max(NAME_MIN, maxLen));
13642
+ }
13060
13643
  var BalancesList = ({
13061
13644
  resource,
13062
13645
  params,
@@ -13070,7 +13653,9 @@ var BalancesList = ({
13070
13653
  const balances = page?.data ?? [];
13071
13654
  const nextCursor = page?.has_more && balances.length > 0 ? balances[balances.length - 1].source_id : null;
13072
13655
  const idWidth = sourceIdWidth(balances);
13656
+ const accountNameWidth = nameWidth(balances);
13073
13657
  const headerRow = [
13658
+ formatCell("Source name", accountNameWidth),
13074
13659
  formatCell("Source ID", idWidth),
13075
13660
  formatCell("Balance type", TYPE_WIDTH),
13076
13661
  formatCell("Current balance", CURRENT_WIDTH),
@@ -13079,6 +13664,7 @@ var BalancesList = ({
13079
13664
  const separatorRow = "-".repeat(headerRow.length);
13080
13665
  const rows = balances.map(
13081
13666
  (balance) => [
13667
+ formatCell(accountName(balance), accountNameWidth),
13082
13668
  formatCell(balance.source_id ?? "-", idWidth),
13083
13669
  formatCell(balance.type ?? "-", TYPE_WIDTH),
13084
13670
  formatCell(
@@ -13133,7 +13719,7 @@ var listOptions = z2.object({
13133
13719
  import { jsx as jsx6 } from "react/jsx-runtime";
13134
13720
  function createBalancesCli(createResource, authStorage2, envAccessToken2) {
13135
13721
  const cli2 = Cli2.create("balances", {
13136
- description: "List balances from your Link wallet"
13722
+ description: "[beta] List balances from your Link wallet"
13137
13723
  });
13138
13724
  cli2.command("list", {
13139
13725
  description: "List balances from your Link wallet",
@@ -13877,7 +14463,7 @@ function decodeStripeChallenge(challengeHeader) {
13877
14463
  const { challenge, networkId, request } = resolveStripeChallenge(
13878
14464
  Challenge.deserializeList(challengeHeader)
13879
14465
  );
13880
- return {
14466
+ return sanitizeDeep({
13881
14467
  id: challenge.id,
13882
14468
  realm: challenge.realm,
13883
14469
  method: "stripe",
@@ -13887,7 +14473,7 @@ function decodeStripeChallenge(challengeHeader) {
13887
14473
  expires: challenge.expires,
13888
14474
  network_id: networkId,
13889
14475
  request_json: request
13890
- };
14476
+ });
13891
14477
  }
13892
14478
 
13893
14479
  // src/commands/mpp/pay.tsx
@@ -15590,7 +16176,7 @@ function sourceRow(source, index) {
15590
16176
  const external = formatExternalConnection(source);
15591
16177
  return {
15592
16178
  key: sourceId(source, index),
15593
- name: source.name ?? "Source",
16179
+ name: source.name ?? "-",
15594
16180
  type: source.type ?? "-",
15595
16181
  id: sourceId(source, index),
15596
16182
  capabilities,
@@ -15599,7 +16185,7 @@ function sourceRow(source, index) {
15599
16185
  }
15600
16186
  function tableColumns() {
15601
16187
  return [
15602
- { label: "Name", value: (row) => row.name, minWidth: 14, maxWidth: 24 },
16188
+ { label: "Name", value: (row) => row.name, minWidth: 14, maxWidth: 36 },
15603
16189
  { label: "Type", value: (row) => row.type, minWidth: 10, maxWidth: 14 },
15604
16190
  { label: "ID", value: (row) => row.id, minWidth: 16, maxWidth: 48 },
15605
16191
  {
@@ -15713,7 +16299,7 @@ var listOptions2 = z8.object({
15713
16299
  import { jsx as jsx24 } from "react/jsx-runtime";
15714
16300
  function createSourcesCli(createResource, authStorage2, envAccessToken2) {
15715
16301
  const cli2 = Cli10.create("sources", {
15716
- description: "List sources from your Link wallet"
16302
+ description: "[beta] List sources from your Link wallet"
15717
16303
  });
15718
16304
  cli2.command("list", {
15719
16305
  description: "List sources from your Link wallet",
@@ -15907,10 +16493,25 @@ var CancelSpendRequest = ({
15907
16493
  };
15908
16494
 
15909
16495
  // src/commands/spend-request/create.tsx
15910
- import { Box as Box18, Text as Text20, useApp as useApp4 } from "ink";
16496
+ import { Box as Box18, Text as Text20, useApp as useApp4, useInput as useInput8 } from "ink";
15911
16497
  import Spinner10 from "ink-spinner";
15912
16498
  import { useCallback as useCallback8, useEffect as useEffect9, useState as useState9 } from "react";
15913
16499
 
16500
+ // src/utils/format-amount.ts
16501
+ function formatAmount(amount, currency) {
16502
+ const currencyCode = currency.toUpperCase();
16503
+ try {
16504
+ const formatter = new Intl.NumberFormat("en-US", {
16505
+ style: "currency",
16506
+ currency: currencyCode
16507
+ });
16508
+ const fractionDigits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
16509
+ return formatter.format(amount / 10 ** fractionDigits);
16510
+ } catch {
16511
+ return `${amount} ${currency}`;
16512
+ }
16513
+ }
16514
+
15914
16515
  // src/commands/spend-request/approval-waiting-view.tsx
15915
16516
  import { Box as Box17, Text as Text19 } from "ink";
15916
16517
  import Spinner9 from "ink-spinner";
@@ -15955,7 +16556,8 @@ function useApprovalPolling({
15955
16556
  requestId,
15956
16557
  onComplete,
15957
16558
  onSuccess,
15958
- onError
16559
+ onError,
16560
+ onRequiresAction
15959
16561
  }) {
15960
16562
  const isWaiting = status === "waiting" || status === "polling";
15961
16563
  useInput7(
@@ -15976,6 +16578,12 @@ function useApprovalPolling({
15976
16578
  try {
15977
16579
  const final = await pollUntilApproved(repository, requestId);
15978
16580
  if (cancelled) return;
16581
+ if (final.status === "requires_action") {
16582
+ onRequiresAction(final);
16583
+ setStatus("requires_action");
16584
+ setTimeout(() => onComplete(final), DISPLAY_DELAY_MS);
16585
+ return;
16586
+ }
15979
16587
  if (final.status !== "approved") {
15980
16588
  onError(
15981
16589
  `Spend request did not reach approved (status: ${final.status})`
@@ -16005,6 +16613,7 @@ function useApprovalPolling({
16005
16613
  onComplete,
16006
16614
  onSuccess,
16007
16615
  onError,
16616
+ onRequiresAction,
16008
16617
  setStatus
16009
16618
  ]);
16010
16619
  }
@@ -16019,15 +16628,20 @@ var CreateSpendRequest = ({
16019
16628
  force,
16020
16629
  onComplete
16021
16630
  }) => {
16631
+ const { exit } = useApp4();
16022
16632
  const [status, setStatus] = useState9("creating");
16023
16633
  const [request, setRequest] = useState9(null);
16634
+ const [duplicateRequest, setDuplicateRequest] = useState9(
16635
+ null
16636
+ );
16024
16637
  const [error, setError] = useState9("");
16025
16638
  const [verificationUrl, setVerificationUrl] = useState9("");
16026
16639
  const [supportUrl, setSupportUrl] = useState9("");
16640
+ const [countdown, setCountdown] = useState9(30);
16027
16641
  const [outputFilePath, setOutputFilePath] = useState9(null);
16028
16642
  const [fileError, setFileError] = useState9("");
16643
+ const [nextAction, setNextAction] = useState9(null);
16029
16644
  const approvalUrl = request?.approval_url ?? "";
16030
- const { exit } = useApp4();
16031
16645
  const completeAndExit = useCallback8(
16032
16646
  (result) => {
16033
16647
  onComplete(result);
@@ -16040,6 +16654,10 @@ var CreateSpendRequest = ({
16040
16654
  []
16041
16655
  );
16042
16656
  const onError = useCallback8((msg) => setError(msg), []);
16657
+ const onRequiresAction = useCallback8((result) => {
16658
+ setRequest(result);
16659
+ setNextAction(result.status_details?.requires_action?.next_action ?? null);
16660
+ }, []);
16043
16661
  useApprovalPolling({
16044
16662
  status,
16045
16663
  setStatus,
@@ -16048,20 +16666,109 @@ var CreateSpendRequest = ({
16048
16666
  requestId: request?.id ?? null,
16049
16667
  onComplete: completeAndExit,
16050
16668
  onSuccess,
16051
- onError
16669
+ onError,
16670
+ onRequiresAction
16052
16671
  });
16672
+ useInput8(
16673
+ (_input, key) => {
16674
+ if (key.return && nextAction?.action_url) {
16675
+ openUrl(nextAction.action_url);
16676
+ completeAndExit(request);
16677
+ }
16678
+ },
16679
+ {
16680
+ isActive: status === "requires_action" && nextAction?.resolution !== "auto_resume"
16681
+ }
16682
+ );
16053
16683
  useEffect9(() => {
16054
- const create = async () => {
16055
- try {
16056
- const result = await repository.createSpendRequest(params);
16057
- setRequest(result);
16058
- if (requestApproval) {
16059
- setStatus("waiting");
16060
- } else {
16061
- setStatus("success");
16062
- setTimeout(() => completeAndExit(result), DISPLAY_DELAY_MS);
16063
- }
16064
- } catch (err) {
16684
+ if (status !== "requires_action") return;
16685
+ if (nextAction?.resolution === "auto_resume") {
16686
+ setStatus("resuming");
16687
+ }
16688
+ }, [status, nextAction]);
16689
+ useEffect9(() => {
16690
+ if (status !== "resuming" || !request?.id) return;
16691
+ let cancelled = false;
16692
+ const requestId = request.id;
16693
+ const deadline = Date.now() + RESUME_TIMEOUT_MS;
16694
+ const poll = async () => {
16695
+ while (!cancelled) {
16696
+ if (Date.now() > deadline) {
16697
+ setStatus("resume_timeout");
16698
+ setTimeout(() => completeAndExit(request), DISPLAY_DELAY_MS);
16699
+ return;
16700
+ }
16701
+ await new Promise((r) => setTimeout(r, RESUME_POLL_INTERVAL_MS));
16702
+ if (cancelled) return;
16703
+ let latest;
16704
+ try {
16705
+ latest = await repository.getSpendRequest(requestId);
16706
+ } catch {
16707
+ continue;
16708
+ }
16709
+ if (cancelled || !latest) continue;
16710
+ setRequest(latest);
16711
+ if (latest.status === "requires_action") continue;
16712
+ if (latest.status === "approved" || latest.status === "succeeded") {
16713
+ setStatus("success");
16714
+ } else {
16715
+ setError(
16716
+ `Spend request did not resolve after 3D Secure (status: ${latest.status})`
16717
+ );
16718
+ setStatus("error");
16719
+ }
16720
+ setTimeout(() => completeAndExit(latest), DISPLAY_DELAY_MS);
16721
+ return;
16722
+ }
16723
+ };
16724
+ poll();
16725
+ return () => {
16726
+ cancelled = true;
16727
+ };
16728
+ }, [status, request, repository, completeAndExit]);
16729
+ useInput8((_, key) => {
16730
+ if (key.return && (verificationUrl || supportUrl) && status === "verification_required") {
16731
+ openUrl(verificationUrl || supportUrl);
16732
+ setStatus("opened");
16733
+ setTimeout(() => completeAndExit(null), DISPLAY_DELAY_MS);
16734
+ }
16735
+ });
16736
+ useEffect9(() => {
16737
+ if (status !== "verification_required") return;
16738
+ if (countdown <= 0) {
16739
+ completeAndExit(null);
16740
+ return;
16741
+ }
16742
+ const timer = setTimeout(() => setCountdown((c) => c - 1), 1e3);
16743
+ return () => clearTimeout(timer);
16744
+ }, [status, countdown, completeAndExit]);
16745
+ useEffect9(() => {
16746
+ if (status !== "requires_action") return;
16747
+ if (nextAction?.resolution === "auto_resume") return;
16748
+ if (countdown <= 0) {
16749
+ completeAndExit(request);
16750
+ return;
16751
+ }
16752
+ const timer = setTimeout(() => setCountdown((c) => c - 1), 1e3);
16753
+ return () => clearTimeout(timer);
16754
+ }, [status, nextAction, countdown, completeAndExit, request]);
16755
+ useEffect9(() => {
16756
+ const create = async () => {
16757
+ try {
16758
+ const result = await repository.createSpendRequest(params);
16759
+ setRequest(result);
16760
+ if (result.status === "requires_action") {
16761
+ setNextAction(
16762
+ result.status_details?.requires_action?.next_action ?? null
16763
+ );
16764
+ setStatus("requires_action");
16765
+ } else if (requestApproval) {
16766
+ setStatus("waiting");
16767
+ } else {
16768
+ setStatus("success");
16769
+ setTimeout(() => completeAndExit(result), DISPLAY_DELAY_MS);
16770
+ }
16771
+ } catch (err) {
16065
16772
  setError(err.message);
16066
16773
  if (err instanceof LinkApiError) {
16067
16774
  const errDetail = err.details;
@@ -16069,6 +16776,12 @@ var CreateSpendRequest = ({
16069
16776
  setVerificationUrl(errDetail.error.verification_url);
16070
16777
  if (errDetail?.error?.support_url)
16071
16778
  setSupportUrl(errDetail.error.support_url);
16779
+ if (errDetail?.error?.verification_url || errDetail?.error?.support_url) {
16780
+ setStatus("verification_required");
16781
+ return;
16782
+ }
16783
+ const duplicate = getDuplicateSpendRequest(err);
16784
+ if (duplicate) setDuplicateRequest(sanitizeDeep(duplicate));
16072
16785
  }
16073
16786
  setStatus("error");
16074
16787
  setTimeout(() => completeAndExit(null), DISPLAY_DELAY_MS);
@@ -16088,6 +16801,110 @@ var CreateSpendRequest = ({
16088
16801
  };
16089
16802
  writeCredentialFile(outputFile, fileData, force ?? false).then((path7) => setOutputFilePath(path7)).catch((err) => setFileError(err.message));
16090
16803
  }, [status, outputFile, force, request]);
16804
+ if (status === "verification_required") {
16805
+ const url = verificationUrl || supportUrl;
16806
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16807
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: "\u2717 Failed to create spend request" }),
16808
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: error }),
16809
+ /* @__PURE__ */ jsxs18(
16810
+ Box18,
16811
+ {
16812
+ flexDirection: "column",
16813
+ borderStyle: "round",
16814
+ borderColor: "cyan",
16815
+ paddingX: 2,
16816
+ paddingY: 1,
16817
+ marginTop: 1,
16818
+ children: [
16819
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16820
+ "Open:",
16821
+ " ",
16822
+ /* @__PURE__ */ jsx27(Text20, { bold: true, color: "cyan", children: url })
16823
+ ] }),
16824
+ /* @__PURE__ */ jsx27(Text20, { dimColor: true, children: "Press Enter to open in browser" }),
16825
+ /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
16826
+ "Exiting in ",
16827
+ countdown,
16828
+ "s..."
16829
+ ] })
16830
+ ]
16831
+ }
16832
+ )
16833
+ ] });
16834
+ }
16835
+ if (status === "opened") {
16836
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16837
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: "\u2717 Failed to create spend request" }),
16838
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: error }),
16839
+ /* @__PURE__ */ jsx27(Text20, { color: "green", children: "\u2713 Opened verification URL in browser" })
16840
+ ] });
16841
+ }
16842
+ if (status === "requires_action") {
16843
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16844
+ /* @__PURE__ */ jsx27(Text20, { color: "yellow", children: "\u26A0 Action required before payment can proceed" }),
16845
+ /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16846
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16847
+ "ID: ",
16848
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.id })
16849
+ ] }),
16850
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16851
+ "Type: ",
16852
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: nextAction?.type })
16853
+ ] }),
16854
+ /* @__PURE__ */ jsx27(Text20, { children: nextAction?.display_message })
16855
+ ] }),
16856
+ nextAction?.action_url && /* @__PURE__ */ jsxs18(
16857
+ Box18,
16858
+ {
16859
+ flexDirection: "column",
16860
+ borderStyle: "round",
16861
+ borderColor: "cyan",
16862
+ paddingX: 2,
16863
+ paddingY: 1,
16864
+ marginTop: 1,
16865
+ children: [
16866
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16867
+ "Open:",
16868
+ " ",
16869
+ /* @__PURE__ */ jsx27(Text20, { bold: true, color: "cyan", children: nextAction.action_url })
16870
+ ] }),
16871
+ /* @__PURE__ */ jsx27(Text20, { dimColor: true, children: "Press Enter to open in browser" }),
16872
+ /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
16873
+ "Exiting in ",
16874
+ countdown,
16875
+ "s..."
16876
+ ] })
16877
+ ]
16878
+ }
16879
+ ),
16880
+ /* @__PURE__ */ jsx27(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx27(Text20, { dimColor: true, children: "Complete this step, then create a new spend request." }) })
16881
+ ] });
16882
+ }
16883
+ if (status === "resuming") {
16884
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16885
+ /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
16886
+ /* @__PURE__ */ jsx27(Spinner10, { type: "dots" }),
16887
+ " Waiting for 3D Secure verification to complete..."
16888
+ ] }),
16889
+ /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16890
+ /* @__PURE__ */ jsx27(Text20, { children: nextAction?.display_message }),
16891
+ nextAction?.action_url && /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
16892
+ "URL: ",
16893
+ /* @__PURE__ */ jsx27(Text20, { color: "cyan", children: nextAction.action_url })
16894
+ ] })
16895
+ ] })
16896
+ ] });
16897
+ }
16898
+ if (status === "resume_timeout") {
16899
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16900
+ /* @__PURE__ */ jsx27(Text20, { color: "yellow", children: "\u2717 Timed out waiting for 3D Secure verification to resolve" }),
16901
+ /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
16902
+ "Run `spend-request retrieve ",
16903
+ request?.id,
16904
+ "` to check the current status."
16905
+ ] })
16906
+ ] });
16907
+ }
16091
16908
  if (status === "creating") {
16092
16909
  return /* @__PURE__ */ jsx27(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
16093
16910
  /* @__PURE__ */ jsx27(Spinner10, { type: "dots" }),
@@ -16098,14 +16915,52 @@ var CreateSpendRequest = ({
16098
16915
  return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
16099
16916
  /* @__PURE__ */ jsx27(Text20, { color: "red", children: "\u2717 Failed to create spend request" }),
16100
16917
  /* @__PURE__ */ jsx27(Text20, { color: "red", children: error }),
16101
- verificationUrl && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
16102
- "Complete additional verification at: ",
16103
- verificationUrl
16104
- ] }),
16105
- supportUrl && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
16106
- "Identity verification failed. Contact support at: ",
16107
- supportUrl
16108
- ] })
16918
+ duplicateRequest && /* @__PURE__ */ jsxs18(
16919
+ Box18,
16920
+ {
16921
+ flexDirection: "column",
16922
+ borderStyle: "round",
16923
+ borderColor: "yellow",
16924
+ paddingX: 2,
16925
+ paddingY: 1,
16926
+ marginTop: 1,
16927
+ children: [
16928
+ /* @__PURE__ */ jsx27(Text20, { bold: true, color: "yellow", children: "A matching spend request already exists" }),
16929
+ /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, children: [
16930
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16931
+ "ID: ",
16932
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: duplicateRequest.id })
16933
+ ] }),
16934
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16935
+ "Status: ",
16936
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: duplicateRequest.status })
16937
+ ] }),
16938
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16939
+ "Amount:",
16940
+ " ",
16941
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: duplicateRequest.amount != null ? formatAmount(
16942
+ duplicateRequest.amount,
16943
+ duplicateRequest.currency ?? ""
16944
+ ) : "N/A" })
16945
+ ] }),
16946
+ /* @__PURE__ */ jsxs18(Text20, { children: [
16947
+ "Merchant: ",
16948
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: duplicateRequest.merchant_name })
16949
+ ] })
16950
+ ] }),
16951
+ duplicateRequest.status !== "expired" && duplicateRequest.status !== "canceled" && duplicateRequest.status !== "failed" && /* @__PURE__ */ jsxs18(Fragment4, { children: [
16952
+ /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
16953
+ "\n",
16954
+ "Retrieve it to resume instead of creating a new one:"
16955
+ ] }),
16956
+ /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
16957
+ "spend-request retrieve ",
16958
+ duplicateRequest.id
16959
+ ] })
16960
+ ] })
16961
+ ]
16962
+ }
16963
+ )
16109
16964
  ] });
16110
16965
  }
16111
16966
  if (status === "success") {
@@ -16123,7 +16978,7 @@ var CreateSpendRequest = ({
16123
16978
  /* @__PURE__ */ jsxs18(Text20, { children: [
16124
16979
  "Amount:",
16125
16980
  " ",
16126
- /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.amount != null ? `${request.amount} ${request.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
16981
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.amount != null ? formatAmount(request.amount, request.currency ?? "") : "N/A" })
16127
16982
  ] }),
16128
16983
  /* @__PURE__ */ jsxs18(Text20, { children: [
16129
16984
  "Merchant: ",
@@ -16246,7 +17101,7 @@ var SpendRequestList = ({
16246
17101
  return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
16247
17102
  /* @__PURE__ */ jsx28(Text21, { bold: true, children: includeHistory ? "All Spend Requests" : "Active Spend Requests" }),
16248
17103
  /* @__PURE__ */ jsx28(Box19, { flexDirection: "column", marginTop: 1, children: requests.map((sr) => {
16249
- const statusColor = sr.status === "approved" ? "green" : sr.status === "pending_approval" ? "yellow" : "white";
17104
+ const statusColor = sr.status === "approved" ? "green" : sr.status === "pending_approval" || sr.status === "requires_action" ? "yellow" : "white";
16250
17105
  const amount = sr.amount != null ? `$${(sr.amount / 100).toFixed(2)} ${(sr.currency ?? "usd").toUpperCase()}` : "";
16251
17106
  return /* @__PURE__ */ jsx28(Box19, { paddingX: 2, children: /* @__PURE__ */ jsxs19(Text21, { children: [
16252
17107
  /* @__PURE__ */ jsx28(Text21, { dimColor: true, children: sr.id }),
@@ -16260,7 +17115,7 @@ var SpendRequestList = ({
16260
17115
  };
16261
17116
 
16262
17117
  // src/commands/spend-request/request-approval.tsx
16263
- import { Box as Box20, Text as Text22, useApp as useApp6 } from "ink";
17118
+ import { Box as Box20, Text as Text22, useApp as useApp6, useInput as useInput9 } from "ink";
16264
17119
  import Spinner12 from "ink-spinner";
16265
17120
  import { useCallback as useCallback10, useEffect as useEffect10, useState as useState10 } from "react";
16266
17121
  import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
@@ -16269,12 +17124,6 @@ var RequestApproval = ({
16269
17124
  id,
16270
17125
  onComplete
16271
17126
  }) => {
16272
- const [status, setStatus] = useState10("requesting");
16273
- const [approvalUrl, setApprovalUrl] = useState10("");
16274
- const [result, setResult] = useState10(null);
16275
- const [error, setError] = useState10("");
16276
- const [verificationUrl, setVerificationUrl] = useState10("");
16277
- const [supportUrl, setSupportUrl] = useState10("");
16278
17127
  const { exit } = useApp6();
16279
17128
  const completeAndExit = useCallback10(
16280
17129
  (result2) => {
@@ -16283,8 +17132,20 @@ var RequestApproval = ({
16283
17132
  },
16284
17133
  [onComplete, exit]
16285
17134
  );
17135
+ const [status, setStatus] = useState10("requesting");
17136
+ const [approvalUrl, setApprovalUrl] = useState10("");
17137
+ const [result, setResult] = useState10(null);
17138
+ const [error, setError] = useState10("");
17139
+ const [verificationUrl, setVerificationUrl] = useState10("");
17140
+ const [supportUrl, setSupportUrl] = useState10("");
17141
+ const [countdown, setCountdown] = useState10(30);
17142
+ const [nextAction, setNextAction] = useState10(null);
16286
17143
  const onSuccess = useCallback10((r) => setResult(r), []);
16287
17144
  const onError = useCallback10((msg) => setError(msg), []);
17145
+ const onRequiresAction = useCallback10((r) => {
17146
+ setResult(r);
17147
+ setNextAction(r.status_details?.requires_action?.next_action ?? null);
17148
+ }, []);
16288
17149
  useApprovalPolling({
16289
17150
  status,
16290
17151
  setStatus,
@@ -16293,8 +17154,25 @@ var RequestApproval = ({
16293
17154
  requestId: id,
16294
17155
  onComplete: completeAndExit,
16295
17156
  onSuccess,
16296
- onError
17157
+ onError,
17158
+ onRequiresAction
17159
+ });
17160
+ useInput9((_, key) => {
17161
+ if (key.return && (verificationUrl || supportUrl) && status === "verification_required") {
17162
+ openUrl(verificationUrl || supportUrl);
17163
+ setStatus("opened");
17164
+ setTimeout(() => completeAndExit(null), DISPLAY_DELAY_MS);
17165
+ }
16297
17166
  });
17167
+ useEffect10(() => {
17168
+ if (status !== "verification_required") return;
17169
+ if (countdown <= 0) {
17170
+ completeAndExit(null);
17171
+ return;
17172
+ }
17173
+ const timer = setTimeout(() => setCountdown((c) => c - 1), 1e3);
17174
+ return () => clearTimeout(timer);
17175
+ }, [status, countdown, completeAndExit]);
16298
17176
  useEffect10(() => {
16299
17177
  const request = async () => {
16300
17178
  try {
@@ -16309,6 +17187,10 @@ var RequestApproval = ({
16309
17187
  setVerificationUrl(errDetail.error.verification_url);
16310
17188
  if (errDetail?.error?.support_url)
16311
17189
  setSupportUrl(errDetail.error.support_url);
17190
+ if (errDetail?.error?.verification_url || errDetail?.error?.support_url) {
17191
+ setStatus("verification_required");
17192
+ return;
17193
+ }
16312
17194
  }
16313
17195
  setStatus("error");
16314
17196
  setTimeout(() => {
@@ -16318,7 +17200,61 @@ var RequestApproval = ({
16318
17200
  }
16319
17201
  };
16320
17202
  request();
16321
- }, [repository, id, exit, onComplete]);
17203
+ }, [repository, id, onComplete, exit]);
17204
+ if (status === "verification_required") {
17205
+ const url = verificationUrl || supportUrl;
17206
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
17207
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: "\u2717 Failed to request approval" }),
17208
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: error }),
17209
+ /* @__PURE__ */ jsxs20(
17210
+ Box20,
17211
+ {
17212
+ flexDirection: "column",
17213
+ borderStyle: "round",
17214
+ borderColor: "cyan",
17215
+ paddingX: 2,
17216
+ paddingY: 1,
17217
+ marginTop: 1,
17218
+ children: [
17219
+ /* @__PURE__ */ jsxs20(Text22, { children: [
17220
+ "Open:",
17221
+ " ",
17222
+ /* @__PURE__ */ jsx29(Text22, { bold: true, color: "cyan", children: url })
17223
+ ] }),
17224
+ /* @__PURE__ */ jsx29(Text22, { dimColor: true, children: "Press Enter to open in browser" }),
17225
+ /* @__PURE__ */ jsxs20(Text22, { dimColor: true, children: [
17226
+ "Exiting in ",
17227
+ countdown,
17228
+ "s..."
17229
+ ] })
17230
+ ]
17231
+ }
17232
+ )
17233
+ ] });
17234
+ }
17235
+ if (status === "opened") {
17236
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
17237
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: "\u2717 Failed to request approval" }),
17238
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: error }),
17239
+ /* @__PURE__ */ jsx29(Text22, { color: "green", children: "\u2713 Opened verification URL in browser" })
17240
+ ] });
17241
+ }
17242
+ if (status === "requires_action") {
17243
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
17244
+ /* @__PURE__ */ jsx29(Text22, { color: "yellow", children: "\u26A0 Action required before payment can proceed" }),
17245
+ /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
17246
+ /* @__PURE__ */ jsxs20(Text22, { children: [
17247
+ "ID: ",
17248
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.id })
17249
+ ] }),
17250
+ /* @__PURE__ */ jsx29(Text22, { children: nextAction?.display_message }),
17251
+ nextAction?.action_url && /* @__PURE__ */ jsxs20(Text22, { children: [
17252
+ "URL: ",
17253
+ /* @__PURE__ */ jsx29(Text22, { color: "cyan", children: nextAction.action_url })
17254
+ ] })
17255
+ ] })
17256
+ ] });
17257
+ }
16322
17258
  if (status === "requesting") {
16323
17259
  return /* @__PURE__ */ jsx29(Box20, { children: /* @__PURE__ */ jsxs20(Text22, { color: "cyan", children: [
16324
17260
  /* @__PURE__ */ jsx29(Spinner12, { type: "dots" }),
@@ -16328,15 +17264,7 @@ var RequestApproval = ({
16328
17264
  if (status === "error") {
16329
17265
  return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
16330
17266
  /* @__PURE__ */ jsx29(Text22, { color: "red", children: "\u2717 Failed to request approval" }),
16331
- /* @__PURE__ */ jsx29(Text22, { color: "red", children: error }),
16332
- verificationUrl && /* @__PURE__ */ jsxs20(Text22, { color: "red", children: [
16333
- "Complete additional verification at: ",
16334
- verificationUrl
16335
- ] }),
16336
- supportUrl && /* @__PURE__ */ jsxs20(Text22, { color: "red", children: [
16337
- "Identity verification failed. Contact support at: ",
16338
- supportUrl
16339
- ] })
17267
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: error })
16340
17268
  ] });
16341
17269
  }
16342
17270
  if (status === "success") {
@@ -16389,6 +17317,9 @@ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
16389
17317
  "failed",
16390
17318
  "canceled"
16391
17319
  ]);
17320
+ function isAutoResume(request) {
17321
+ return request.status_details?.requires_action?.next_action?.resolution === "auto_resume";
17322
+ }
16392
17323
  var RetrieveSpendRequest = ({
16393
17324
  repository,
16394
17325
  id,
@@ -16444,6 +17375,9 @@ var RetrieveSpendRequest = ({
16444
17375
  } else if (result.status === "denied") {
16445
17376
  setPhase("declined");
16446
17377
  setTimeout(() => onComplete(result), DISPLAY_DELAY_MS);
17378
+ } else if (result.status === "requires_action" && !isAutoResume(result)) {
17379
+ setPhase("requires_action");
17380
+ setTimeout(() => onComplete(result), DISPLAY_DELAY_MS);
16447
17381
  } else if (TERMINAL_STATUSES.has(result.status)) {
16448
17382
  setPhase("finalized");
16449
17383
  setTimeout(() => onComplete(result), DISPLAY_DELAY_MS);
@@ -16489,6 +17423,11 @@ var RetrieveSpendRequest = ({
16489
17423
  if (timerRef.current) clearInterval(timerRef.current);
16490
17424
  setPhase("declined");
16491
17425
  setTimeout(() => onComplete(result), DISPLAY_DELAY_MS);
17426
+ } else if (result.status === "requires_action" && !isAutoResume(result)) {
17427
+ if (pollRef.current) clearInterval(pollRef.current);
17428
+ if (timerRef.current) clearInterval(timerRef.current);
17429
+ setPhase("requires_action");
17430
+ setTimeout(() => onComplete(result), DISPLAY_DELAY_MS);
16492
17431
  } else if (TERMINAL_STATUSES.has(result.status)) {
16493
17432
  if (pollRef.current) clearInterval(pollRef.current);
16494
17433
  if (timerRef.current) clearInterval(timerRef.current);
@@ -16537,14 +17476,24 @@ var RetrieveSpendRequest = ({
16537
17476
  ] });
16538
17477
  }
16539
17478
  if (phase === "polling") {
17479
+ const resumingNextAction = request?.status === "requires_action" ? request.status_details?.requires_action?.next_action : void 0;
16540
17480
  return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16541
17481
  /* @__PURE__ */ jsx30(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
16542
17482
  /* @__PURE__ */ jsx30(Spinner13, { type: "dots" }),
16543
- " Awaiting approval... (",
17483
+ " ",
17484
+ resumingNextAction ? "Waiting for 3D Secure verification to complete..." : "Awaiting approval...",
17485
+ " ",
17486
+ "(",
16544
17487
  elapsed,
16545
17488
  "s elapsed)"
16546
17489
  ] }) }),
16547
- request?.approval_url && /* @__PURE__ */ jsx30(Box21, { marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
17490
+ resumingNextAction ? /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
17491
+ /* @__PURE__ */ jsx30(Text23, { dimColor: true, children: resumingNextAction.display_message }),
17492
+ resumingNextAction.action_url && /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
17493
+ "URL: ",
17494
+ /* @__PURE__ */ jsx30(Text23, { color: "cyan", children: resumingNextAction.action_url })
17495
+ ] })
17496
+ ] }) : request?.approval_url && /* @__PURE__ */ jsx30(Box21, { marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
16548
17497
  "Approval URL: ",
16549
17498
  /* @__PURE__ */ jsx30(Text23, { color: "cyan", children: request.approval_url })
16550
17499
  ] }) })
@@ -16634,6 +17583,28 @@ var RetrieveSpendRequest = ({
16634
17583
  ] })
16635
17584
  ] });
16636
17585
  }
17586
+ if (phase === "requires_action") {
17587
+ const nextAction = request?.status_details?.requires_action?.next_action;
17588
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
17589
+ /* @__PURE__ */ jsx30(Text23, { color: "yellow", children: "\u26A0 Action required before payment can proceed" }),
17590
+ /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
17591
+ /* @__PURE__ */ jsxs21(Text23, { children: [
17592
+ "ID: ",
17593
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
17594
+ ] }),
17595
+ /* @__PURE__ */ jsxs21(Text23, { children: [
17596
+ "Type: ",
17597
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: nextAction?.type })
17598
+ ] }),
17599
+ /* @__PURE__ */ jsx30(Text23, { children: nextAction?.display_message }),
17600
+ nextAction?.action_url && /* @__PURE__ */ jsxs21(Text23, { children: [
17601
+ "URL: ",
17602
+ /* @__PURE__ */ jsx30(Text23, { color: "cyan", children: nextAction.action_url })
17603
+ ] })
17604
+ ] }),
17605
+ /* @__PURE__ */ jsx30(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx30(Text23, { dimColor: true, children: "Complete this step, then create a new spend request." }) })
17606
+ ] });
17607
+ }
16637
17608
  if (phase === "declined") {
16638
17609
  return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16639
17610
  /* @__PURE__ */ jsx30(Text23, { color: "red", children: "\u2717 Spend request declined" }),
@@ -16793,6 +17764,20 @@ var RetrieveSpendRequest = ({
16793
17764
  ] })
16794
17765
  ] })
16795
17766
  ] }),
17767
+ !request?.card && (request?.card_brand || request?.card_last4) && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
17768
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: "Card:" }),
17769
+ /* @__PURE__ */ jsxs21(Text23, { children: [
17770
+ " ",
17771
+ [
17772
+ request?.card_brand,
17773
+ request?.card_last4 && `\xB7\xB7\xB7\xB7${request.card_last4}`
17774
+ ].filter(Boolean).join(" ")
17775
+ ] }),
17776
+ /* @__PURE__ */ jsxs21(Text23, { color: "gray", children: [
17777
+ " ",
17778
+ "Use --include card to expand full card details"
17779
+ ] })
17780
+ ] }),
16796
17781
  request?.card && outputFile && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16797
17782
  outputFilePath && /* @__PURE__ */ jsxs21(Text23, { color: "green", children: [
16798
17783
  "Card credentials written to ",
@@ -16812,18 +17797,24 @@ import { z as z10 } from "incur";
16812
17797
  var createOptions = z10.object({
16813
17798
  paymentMethodId: z10.string().optional().describe("Payment method ID"),
16814
17799
  credentialType: z10.enum(["shared_payment_token", "card"]).default("card").describe(
16815
- '"card" for checkout forms/Stripe Elements; "shared_payment_token" for HTTP 402/machine payment flows'
17800
+ '"card" for checkout forms and Link Pay Token; "shared_payment_token" for HTTP 402/machine payment flows'
16816
17801
  ),
16817
17802
  networkId: z10.string().optional().describe(
16818
17803
  "Network ID (required for shared_payment_token) \u2014 use `link-cli mpp decode` to extract"
16819
17804
  ),
17805
+ executionMethod: z10.enum(["link_pay_token"]).optional().describe(
17806
+ "Use link_pay_token only with merchant_account_id read from the checkout AI-agent steering DOM"
17807
+ ),
17808
+ merchantAccountId: z10.string().optional().describe(
17809
+ "Stripe account ID from data-stripe-merchant-account; required with execution_method link_pay_token"
17810
+ ),
16820
17811
  amount: z10.coerce.number().int().positive().max(5e5).describe("Amount in cents, max 500000 ($5,000.00)"),
16821
17812
  currency: z10.string().length(3).default("usd").describe("Currency code"),
16822
17813
  merchantName: z10.string().optional().describe(
16823
- "Merchant name (required for card; forbidden for shared_payment_token)"
17814
+ "Merchant name (required for regular card requests; omit for link_pay_token and shared_payment_token)"
16824
17815
  ),
16825
17816
  merchantUrl: z10.string().optional().describe(
16826
- "Merchant URL (required for card; forbidden for shared_payment_token)"
17817
+ "Merchant URL (required for regular card requests; omit for link_pay_token and shared_payment_token)"
16827
17818
  ),
16828
17819
  context: z10.string().min(100).describe(
16829
17820
  "Min 100 chars \u2014 describe the purchase and rationale; the user reads this when approving"
@@ -16834,7 +17825,9 @@ var createOptions = z10.object({
16834
17825
  total: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
16835
17826
  'Total (repeatable, key:value format). Keys: type (required; one of: subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). Example: "type:total,display_text:Total,amount:5000"'
16836
17827
  ),
16837
- requestApproval: z10.boolean().default(true).describe("Request approval and poll until approved/denied/expired"),
17828
+ requestApproval: z10.boolean().default(true).describe(
17829
+ "Request approval and poll until approved/denied/expired, or until requires_action with a non-auto_resume resolution"
17830
+ ),
16838
17831
  test: z10.boolean().default(false).describe(
16839
17832
  "Use test mode (creates testmode credentials from test card data)"
16840
17833
  ),
@@ -16948,6 +17941,18 @@ var UpdateSpendRequest = ({
16948
17941
 
16949
17942
  // src/commands/spend-request/index.tsx
16950
17943
  import { jsx as jsx32 } from "react/jsx-runtime";
17944
+ function buildRequiresActionResult(request) {
17945
+ const nextAction = request.status_details?.requires_action?.next_action;
17946
+ const isAutoResume2 = nextAction?.resolution === "auto_resume";
17947
+ return {
17948
+ ...request,
17949
+ instruction: isAutoResume2 ? `The spend request requires 3D Secure verification. Present action_url (${nextAction?.action_url}) to the user, then call \`spend-request retrieve ${request.id} --interval 2 --max-attempts 300\` to poll until it resolves. Do not create a new spend request \u2014 this one resumes automatically once the challenge is completed.` : `The spend request requires action (${nextAction?.type}): ${nextAction?.display_message}${nextAction?.action_url ? ` URL: ${nextAction.action_url}` : ""} Have the user complete this, then create a new spend request.`,
17950
+ _next: isAutoResume2 ? {
17951
+ command: `spend-request retrieve ${request.id} --interval 2 --max-attempts 300`,
17952
+ until: "status changes from requires_action"
17953
+ } : void 0
17954
+ };
17955
+ }
16951
17956
  async function applyOutputFile(request, outputFile, force) {
16952
17957
  if (!outputFile || !request.card) return request;
16953
17958
  const fileData = {
@@ -17004,6 +18009,53 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17004
18009
  const requestApproval = !!opts.requestApproval;
17005
18010
  const credentialType = opts.credentialType;
17006
18011
  const networkId = opts.networkId;
18012
+ const executionMethod = opts.executionMethod;
18013
+ const merchantAccountId = opts.merchantAccountId?.trim();
18014
+ const lptExecutionRequested = executionMethod !== void 0 || merchantAccountId !== void 0;
18015
+ if (lptExecutionRequested) {
18016
+ if (executionMethod !== "link_pay_token") {
18017
+ return c.error({
18018
+ code: "INVALID_INPUT",
18019
+ message: "execution-method link_pay_token is required when merchant-account-id is provided"
18020
+ });
18021
+ }
18022
+ if (!merchantAccountId) {
18023
+ return c.error({
18024
+ code: "INVALID_INPUT",
18025
+ message: "merchant-account-id is required when execution-method is link_pay_token"
18026
+ });
18027
+ }
18028
+ if (credentialType !== "card") {
18029
+ return c.error({
18030
+ code: "INVALID_INPUT",
18031
+ message: "credential-type must be card when execution-method is link_pay_token"
18032
+ });
18033
+ }
18034
+ if (networkId) {
18035
+ return c.error({
18036
+ code: "INVALID_INPUT",
18037
+ message: "network-id cannot be used when execution-method is link_pay_token"
18038
+ });
18039
+ }
18040
+ if (opts.test) {
18041
+ return c.error({
18042
+ code: "INVALID_INPUT",
18043
+ message: "test cannot be used when execution-method is link_pay_token"
18044
+ });
18045
+ }
18046
+ if (opts.approve) {
18047
+ return c.error({
18048
+ code: "INVALID_INPUT",
18049
+ message: "approve cannot be used when execution-method is link_pay_token; use request-approval instead"
18050
+ });
18051
+ }
18052
+ if (opts.merchantName || opts.merchantUrl) {
18053
+ return c.error({
18054
+ code: "INVALID_INPUT",
18055
+ message: "merchant-name and merchant-url cannot be used when execution-method is link_pay_token; Link resolves the merchant identity from merchant-account-id"
18056
+ });
18057
+ }
18058
+ }
17007
18059
  if (credentialType === "shared_payment_token" && !networkId) {
17008
18060
  return c.error({
17009
18061
  code: "INVALID_INPUT",
@@ -17024,13 +18076,13 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17024
18076
  message: "network-id can only be used when credential-type is shared_payment_token"
17025
18077
  });
17026
18078
  }
17027
- if (credentialType !== "shared_payment_token" && !opts.merchantName) {
18079
+ if (!lptExecutionRequested && credentialType !== "shared_payment_token" && !opts.merchantName) {
17028
18080
  return c.error({
17029
18081
  code: "INVALID_INPUT",
17030
18082
  message: "merchant-name is required when credential-type is card"
17031
18083
  });
17032
18084
  }
17033
- if (credentialType !== "shared_payment_token" && !opts.merchantUrl) {
18085
+ if (!lptExecutionRequested && credentialType !== "shared_payment_token" && !opts.merchantUrl) {
17034
18086
  return c.error({
17035
18087
  code: "INVALID_INPUT",
17036
18088
  message: "merchant-url is required when credential-type is card"
@@ -17057,6 +18109,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17057
18109
  payment_details: opts.paymentMethodId,
17058
18110
  credential_type: credentialType,
17059
18111
  network_id: networkId,
18112
+ execution_method: executionMethod,
18113
+ merchant_account_id: merchantAccountId,
17060
18114
  amount: opts.amount,
17061
18115
  currency: opts.currency,
17062
18116
  merchant_name: opts.merchantName,
@@ -17114,9 +18168,29 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17114
18168
  message: `${err.message} Support URL: ${apiErr.error.support_url}`
17115
18169
  });
17116
18170
  }
18171
+ const duplicate = getDuplicateSpendRequest(err);
18172
+ if (duplicate) {
18173
+ return c.error({
18174
+ code: apiErr?.error?.code ?? "spend_request_rate_limited",
18175
+ message: `${err.message} A matching spend request already exists: ${duplicate.id} (status: ${duplicate.status}). Retrieve it to resume instead of creating a new one.`,
18176
+ cta: {
18177
+ description: "Retrieve the conflicting spend request to inspect its status and resume it if valid.",
18178
+ commands: [
18179
+ {
18180
+ command: `spend-request retrieve ${duplicate.id}`,
18181
+ description: "Retrieve the conflicting spend request to resume it"
18182
+ }
18183
+ ]
18184
+ }
18185
+ });
18186
+ }
17117
18187
  }
17118
18188
  throw err;
17119
18189
  }
18190
+ if (created.status === "requires_action") {
18191
+ yield buildRequiresActionResult(created);
18192
+ return;
18193
+ }
17120
18194
  if (!requestApproval) {
17121
18195
  try {
17122
18196
  yield await applyOutputFile(created, outputFile, forceOverwrite);
@@ -17302,9 +18376,16 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17302
18376
  "failed",
17303
18377
  "canceled"
17304
18378
  ]);
18379
+ const isPollTerminal = (req) => {
18380
+ if (terminalStatuses.has(req.status)) return true;
18381
+ if (req.status === "requires_action") {
18382
+ return req.status_details?.requires_action?.next_action?.resolution !== "auto_resume";
18383
+ }
18384
+ return false;
18385
+ };
17305
18386
  for await (const result of pollUntil({
17306
18387
  fn: () => repository.getSpendRequest(id, { include }),
17307
- isTerminal: (req) => req === null || terminalStatuses.has(req.status),
18388
+ isTerminal: (req) => req === null || isPollTerminal(req),
17308
18389
  interval,
17309
18390
  maxAttempts,
17310
18391
  timeout
@@ -17316,6 +18397,10 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
17316
18397
  });
17317
18398
  }
17318
18399
  if (result.terminal) {
18400
+ if (result.value.status === "requires_action" && !result.reason) {
18401
+ yield buildRequiresActionResult(result.value);
18402
+ return;
18403
+ }
17319
18404
  if (terminalStatuses.has(result.value.status) || !result.reason) {
17320
18405
  try {
17321
18406
  yield await applyOutputFile(
@@ -17393,19 +18478,6 @@ var STATUS_WIDTH = 10;
17393
18478
  var CATEGORY_WIDTH = 16;
17394
18479
  var MIN_DESCRIPTION_WIDTH = 16;
17395
18480
  var HORIZONTAL_PADDING2 = 4;
17396
- function formatAmount(amount, currency) {
17397
- const currencyCode = currency.toUpperCase();
17398
- try {
17399
- const formatter = new Intl.NumberFormat("en-US", {
17400
- style: "currency",
17401
- currency: currencyCode
17402
- });
17403
- const fractionDigits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
17404
- return formatter.format(amount / 10 ** fractionDigits);
17405
- } catch {
17406
- return `${amount} ${currency}`;
17407
- }
17408
- }
17409
18481
  function truncateCell3(value, width) {
17410
18482
  if (value.length <= width) {
17411
18483
  return value;
@@ -17503,7 +18575,7 @@ var listOptions4 = z12.object({
17503
18575
  import { jsx as jsx34 } from "react/jsx-runtime";
17504
18576
  function createTransactionsCli(createResource, authStorage2, envAccessToken2) {
17505
18577
  const cli2 = Cli12.create("transactions", {
17506
- description: "List transactions from Link and external accounts"
18578
+ description: "[beta] List transactions from Link and external accounts"
17507
18579
  });
17508
18580
  cli2.command("list", {
17509
18581
  description: "List transactions from Link and external accounts, including non-Link activity",
@@ -17654,9 +18726,22 @@ function requireFetchImplementation2(config) {
17654
18726
 
17655
18727
  // src/auth/auth-resource.ts
17656
18728
  var CLIENT_ID = "lwlpk_U7Qy7ThG69STZk";
18729
+ function extractOAuthErrorMessage(err) {
18730
+ if (!err) return void 0;
18731
+ if (err.error_description != null) return err.error_description;
18732
+ if (typeof err.error === "string") return err.error;
18733
+ if (typeof err.error === "object" && err.error !== null) {
18734
+ return err.error.message ?? JSON.stringify(err.error);
18735
+ }
18736
+ return void 0;
18737
+ }
18738
+ function extractOAuthErrorCode(err) {
18739
+ if (!err) return void 0;
18740
+ return typeof err.error === "string" ? err.error : void 0;
18741
+ }
17657
18742
  function formatOAuthError(prefix, status, data, rawBody) {
17658
18743
  const err = data;
17659
- return `${prefix} (${status}): ${err?.error_description ?? err?.error ?? (rawBody || "unknown error")}`;
18744
+ return `${prefix} (${status}): ${extractOAuthErrorMessage(err) ?? (rawBody || "unknown error")}`;
17660
18745
  }
17661
18746
  function appendAuthorizationDetailValue(params, key, value) {
17662
18747
  if (Array.isArray(value)) {
@@ -17799,19 +18884,24 @@ ${serializeRedactedFormBody(params)}`
17799
18884
  }
17800
18885
  if (status === 400) {
17801
18886
  const err = data;
17802
- switch (err.error) {
18887
+ switch (extractOAuthErrorCode(err)) {
17803
18888
  case "authorization_pending":
17804
18889
  case "slow_down":
17805
18890
  return null;
17806
18891
  case "expired_token":
17807
18892
  throw new LinkApiError(
17808
18893
  "Device code expired. Please restart the login flow.",
17809
- { status, code: err.error, rawBody, details: data }
18894
+ {
18895
+ status,
18896
+ code: extractOAuthErrorCode(err),
18897
+ rawBody,
18898
+ details: data
18899
+ }
17810
18900
  );
17811
18901
  case "access_denied":
17812
18902
  throw new LinkApiError("Authorization denied by user.", {
17813
18903
  status,
17814
- code: err.error,
18904
+ code: extractOAuthErrorCode(err),
17815
18905
  rawBody,
17816
18906
  details: data
17817
18907
  });
@@ -17823,7 +18913,7 @@ ${serializeRedactedFormBody(params)}`
17823
18913
  formatOAuthError("Token poll failed", status, data, rawBody),
17824
18914
  {
17825
18915
  status,
17826
- code: data?.error,
18916
+ code: extractOAuthErrorCode(data),
17827
18917
  rawBody,
17828
18918
  details: data
17829
18919
  }
@@ -17842,7 +18932,7 @@ ${serializeRedactedFormBody(params)}`
17842
18932
  formatOAuthError("Token revocation failed", status, data, rawBody),
17843
18933
  {
17844
18934
  status,
17845
- code: data?.error,
18935
+ code: extractOAuthErrorCode(data),
17846
18936
  rawBody,
17847
18937
  details: data
17848
18938
  }
@@ -17863,7 +18953,7 @@ ${serializeRedactedFormBody(params)}`
17863
18953
  formatOAuthError("Token refresh failed", status, data, rawBody),
17864
18954
  {
17865
18955
  status,
17866
- code: data?.error,
18956
+ code: extractOAuthErrorCode(data),
17867
18957
  rawBody,
17868
18958
  details: data
17869
18959
  }
@@ -18199,7 +19289,7 @@ function cacheUpdateInfo(value, ttlMs = UPDATE_CACHE_TTL_MS) {
18199
19289
  }
18200
19290
 
18201
19291
  // src/cli.tsx
18202
- var cliVersion = "0.11.0";
19292
+ var cliVersion = "0.13.0";
18203
19293
  var cliName = "@stripe/link-cli";
18204
19294
  var defaultHeaders = {
18205
19295
  "User-Agent": `link-cli/${cliVersion}`
@@ -18228,26 +19318,12 @@ var factory = new ResourceFactory({
18228
19318
  });
18229
19319
  var authRepo = factory.createAuthResource();
18230
19320
  var spendRequestRepo = factory.createSpendRequestResource();
18231
- var requestedCommand = process.argv[2];
18232
- var hiddenCli = requestedCommand === "transactions" ? createTransactionsCli(
18233
- () => factory.createTransactionsResource(),
18234
- authStorage,
18235
- envAccessToken
18236
- ) : requestedCommand === "sources" ? createSourcesCli(
18237
- () => factory.createSourcesResource(),
18238
- authStorage,
18239
- envAccessToken
18240
- ) : requestedCommand === "balances" ? createBalancesCli(
18241
- () => factory.createBalancesResource(),
18242
- authStorage,
18243
- envAccessToken
18244
- ) : null;
18245
- if (hiddenCli) {
18246
- process.argv.splice(2, 1);
18247
- }
18248
- var cli = hiddenCli ?? Cli14.create("link-cli", {
19321
+ var cli = Cli14.create("link-cli", {
18249
19322
  description: "Create a secure, one-time payment credential from a Link wallet to let agents complete purchases on behalf of users.",
18250
- version: cliVersion
19323
+ version: cliVersion,
19324
+ sync: {
19325
+ include: ["skills/*"]
19326
+ }
18251
19327
  });
18252
19328
  var isAgent = process.argv.includes("--format") || process.argv.includes("--mcp");
18253
19329
  var agentUpdateInfoProvider = createAgentUpdateInfoProvider(
@@ -18262,67 +19338,86 @@ if (!isAgent && process.stdout.isTTY) {
18262
19338
  process.stderr.write(renderInteractiveUpdateNotice(updateInfo));
18263
19339
  }
18264
19340
  }
18265
- if (!hiddenCli) {
18266
- cli.command(
18267
- createAuthCli(authRepo, getUpdateInfo, authStorage, envAccessToken)
18268
- );
18269
- cli.command(
18270
- createSpendRequestCli(spendRequestRepo, authStorage, envAccessToken)
18271
- );
18272
- cli.command(
18273
- createPaymentMethodsCli(
18274
- () => factory.createPaymentMethodsResource(),
18275
- authStorage,
18276
- envAccessToken
18277
- )
18278
- );
18279
- cli.command(
18280
- createShippingAddressCli(
18281
- () => factory.createShippingAddressResource(),
18282
- authStorage,
18283
- envAccessToken
18284
- )
18285
- );
18286
- cli.command(
18287
- createUserInfoCli(
18288
- () => factory.createUserInfoResource(),
18289
- authStorage,
18290
- envAccessToken
18291
- )
18292
- );
18293
- cli.command(
18294
- createMppCli(
18295
- spendRequestRepo,
18296
- () => factory.createPaymentMethodsResource(),
18297
- authStorage,
18298
- envAccessToken
18299
- )
18300
- );
18301
- cli.command(
18302
- createReportCli(
18303
- () => factory.createReportResource(),
18304
- authStorage,
18305
- envAccessToken
18306
- )
18307
- );
18308
- cli.command(
18309
- createDemoCli(
18310
- authRepo,
18311
- spendRequestRepo,
18312
- () => factory.createPaymentMethodsResource(),
18313
- authStorage
18314
- )
18315
- );
18316
- cli.command(
18317
- createOnboardCli(
18318
- authRepo,
18319
- spendRequestRepo,
18320
- () => factory.createPaymentMethodsResource(),
18321
- authStorage
18322
- )
18323
- );
18324
- cli.command(createServeCli(cli));
18325
- }
19341
+ cli.command(
19342
+ createAuthCli(authRepo, getUpdateInfo, authStorage, envAccessToken)
19343
+ );
19344
+ cli.command(
19345
+ createSpendRequestCli(spendRequestRepo, authStorage, envAccessToken)
19346
+ );
19347
+ cli.command(
19348
+ createPaymentMethodsCli(
19349
+ () => factory.createPaymentMethodsResource(),
19350
+ authStorage,
19351
+ envAccessToken
19352
+ )
19353
+ );
19354
+ cli.command(
19355
+ createShippingAddressCli(
19356
+ () => factory.createShippingAddressResource(),
19357
+ authStorage,
19358
+ envAccessToken
19359
+ )
19360
+ );
19361
+ cli.command(
19362
+ createUserInfoCli(
19363
+ () => factory.createUserInfoResource(),
19364
+ authStorage,
19365
+ envAccessToken
19366
+ )
19367
+ );
19368
+ cli.command(
19369
+ createMppCli(
19370
+ spendRequestRepo,
19371
+ () => factory.createPaymentMethodsResource(),
19372
+ authStorage,
19373
+ envAccessToken
19374
+ )
19375
+ );
19376
+ cli.command(
19377
+ createReportCli(
19378
+ () => factory.createReportResource(),
19379
+ authStorage,
19380
+ envAccessToken
19381
+ )
19382
+ );
19383
+ cli.command(
19384
+ createBalancesCli(
19385
+ () => factory.createBalancesResource(),
19386
+ authStorage,
19387
+ envAccessToken
19388
+ )
19389
+ );
19390
+ cli.command(
19391
+ createSourcesCli(
19392
+ () => factory.createSourcesResource(),
19393
+ authStorage,
19394
+ envAccessToken
19395
+ )
19396
+ );
19397
+ cli.command(
19398
+ createTransactionsCli(
19399
+ () => factory.createTransactionsResource(),
19400
+ authStorage,
19401
+ envAccessToken
19402
+ )
19403
+ );
19404
+ cli.command(
19405
+ createDemoCli(
19406
+ authRepo,
19407
+ spendRequestRepo,
19408
+ () => factory.createPaymentMethodsResource(),
19409
+ authStorage
19410
+ )
19411
+ );
19412
+ cli.command(
19413
+ createOnboardCli(
19414
+ authRepo,
19415
+ spendRequestRepo,
19416
+ () => factory.createPaymentMethodsResource(),
19417
+ authStorage
19418
+ )
19419
+ );
19420
+ cli.command(createServeCli(cli));
18326
19421
  cli.serve();
18327
19422
  var cli_default = cli;
18328
19423
  export {