run402 4.115.0 → 4.116.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.
@@ -1765,12 +1765,13 @@ export class NodeActions {
1765
1765
  if (!opts.fund)
1766
1766
  return false;
1767
1767
  }
1768
+ const faucetKey = run.childKey("wallets.faucet");
1768
1769
  const faucetStep = run.addStep({
1769
1770
  action: "wallets.faucet",
1770
1771
  description: "Request testnet faucet funds for wallet",
1771
1772
  mutation: true,
1772
1773
  auto: true,
1773
- details: { idempotency_key: run.childKey("wallets.faucet") },
1774
+ details: { idempotency_key: faucetKey ?? null },
1774
1775
  });
1775
1776
  await run.approve(faucetStep, ["wallets.faucet"], "Request testnet USDC for the local wallet.");
1776
1777
  if (run.dryRun) {
@@ -1778,9 +1779,7 @@ export class NodeActions {
1778
1779
  return false;
1779
1780
  }
1780
1781
  run.setState(faucetStep, "running");
1781
- const faucet = await this.sdk.wallets.faucet({
1782
- idempotencyKey: run.childKey("wallets.faucet"),
1783
- });
1782
+ const faucet = await this.sdk.wallets.faucet(faucetKey ? { idempotencyKey: faucetKey } : {});
1784
1783
  run.setState(faucetStep, "succeeded", {
1785
1784
  transaction_hash: faucet.transactionHash,
1786
1785
  amount: faucet.amount,
@@ -1806,7 +1805,7 @@ export class NodeActions {
1806
1805
  auto: true,
1807
1806
  details: {
1808
1807
  tier: desiredTier,
1809
- idempotency_key: run.childKey("tier.set"),
1808
+ idempotency_key: run.childKey("tier.set") ?? null,
1810
1809
  reason: "dry_run",
1811
1810
  },
1812
1811
  });
@@ -1853,12 +1852,12 @@ export class NodeActions {
1853
1852
  tier: desiredTier,
1854
1853
  current_tier: current ?? null,
1855
1854
  active: status?.active ?? null,
1856
- idempotency_key: idempotencyKey,
1855
+ idempotency_key: idempotencyKey ?? null,
1857
1856
  },
1858
1857
  });
1859
1858
  await run.approve(step, ["tier.set"], `Set the ${desiredTier} tier (start, renew, or upgrade).`);
1860
1859
  run.setState(step, "running");
1861
- const pay = () => this.sdk.tier.set(desiredTier, { idempotencyKey });
1860
+ const pay = () => this.sdk.tier.set(desiredTier, idempotencyKey ? { idempotencyKey } : {});
1862
1861
  const result = await (justFunded ? afterFaucet(pay) : pay());
1863
1862
  run.setState(step, "succeeded", { tier: result.tier, action: result.action });
1864
1863
  }
@@ -2109,12 +2108,15 @@ class ActionRun {
2109
2108
  get rootIdempotencyKey() {
2110
2109
  return this.input.idempotencyKey ?? this.options.idempotencyKey;
2111
2110
  }
2111
+ /**
2112
+ * A recursive mutation's key exists only under a caller-supplied root. A key
2113
+ * marks one payment or creation intent, a boundary only the caller knows: a
2114
+ * key derived from the inputs alone would answer a deliberate second
2115
+ * purchase with the first one's cached receipt.
2116
+ */
2112
2117
  childKey(scope) {
2113
- const root = this.rootIdempotencyKey ?? deriveStableRootKey(this.input);
2114
- if (!root) {
2115
- throw this.error(`Cannot derive an idempotency key for recursive mutation ${scope}.`, "RUN402_IDEMPOTENCY_REQUIRED", { scope, action: this.input.type });
2116
- }
2117
- return `action:${root}:${scope}`;
2118
+ const root = this.rootIdempotencyKey;
2119
+ return root ? `action:${root}:${scope}` : undefined;
2118
2120
  }
2119
2121
  addStep(init) {
2120
2122
  const step = {
@@ -2963,24 +2965,6 @@ function workspaceLinkConflict(link, input, targetKind, linkPath) {
2963
2965
  }
2964
2966
  return null;
2965
2967
  }
2966
- function deriveStableRootKey(input) {
2967
- if (input.type === Run402Action.ProjectsProvision && input.name) {
2968
- return `projects.provision:${input.name}`;
2969
- }
2970
- if (input.type === Run402Action.Up) {
2971
- const stable = JSON.stringify({
2972
- type: input.type,
2973
- dir: input.dir ?? ".",
2974
- manifest: input.manifest ?? null,
2975
- projectId: input.projectId ?? null,
2976
- name: input.name ?? null,
2977
- tier: input.tier ?? DEFAULT_BOOTSTRAP_TIER,
2978
- orgId: input.orgId ?? null,
2979
- });
2980
- return `up:${createHash("sha256").update(stable).digest("hex").slice(0, 24)}`;
2981
- }
2982
- return null;
2983
- }
2984
2968
  function hasDeployableContent(spec) {
2985
2969
  const meaningful = ["database", "site", "functions", "secrets", "subdomains", "routes", "checks", "i18n", "assets"];
2986
2970
  return meaningful.some((key) => hasContent(spec[key]));