@crvouga/mockingbird-service-stripe 3.10.1 → 3.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog — @crvouga/mockingbird-service-stripe
2
2
 
3
+ ## 3.10.3 (2026-11-02)
4
+
5
+ ### Fixes and improvements
6
+
7
+ - stop walkSchema recursing forever on a self-referential $ref ([69464a9](https://github.com/crvouga/mockingbird/commit/69464a9d9e7f468c5e1095125108d4d3d5515431))
8
+ - densify sparse bracket arrays by their written indices ([84a28cb](https://github.com/crvouga/mockingbird/commit/84a28cb182e3d7df91102897f0fc11fca714ba5f))
9
+ - do not save idempotent results for requests that fail validation ([f2161aa](https://github.com/crvouga/mockingbird/commit/f2161aadeae30bcc586e26131da12a7030bdeb11))
10
+ - keep the command palette's highlighted option in view and announced ([24b8a92](https://github.com/crvouga/mockingbird/commit/24b8a923f65d9deecb2c298169cdc9b7af90e609))
11
+
12
+ ## 3.10.2 (2026-11-02)
13
+
14
+ ### Fixes and improvements
15
+
16
+ - reopen IndexedDB durability connection after the browser force-closes it ([d0b45aa](https://github.com/crvouga/mockingbird/commit/d0b45aa1d12a55967e72b8ddc6573f5998c377ce))
17
+
3
18
  ## 3.10.1 (2026-11-02)
4
19
 
5
20
  ### Fixes and improvements
package/README.md CHANGED
@@ -338,7 +338,10 @@ Like Stripe's portal, it has no pause control: pausing is `pause_collection` or
338
338
  POSTs with `Idempotency-Key` go through the shared `IdempotencyStore`, scoped per account: a
339
339
  replay returns the stored response byte for byte (with `idempotent-replayed: true`); the same key
340
340
  with different parameters is 400 `idempotency_error`; a concurrent request on an in-flight key is
341
- 409 `idempotency_key_in_use`, with Stripe's wording.
341
+ 409 `idempotency_key_in_use`, with Stripe's wording. As Stripe does, a request whose parameters fail validation
342
+ (any `parameter_*` error, such as an unknown or missing parameter) is not saved, so the corrected
343
+ request can be retried under the same key; an error raised once the endpoint ran (a decline,
344
+ `resource_missing`) is saved and replayed.
342
345
 
343
346
  ### Fault presets
344
347
 
@@ -9,7 +9,7 @@ import {
9
9
  resolveAdminPrefix,
10
10
  restoreClock,
11
11
  signV4
12
- } from "./chunk-P7O2SR42.js";
12
+ } from "./chunk-NUTYUHW7.js";
13
13
 
14
14
  // ../../adapters/node/dist/fleet-archive.js
15
15
  import { createHash } from "node:crypto";
@@ -3873,7 +3873,7 @@ async function preflightFleet(config, options) {
3873
3873
  break;
3874
3874
  }
3875
3875
  }
3876
- targets.set(name, { ...target, packageVersion: packageVersion ?? "3.10.1" });
3876
+ targets.set(name, { ...target, packageVersion: packageVersion ?? "3.10.3" });
3877
3877
  } catch (error) {
3878
3878
  throw new Error(`service ${name}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
3879
3879
  }
@@ -6668,4 +6668,4 @@ export {
6668
6668
  withFleetRun,
6669
6669
  NamespacePool
6670
6670
  };
6671
- //# sourceMappingURL=chunk-DKA7ZDNT.js.map
6671
+ //# sourceMappingURL=chunk-KHNJCSHG.js.map
@@ -17,7 +17,7 @@ import {
17
17
  requestBaseUrl,
18
18
  resolveSchema,
19
19
  signers
20
- } from "./chunk-P7O2SR42.js";
20
+ } from "./chunk-NUTYUHW7.js";
21
21
 
22
22
  // src/account.ts
23
23
  var accountOfKey = (key) => `acct_${opaqueToken(key, 8)}`;
@@ -163,7 +163,13 @@ var StripeError = class extends HttpError {
163
163
  this.name = "StripeError";
164
164
  }
165
165
  init;
166
+ /**
167
+ * Raised while reading the request's parameters, before the endpoint began executing.
168
+ * Stripe saves no idempotent result for these (see `IDEMPOTENCY_UNSAVED`).
169
+ */
170
+ validation = false;
166
171
  };
172
+ var IDEMPOTENCY_UNSAVED = "x-mockingbird-idempotency-unsaved";
167
173
  var invalidRequest = (message, param, code) => new StripeError({
168
174
  status: 400,
169
175
  message,
@@ -4244,7 +4250,18 @@ var withoutExpand = (raw) => {
4244
4250
  const { expand, ...rest } = raw;
4245
4251
  return { rest, expand: expandPathsOf(expand) };
4246
4252
  };
4247
- var bodyParams = (context, options = {}) => {
4253
+ var validating = (read) => {
4254
+ try {
4255
+ return read();
4256
+ } catch (error) {
4257
+ if (error instanceof StripeError) error.validation = true;
4258
+ throw error;
4259
+ }
4260
+ };
4261
+ var bodyParams = (context, options = {}) => validating(() => readBodyParams(context, options));
4262
+ var deleteParams = (context, options = {}) => validating(() => readDeleteParams(context, options));
4263
+ var queryParams = (context, options = {}) => validating(() => readQueryParams(context, options));
4264
+ var readBodyParams = (context, options = {}) => {
4248
4265
  const body = context.body;
4249
4266
  const raw = body.kind === "form" ? body.value : {};
4250
4267
  if (typeof raw === "object" && raw !== null && !Array.isArray(raw) && raw.preferred_locales === "")
@@ -4255,7 +4272,7 @@ var bodyParams = (context, options = {}) => {
4255
4272
  if (expandEmpty) throw parameterInvalidEmpty("expand");
4256
4273
  return expand.length === 0 ? params : { ...params, expand };
4257
4274
  };
4258
- var deleteParams = (context, options = {}) => {
4275
+ var readDeleteParams = (context, options = {}) => {
4259
4276
  const query = context.query;
4260
4277
  const fromQuery = typeof query === "object" && query !== null && !Array.isArray(query) && Object.keys(query).some((key) => key !== "expand");
4261
4278
  if (!fromQuery) return bodyParams(context, options);
@@ -4263,7 +4280,7 @@ var deleteParams = (context, options = {}) => {
4263
4280
  const params = stringMetadata(parseParams(formBodySchema(context), rest, options));
4264
4281
  return expand.length === 0 ? params : { ...params, expand };
4265
4282
  };
4266
- var queryParams = (context, options = {}) => {
4283
+ var readQueryParams = (context, options = {}) => {
4267
4284
  const { rest, expand } = withoutExpand(context.query);
4268
4285
  const params = stringMetadata(parseParams(querySchema(context), rest, options));
4269
4286
  if (params.customer !== void 0 && params.customer_account !== void 0)
@@ -15562,8 +15579,10 @@ var StripeAPI = class {
15562
15579
  now: this.now,
15563
15580
  notFound: (request) => this.errorResponse({ status: 404, message: unrecognizedUrl(request) }),
15564
15581
  onError: (error) => {
15565
- if (error instanceof StripeError) return this.errorResponse(error.init);
15566
- throw error;
15582
+ if (!(error instanceof StripeError)) throw error;
15583
+ const response = this.errorResponse(error.init);
15584
+ if (error.validation) response.headers.set(IDEMPOTENCY_UNSAVED, "true");
15585
+ return response;
15567
15586
  },
15568
15587
  before: (context) => {
15569
15588
  if (BROWSER_PATH.test(context.url.pathname)) return void 0;
@@ -15608,6 +15627,7 @@ var StripeAPI = class {
15608
15627
  }
15609
15628
  decorate(response, version, cors) {
15610
15629
  const headers = new Headers(response.headers);
15630
+ headers.delete(IDEMPOTENCY_UNSAVED);
15611
15631
  headers.set("request-id", this.state.ids.next("req_"));
15612
15632
  headers.set("stripe-version", version);
15613
15633
  if (cors) for (const [name, value] of Object.entries(CORS_HEADERS)) headers.set(name, value);
@@ -15711,7 +15731,11 @@ var StripeAPI = class {
15711
15731
  message: `There is currently another in-progress request using this Idempotent Key (that probably means you submitted twice, and the other request is still going through): ${idempotencyKey}. Please try again later.`
15712
15732
  })
15713
15733
  },
15714
- handle
15734
+ handle,
15735
+ // Stripe saves the first response once the endpoint began executing, so a decline or
15736
+ // a missing resource replays; a request whose parameters failed validation never got
15737
+ // that far and can be retried, fixed, under the same key.
15738
+ (status, reply) => status < 500 && !reply.headers.has(IDEMPOTENCY_UNSAVED)
15715
15739
  );
15716
15740
  }
15717
15741
  return this.decorate(response, version, cors);
@@ -15855,4 +15879,4 @@ export {
15855
15879
  createRuntime2 as createRuntime,
15856
15880
  StripeAPI
15857
15881
  };
15858
- //# sourceMappingURL=chunk-HVSAON3H.js.map
15882
+ //# sourceMappingURL=chunk-KXNVS35C.js.map