@stripe/link-cli 0.3.1 → 0.4.1

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 +8 -0
  2. package/dist/cli.js +66 -49
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -84,6 +84,14 @@ link-cli spend-request retrieve lsrq_001 --format json
84
84
  ```
85
85
  By default, retrieving a spend request will not include card details. Use the `--include=card` to see unmasked card details.
86
86
 
87
+ For agent polling, pass `--interval` and optionally `--max-attempts`:
88
+
89
+ ```bash
90
+ link-cli spend-request retrieve lsrq_001 --interval 2 --max-attempts 150 --format json
91
+ ```
92
+
93
+ Polling exits successfully only after the request reaches a terminal status such as `approved`, `denied`, or `expired`. If polling reaches `--timeout` or exhausts `--max-attempts` while the request is still non-terminal, the command exits non-zero with `code: "POLLING_TIMEOUT"` so callers do not treat a still-pending request as complete.
94
+
87
95
  If the merchant supports MPP, use `link-cli mpp pay` instead:
88
96
 
89
97
  ```bash
package/dist/cli.js CHANGED
@@ -13688,7 +13688,7 @@ function useApprovalPolling({
13688
13688
  if (!cancelled) {
13689
13689
  onSuccess(final);
13690
13690
  setStatus("success");
13691
- setTimeout(onComplete, 1e3);
13691
+ setTimeout(() => onComplete(final), 1e3);
13692
13692
  }
13693
13693
  } catch (err) {
13694
13694
  if (!cancelled) {
@@ -13748,12 +13748,12 @@ var CreateSpendRequest = ({
13748
13748
  setStatus("waiting");
13749
13749
  } else {
13750
13750
  setStatus("success");
13751
- setTimeout(onComplete, 1500);
13751
+ setTimeout(() => onComplete(result), 1500);
13752
13752
  }
13753
13753
  } catch (err) {
13754
13754
  setError(err.message);
13755
13755
  setStatus("error");
13756
- setTimeout(onComplete, 1500);
13756
+ setTimeout(() => onComplete(null), 1500);
13757
13757
  }
13758
13758
  };
13759
13759
  create();
@@ -13785,10 +13785,7 @@ var CreateSpendRequest = ({
13785
13785
  /* @__PURE__ */ jsxs13(Text15, { children: [
13786
13786
  "Amount:",
13787
13787
  " ",
13788
- /* @__PURE__ */ jsx20(Text15, { bold: true, children: (() => {
13789
- const t = request?.totals.find((t2) => t2.type === "total");
13790
- return t ? String(t.amount) : "N/A";
13791
- })() })
13788
+ /* @__PURE__ */ jsx20(Text15, { bold: true, children: request?.amount != null ? `${request.amount} ${request.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
13792
13789
  ] }),
13793
13790
  /* @__PURE__ */ jsxs13(Text15, { children: [
13794
13791
  "Merchant: ",
@@ -13798,6 +13795,10 @@ var CreateSpendRequest = ({
13798
13795
  "Line Items:",
13799
13796
  " ",
13800
13797
  /* @__PURE__ */ jsx20(Text15, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") || "N/A" })
13798
+ ] }),
13799
+ request?.credential_type === "shared_payment_token" && request.shared_payment_token && /* @__PURE__ */ jsxs13(Text15, { children: [
13800
+ "Token: ",
13801
+ /* @__PURE__ */ jsx20(Text15, { bold: true, children: request.shared_payment_token.id })
13801
13802
  ] })
13802
13803
  ] }),
13803
13804
  /* @__PURE__ */ jsx20(AppDownloadQrCodes, {})
@@ -13885,14 +13886,15 @@ var RequestApproval = ({
13885
13886
  /* @__PURE__ */ jsxs14(Text16, { children: [
13886
13887
  "Amount:",
13887
13888
  " ",
13888
- /* @__PURE__ */ jsx21(Text16, { bold: true, children: (() => {
13889
- const t = result?.totals.find((t2) => t2.type === "total");
13890
- return t ? String(t.amount) : "N/A";
13891
- })() })
13889
+ /* @__PURE__ */ jsx21(Text16, { bold: true, children: result?.amount != null ? `${result.amount} ${result.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
13892
13890
  ] }),
13893
13891
  /* @__PURE__ */ jsxs14(Text16, { children: [
13894
13892
  "Merchant: ",
13895
13893
  /* @__PURE__ */ jsx21(Text16, { bold: true, children: result?.merchant_name })
13894
+ ] }),
13895
+ result?.credential_type === "shared_payment_token" && result.shared_payment_token && /* @__PURE__ */ jsxs14(Text16, { children: [
13896
+ "Token: ",
13897
+ /* @__PURE__ */ jsx21(Text16, { bold: true, children: result.shared_payment_token.id })
13896
13898
  ] })
13897
13899
  ] })
13898
13900
  ] });
@@ -13925,6 +13927,7 @@ var RetrieveSpendRequest = ({
13925
13927
  const startTimeRef = useRef4(Date.now());
13926
13928
  const pollRef = useRef4(null);
13927
13929
  const timerRef = useRef4(null);
13930
+ const requestRef = useRef4(null);
13928
13931
  useEffect12(() => {
13929
13932
  return () => {
13930
13933
  if (pollRef.current) clearInterval(pollRef.current);
@@ -13938,16 +13941,17 @@ var RetrieveSpendRequest = ({
13938
13941
  if (!result) {
13939
13942
  setError(`Spend request ${id} not found`);
13940
13943
  setPhase("error");
13941
- setTimeout(onComplete, 1500);
13944
+ setTimeout(() => onComplete(null), 1500);
13942
13945
  return;
13943
13946
  }
13947
+ requestRef.current = result;
13944
13948
  setRequest(result);
13945
13949
  if (result.status === "approved") {
13946
13950
  setPhase("success");
13947
- setTimeout(onComplete, 1500);
13951
+ setTimeout(() => onComplete(result), 1500);
13948
13952
  } else if (result.status === "denied") {
13949
13953
  setPhase("declined");
13950
- setTimeout(onComplete, 1500);
13954
+ setTimeout(() => onComplete(result), 1500);
13951
13955
  } else {
13952
13956
  startTimeRef.current = Date.now();
13953
13957
  setPhase("polling");
@@ -13955,7 +13959,7 @@ var RetrieveSpendRequest = ({
13955
13959
  } catch (err) {
13956
13960
  setError(err.message);
13957
13961
  setPhase("error");
13958
- setTimeout(onComplete, 1500);
13962
+ setTimeout(() => onComplete(null), 1500);
13959
13963
  }
13960
13964
  };
13961
13965
  fetch2();
@@ -13972,23 +13976,24 @@ var RetrieveSpendRequest = ({
13972
13976
  if (pollRef.current) clearInterval(pollRef.current);
13973
13977
  if (timerRef.current) clearInterval(timerRef.current);
13974
13978
  setPhase("timeout");
13975
- setTimeout(onComplete, 1500);
13979
+ setTimeout(() => onComplete(requestRef.current), 1500);
13976
13980
  return;
13977
13981
  }
13978
13982
  try {
13979
13983
  const result = await repository.getSpendRequest(id, { include });
13980
13984
  if (!result) return;
13985
+ requestRef.current = result;
13981
13986
  setRequest(result);
13982
13987
  if (result.status === "approved") {
13983
13988
  if (pollRef.current) clearInterval(pollRef.current);
13984
13989
  if (timerRef.current) clearInterval(timerRef.current);
13985
13990
  setPhase("success");
13986
- setTimeout(onComplete, 1500);
13991
+ setTimeout(() => onComplete(result), 1500);
13987
13992
  } else if (result.status === "denied") {
13988
13993
  if (pollRef.current) clearInterval(pollRef.current);
13989
13994
  if (timerRef.current) clearInterval(timerRef.current);
13990
13995
  setPhase("declined");
13991
- setTimeout(onComplete, 1500);
13996
+ setTimeout(() => onComplete(result), 1500);
13992
13997
  }
13993
13998
  } catch {
13994
13999
  }
@@ -14061,10 +14066,7 @@ var RetrieveSpendRequest = ({
14061
14066
  /* @__PURE__ */ jsxs15(Text17, { children: [
14062
14067
  "Amount:",
14063
14068
  " ",
14064
- /* @__PURE__ */ jsx22(Text17, { bold: true, children: (() => {
14065
- const t = request?.totals.find((t2) => t2.type === "total");
14066
- return t ? String(t.amount) : "N/A";
14067
- })() })
14069
+ /* @__PURE__ */ jsx22(Text17, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
14068
14070
  ] }),
14069
14071
  /* @__PURE__ */ jsxs15(Text17, { children: [
14070
14072
  "Merchant: ",
@@ -14088,10 +14090,7 @@ var RetrieveSpendRequest = ({
14088
14090
  /* @__PURE__ */ jsxs15(Text17, { children: [
14089
14091
  "Amount:",
14090
14092
  " ",
14091
- /* @__PURE__ */ jsx22(Text17, { bold: true, children: (() => {
14092
- const t = request?.totals.find((t2) => t2.type === "total");
14093
- return t ? String(t.amount) : "N/A";
14094
- })() })
14093
+ /* @__PURE__ */ jsx22(Text17, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
14095
14094
  ] }),
14096
14095
  /* @__PURE__ */ jsxs15(Text17, { children: [
14097
14096
  "Merchant: ",
@@ -14208,11 +14207,15 @@ var createOptions = z6.object({
14208
14207
  )
14209
14208
  });
14210
14209
  var retrieveOptions = z6.object({
14211
- timeout: z6.coerce.number().default(300).describe("Polling timeout in seconds"),
14210
+ timeout: z6.coerce.number().default(300).describe(
14211
+ "Polling timeout in seconds. When reached during active polling, exits non-zero with POLLING_TIMEOUT."
14212
+ ),
14212
14213
  interval: z6.coerce.number().default(0).describe(
14213
- "Poll interval in seconds. When > 0, polls until status is terminal or timeout is reached, yielding status on each attempt."
14214
+ "Poll interval in seconds. When > 0, polls until status is terminal, timeout is reached, or max attempts are exhausted."
14215
+ ),
14216
+ maxAttempts: z6.coerce.number().default(0).describe(
14217
+ "Max poll attempts. 0 = unlimited. Exhaustion during active polling exits non-zero with POLLING_TIMEOUT."
14214
14218
  ),
14215
- maxAttempts: z6.coerce.number().default(0).describe("Max poll attempts. 0 = unlimited (use timeout instead)."),
14216
14219
  include: z6.array(z6.string()).default([]).describe("Include extra data (repeatable, e.g. --include card)")
14217
14220
  });
14218
14221
  var updateOptions = z6.object({
@@ -14248,11 +14251,11 @@ var UpdateSpendRequest = ({
14248
14251
  const result = await repository.updateSpendRequest(id, params);
14249
14252
  setRequest(result);
14250
14253
  setStatus("success");
14251
- setTimeout(onComplete, 1500);
14254
+ setTimeout(() => onComplete(result), 1500);
14252
14255
  } catch (err) {
14253
14256
  setError(err.message);
14254
14257
  setStatus("error");
14255
- setTimeout(onComplete, 1500);
14258
+ setTimeout(() => onComplete(null), 1500);
14256
14259
  }
14257
14260
  };
14258
14261
  update();
@@ -14384,6 +14387,7 @@ function createSpendRequestCli(repository) {
14384
14387
  };
14385
14388
  if (!c.agent && !c.formatExplicit) {
14386
14389
  return new Promise((resolve) => {
14390
+ let capturedResult = null;
14387
14391
  const { waitUntilExit } = render6(
14388
14392
  /* @__PURE__ */ jsx24(
14389
14393
  CreateSpendRequest,
@@ -14391,14 +14395,14 @@ function createSpendRequestCli(repository) {
14391
14395
  repository,
14392
14396
  params: createParams,
14393
14397
  requestApproval,
14394
- onComplete: () => {
14398
+ onComplete: (result) => {
14399
+ capturedResult = result;
14395
14400
  }
14396
14401
  }
14397
14402
  )
14398
14403
  );
14399
- waitUntilExit().then(async () => {
14400
- const created2 = await repository.createSpendRequest(createParams);
14401
- resolve(created2);
14404
+ waitUntilExit().then(() => {
14405
+ resolve(capturedResult);
14402
14406
  });
14403
14407
  });
14404
14408
  }
@@ -14457,6 +14461,7 @@ function createSpendRequestCli(repository) {
14457
14461
  );
14458
14462
  if (!c.agent && !c.formatExplicit) {
14459
14463
  return new Promise((resolve) => {
14464
+ let capturedResult = null;
14460
14465
  const { waitUntilExit } = render6(
14461
14466
  /* @__PURE__ */ jsx24(
14462
14467
  UpdateSpendRequest,
@@ -14464,13 +14469,14 @@ function createSpendRequestCli(repository) {
14464
14469
  repository,
14465
14470
  id,
14466
14471
  params,
14467
- onComplete: () => {
14472
+ onComplete: (result) => {
14473
+ capturedResult = result;
14468
14474
  }
14469
14475
  }
14470
14476
  )
14471
14477
  );
14472
- waitUntilExit().then(async () => {
14473
- resolve(await repository.updateSpendRequest(id, params));
14478
+ waitUntilExit().then(() => {
14479
+ resolve(capturedResult);
14474
14480
  });
14475
14481
  });
14476
14482
  }
@@ -14498,20 +14504,21 @@ function createSpendRequestCli(repository) {
14498
14504
  const id = c.args.id;
14499
14505
  if (!c.agent && !c.formatExplicit) {
14500
14506
  return new Promise((resolve) => {
14507
+ let capturedResult = null;
14501
14508
  const { waitUntilExit } = render6(
14502
14509
  /* @__PURE__ */ jsx24(
14503
14510
  RequestApproval,
14504
14511
  {
14505
14512
  repository,
14506
14513
  id,
14507
- onComplete: () => {
14514
+ onComplete: (result) => {
14515
+ capturedResult = result;
14508
14516
  }
14509
14517
  }
14510
14518
  )
14511
14519
  );
14512
- waitUntilExit().then(async () => {
14513
- const approval2 = await repository.requestApproval(id);
14514
- resolve(approval2);
14520
+ waitUntilExit().then(() => {
14521
+ resolve(capturedResult);
14515
14522
  });
14516
14523
  });
14517
14524
  }
@@ -14554,6 +14561,7 @@ function createSpendRequestCli(repository) {
14554
14561
  const include = includeArr?.length ? includeArr : void 0;
14555
14562
  if (!c.agent && !c.formatExplicit) {
14556
14563
  return new Promise((resolve) => {
14564
+ let capturedResult = null;
14557
14565
  const { waitUntilExit } = render6(
14558
14566
  /* @__PURE__ */ jsx24(
14559
14567
  RetrieveSpendRequest,
@@ -14562,14 +14570,14 @@ function createSpendRequestCli(repository) {
14562
14570
  id,
14563
14571
  timeout,
14564
14572
  include,
14565
- onComplete: () => {
14573
+ onComplete: (result) => {
14574
+ capturedResult = result;
14566
14575
  }
14567
14576
  }
14568
14577
  )
14569
14578
  );
14570
- waitUntilExit().then(async () => {
14571
- const request = await repository.getSpendRequest(id, { include });
14572
- resolve(request);
14579
+ waitUntilExit().then(() => {
14580
+ resolve(capturedResult);
14573
14581
  });
14574
14582
  });
14575
14583
  }
@@ -14596,11 +14604,20 @@ function createSpendRequestCli(repository) {
14596
14604
  return;
14597
14605
  }
14598
14606
  attempts++;
14599
- const shouldStop = interval <= 0 || maxAttempts > 0 && attempts >= maxAttempts || Date.now() >= deadline;
14600
- if (shouldStop) {
14607
+ if (interval <= 0) {
14601
14608
  yield request;
14602
14609
  return;
14603
14610
  }
14611
+ const maxAttemptsExhausted = maxAttempts > 0 && attempts >= maxAttempts;
14612
+ const timeoutReached = Date.now() >= deadline;
14613
+ if (maxAttemptsExhausted || timeoutReached) {
14614
+ const reason = maxAttemptsExhausted ? `max attempts (${maxAttempts}) exhausted` : `timeout (${timeout}s) reached`;
14615
+ return c.error({
14616
+ code: "POLLING_TIMEOUT",
14617
+ message: `Polling stopped before spend request ${id} reached a terminal status: ${reason}; current status is ${request.status}.`,
14618
+ retryable: true
14619
+ });
14620
+ }
14604
14621
  const snapshot = JSON.stringify(request);
14605
14622
  if (snapshot !== previousAttemptData) {
14606
14623
  previousAttemptData = snapshot;
@@ -14913,7 +14930,7 @@ var ResourceFactory = class {
14913
14930
  };
14914
14931
 
14915
14932
  // src/cli.tsx
14916
- var cliVersion = "0.3.1";
14933
+ var cliVersion = "0.4.1";
14917
14934
  var buildNumber = "1";
14918
14935
  var cliName = "@stripe/link-cli";
14919
14936
  var defaultHeaders = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stripe/link-cli",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "link-cli": "./dist/cli.js"