@01.software/sdk 0.44.0 → 0.46.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 (80) hide show
  1. package/CHANGELOG.md +366 -2
  2. package/MIGRATION.md +108 -10
  3. package/README.md +486 -98
  4. package/dist/{server-nXOezi4b.d.cts → catalog-mappers-sIshKNb3.d.cts} +14 -3
  5. package/dist/{server-nXOezi4b.d.ts → catalog-mappers-sIshKNb3.d.ts} +14 -3
  6. package/dist/client.cjs +2693 -345
  7. package/dist/client.cjs.map +1 -1
  8. package/dist/client.d.cts +10 -7
  9. package/dist/client.d.ts +10 -7
  10. package/dist/client.js +2693 -345
  11. package/dist/client.js.map +1 -1
  12. package/dist/{collection-client-DWooaiTr.d.ts → collection-client-D6kKrYdq.d.ts} +8 -5
  13. package/dist/{collection-client-Dyl-CDcj.d.cts → collection-client-DolMjCoC.d.cts} +8 -5
  14. package/dist/{const-pGDnsy0o.d.ts → const-BAG0MH0u.d.cts} +13 -10
  15. package/dist/{const-1vleZ6ov.d.cts → const-CaPq2AE4.d.ts} +13 -10
  16. package/dist/errors.cjs +74 -1
  17. package/dist/errors.cjs.map +1 -1
  18. package/dist/errors.d.cts +38 -1
  19. package/dist/errors.d.ts +38 -1
  20. package/dist/errors.js +74 -1
  21. package/dist/errors.js.map +1 -1
  22. package/dist/{index-DUNySyxV.d.ts → index-BNICJxBL.d.ts} +4 -4
  23. package/dist/{index-a6g7vqAD.d.cts → index-YGrZrxNn.d.cts} +4 -4
  24. package/dist/index.cjs +2754 -368
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +18 -19
  27. package/dist/index.d.ts +18 -19
  28. package/dist/index.js +2754 -368
  29. package/dist/index.js.map +1 -1
  30. package/dist/{payload-types-CDsuOEfM.d.cts → payload-types-CJZuXcgF.d.cts} +6671 -4001
  31. package/dist/{payload-types-CDsuOEfM.d.ts → payload-types-CJZuXcgF.d.ts} +6671 -4001
  32. package/dist/query.cjs +558 -101
  33. package/dist/query.cjs.map +1 -1
  34. package/dist/query.d.cts +43 -45
  35. package/dist/query.d.ts +43 -45
  36. package/dist/query.js +558 -101
  37. package/dist/query.js.map +1 -1
  38. package/dist/realtime.cjs.map +1 -1
  39. package/dist/realtime.d.cts +2 -2
  40. package/dist/realtime.d.ts +2 -2
  41. package/dist/realtime.js.map +1 -1
  42. package/dist/server.cjs +2343 -437
  43. package/dist/server.cjs.map +1 -1
  44. package/dist/server.d.cts +11 -10
  45. package/dist/server.d.ts +11 -10
  46. package/dist/server.js +2343 -437
  47. package/dist/server.js.map +1 -1
  48. package/dist/storefront-cache.cjs +65 -1
  49. package/dist/storefront-cache.cjs.map +1 -1
  50. package/dist/storefront-cache.js +65 -1
  51. package/dist/storefront-cache.js.map +1 -1
  52. package/dist/types-BC6rVmJa.d.ts +47 -0
  53. package/dist/{types-CDND3hzq.d.cts → types-C60vHIkY.d.ts} +1134 -509
  54. package/dist/types-D5p7-m1l.d.cts +47 -0
  55. package/dist/{types-Dt9FJisi.d.ts → types-xlqBeW2N.d.cts} +1134 -509
  56. package/dist/ui/canvas/server.cjs +244 -2
  57. package/dist/ui/canvas/server.cjs.map +1 -1
  58. package/dist/ui/canvas/server.d.cts +27 -1
  59. package/dist/ui/canvas/server.d.ts +27 -1
  60. package/dist/ui/canvas/server.js +244 -2
  61. package/dist/ui/canvas/server.js.map +1 -1
  62. package/dist/ui/canvas.cjs +419 -103
  63. package/dist/ui/canvas.cjs.map +1 -1
  64. package/dist/ui/canvas.d.cts +19 -7
  65. package/dist/ui/canvas.d.ts +19 -7
  66. package/dist/ui/canvas.js +419 -103
  67. package/dist/ui/canvas.js.map +1 -1
  68. package/dist/ui/form.d.cts +1 -1
  69. package/dist/ui/form.d.ts +1 -1
  70. package/dist/ui/video.d.cts +1 -1
  71. package/dist/ui/video.d.ts +1 -1
  72. package/dist/webhook.cjs +2 -1
  73. package/dist/webhook.cjs.map +1 -1
  74. package/dist/webhook.d.cts +4 -4
  75. package/dist/webhook.d.ts +4 -4
  76. package/dist/webhook.js +2 -1
  77. package/dist/webhook.js.map +1 -1
  78. package/package.json +10 -9
  79. package/dist/types-SoXsbKhj.d.cts +0 -33
  80. package/dist/types-oiae_LMm.d.ts +0 -33
package/dist/index.js CHANGED
@@ -28,10 +28,136 @@ var SDKError = class extends Error {
28
28
  details: this.details,
29
29
  userMessage: this.userMessage,
30
30
  suggestion: this.suggestion,
31
- ...this.requestId !== void 0 && { requestId: this.requestId }
31
+ ...this.requestId !== void 0 && { requestId: this.requestId },
32
+ ...this.kind !== void 0 && { kind: this.kind },
33
+ ...this.reason !== void 0 && { reason: this.reason },
34
+ ...this.rawReason !== void 0 && { rawReason: this.rawReason },
35
+ ...this.retryable !== void 0 && { retryable: this.retryable },
36
+ ...this.retryAfter !== void 0 && { retryAfter: this.retryAfter }
32
37
  };
33
38
  }
34
39
  };
40
+ var COMMERCE_ERROR_CODES = [
41
+ "validation_failed",
42
+ "unauthorized",
43
+ "forbidden",
44
+ "token_expired",
45
+ "origin_not_allowed",
46
+ "server_credentials_required",
47
+ "not_found",
48
+ "conflict",
49
+ "cart_revision_conflict",
50
+ "rate_limit_exceeded",
51
+ "usage_limit_exceeded",
52
+ "service_unavailable",
53
+ "idempotency_conflict",
54
+ "idempotency_in_progress",
55
+ "cart_not_active",
56
+ "cart_locked",
57
+ "cart_empty",
58
+ "cart_market_unavailable",
59
+ "cart_market_mismatch",
60
+ "checkout_not_open",
61
+ "payment_slot_held",
62
+ "reservation_expired",
63
+ "payment_session_not_cancelable",
64
+ "provider_identity_mismatch",
65
+ "provider_unavailable",
66
+ "lock_timeout",
67
+ "price_changed",
68
+ "pricing_fact_in_use",
69
+ "insufficient_stock",
70
+ "market_not_found",
71
+ "market_shipping_currency_unsupported",
72
+ "missing_market_rate",
73
+ "missing_shipping_amount",
74
+ "no_enabled_payment_provider",
75
+ "product_market_unavailable",
76
+ "unsupported_currency",
77
+ "missing_price_row",
78
+ "payment_provider_currency_unsupported",
79
+ "discount_code_not_found",
80
+ "discount_not_started",
81
+ "discount_expired",
82
+ "discount_usage_limit",
83
+ "discount_per_customer_limit",
84
+ "discount_customer_required",
85
+ "discount_first_order_only",
86
+ "discount_customer_not_eligible",
87
+ "discount_customer_excluded",
88
+ "discount_items_required",
89
+ "discount_product_not_eligible",
90
+ "discount_product_excluded",
91
+ "discount_min_order_amount",
92
+ "discount_currency_scope_required",
93
+ "discount_allocation_method_unsupported",
94
+ "currency_mismatch"
95
+ ];
96
+ var COMMERCE_ERROR_CODE_SET = new Set(
97
+ COMMERCE_ERROR_CODES
98
+ );
99
+ var COMMERCE_ERROR_ENVELOPE_KEYS = /* @__PURE__ */ new Set([
100
+ "error",
101
+ "reason",
102
+ "requestId",
103
+ "retryable",
104
+ "details"
105
+ ]);
106
+ function isPlainRecord(value) {
107
+ return typeof value === "object" && value !== null && !Array.isArray(value);
108
+ }
109
+ function commerceProtocolError(issue, trustedRequestId) {
110
+ return createApiError(
111
+ "Invalid canonical commerce error response.",
112
+ 502,
113
+ { protocol: "commerce-error-envelope", issue },
114
+ "The server returned an incompatible commerce error response.",
115
+ "Verify that the Console commerce contract is deployed before using this SDK version.",
116
+ trustedRequestId
117
+ );
118
+ }
119
+ function parseCommerceErrorEnvelope(body, headerRequestId) {
120
+ if (!isPlainRecord(body)) {
121
+ throw commerceProtocolError("expected_object", headerRequestId);
122
+ }
123
+ if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {
124
+ throw commerceProtocolError("unexpected_field", headerRequestId);
125
+ }
126
+ if (typeof body.error !== "string" || body.error.length === 0 || typeof body.reason !== "string" || body.reason.length === 0 || typeof body.requestId !== "string" || body.requestId.length === 0 || body.retryable !== void 0 && typeof body.retryable !== "boolean" || body.details !== void 0 && !isPlainRecord(body.details)) {
127
+ throw commerceProtocolError("invalid_field", headerRequestId);
128
+ }
129
+ if (headerRequestId && headerRequestId !== body.requestId) {
130
+ throw commerceProtocolError("request_id_mismatch", headerRequestId);
131
+ }
132
+ return {
133
+ error: body.error,
134
+ reason: body.reason,
135
+ requestId: body.requestId,
136
+ retryable: body.retryable === true,
137
+ ...body.details === void 0 ? {} : { details: body.details }
138
+ };
139
+ }
140
+ function enhanceCommerceError(error, body, headerRequestId) {
141
+ const envelope = parseCommerceErrorEnvelope(body, headerRequestId);
142
+ const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason);
143
+ Object.assign(error, {
144
+ code: envelope.reason,
145
+ kind: "commerce",
146
+ reason: known ? envelope.reason : "unknown_commerce_error",
147
+ ...known ? {} : { rawReason: envelope.reason },
148
+ requestId: envelope.requestId,
149
+ retryable: envelope.retryable,
150
+ details: envelope.details
151
+ });
152
+ return error;
153
+ }
154
+ function isCommerceSDKError(error) {
155
+ if (!(error instanceof SDKError) || error.kind !== "commerce") return false;
156
+ if (typeof error.requestId !== "string" || typeof error.retryable !== "boolean" || error.retryAfter !== void 0 && (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0) || typeof error.reason !== "string") {
157
+ return false;
158
+ }
159
+ return error.reason === "unknown_commerce_error" ? typeof error.rawReason === "string" : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === void 0;
160
+ }
35
161
  var NetworkError = class extends SDKError {
36
162
  constructor(message, status, details, userMessage, suggestion) {
37
163
  super("NETWORK_ERROR", message, status, details, userMessage, suggestion);
@@ -270,6 +396,7 @@ var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
270
396
  var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
271
397
  var DEFAULT_MAX_RETRIES = 3;
272
398
  var STOREFRONT_BROWSER_MAX_RETRIES = 1;
399
+ var MAX_AUTOMATIC_RETRY_AFTER_SECONDS = 5 * 60;
273
400
  function debugLog(debug, type, message, data) {
274
401
  if (!debug) return;
275
402
  const shouldLog = debug === true || type === "request" && debug.logRequests || type === "response" && debug.logResponses || type === "error" && debug.logErrors;
@@ -293,6 +420,11 @@ function redactSensitiveHeaders(headers) {
293
420
  redacted["x-preview-token"]
294
421
  );
295
422
  }
423
+ if (redacted["x-custom-payment-signature"]) {
424
+ redacted["x-custom-payment-signature"] = redactSensitiveHeader(
425
+ redacted["x-custom-payment-signature"]
426
+ );
427
+ }
296
428
  return redacted;
297
429
  }
298
430
  function getErrorSuggestion(status) {
@@ -384,116 +516,129 @@ function attachRequestId(err, id) {
384
516
  }
385
517
  function parseRetryAfter(response) {
386
518
  const raw = response.headers.get("Retry-After");
387
- if (!raw) return void 0;
388
- return parseInt(raw, 10) || void 0;
519
+ if (!raw) return { permitsAutomaticRetry: true };
520
+ const trimmed = raw.trim();
521
+ let seconds;
522
+ if (/^\d+$/.test(trimmed)) {
523
+ seconds = Number(trimmed);
524
+ if (!Number.isSafeInteger(seconds)) {
525
+ return { permitsAutomaticRetry: false };
526
+ }
527
+ } else {
528
+ const retryAt = Date.parse(trimmed);
529
+ if (!Number.isFinite(retryAt)) return { permitsAutomaticRetry: true };
530
+ seconds = Math.max(0, Math.ceil((retryAt - Date.now()) / 1e3));
531
+ }
532
+ return {
533
+ seconds,
534
+ permitsAutomaticRetry: seconds <= MAX_AUTOMATIC_RETRY_AFTER_SECONDS
535
+ };
389
536
  }
390
- function mapResponseToError(status, parsed, details, requestId, retryAfter) {
537
+ function mapResponseToError(status, parsed, details, requestId, retryAfter, errorFamily) {
391
538
  const errorDetails = {
392
539
  ...details,
393
540
  ...parsed.errors && { errors: parsed.errors },
394
- ...parsed.body && { body: parsed.body }
541
+ ...errorFamily !== "commerce" && parsed.body && { body: parsed.body }
395
542
  };
396
543
  const suggestion = getParsedErrorSuggestion(status, parsed);
544
+ const finalize = (error) => {
545
+ const withRequestId = attachRequestId(error, requestId);
546
+ if (retryAfter !== void 0) {
547
+ Object.assign(withRequestId, { retryAfter });
548
+ }
549
+ return errorFamily === "commerce" ? enhanceCommerceError(withRequestId, parsed.body, requestId) : withRequestId;
550
+ };
397
551
  if (status === 400 || status === 422) {
398
- return attachRequestId(
552
+ return finalize(
399
553
  createValidationError(
400
554
  parsed.errorMessage,
401
555
  errorDetails,
402
556
  parsed.userMessage,
403
557
  suggestion,
404
558
  status
405
- ),
406
- requestId
559
+ )
407
560
  );
408
561
  }
409
562
  if (status === 401) {
410
- return attachRequestId(
563
+ return finalize(
411
564
  createAuthError(
412
565
  parsed.errorMessage,
413
566
  errorDetails,
414
567
  parsed.userMessage,
415
568
  suggestion
416
- ),
417
- requestId
569
+ )
418
570
  );
419
571
  }
420
572
  if (status === 403) {
421
- return attachRequestId(
573
+ return finalize(
422
574
  createPermissionError(
423
575
  parsed.errorMessage,
424
576
  errorDetails,
425
577
  parsed.userMessage,
426
578
  suggestion
427
- ),
428
- requestId
579
+ )
429
580
  );
430
581
  }
431
582
  if (status === 404) {
432
- return attachRequestId(
583
+ return finalize(
433
584
  createNotFoundError(
434
585
  parsed.errorMessage,
435
586
  errorDetails,
436
587
  parsed.userMessage,
437
588
  suggestion
438
- ),
439
- requestId
589
+ )
440
590
  );
441
591
  }
442
592
  if (status === 409) {
443
- return attachRequestId(
593
+ return finalize(
444
594
  createConflictError(
445
595
  parsed.errorMessage,
446
596
  errorDetails,
447
597
  parsed.userMessage,
448
598
  suggestion
449
- ),
450
- requestId
599
+ )
451
600
  );
452
601
  }
453
602
  if (status === 410) {
454
- return attachRequestId(
603
+ return finalize(
455
604
  createGoneError(
456
605
  parsed.errorMessage,
457
606
  errorDetails,
458
607
  parsed.userMessage,
459
608
  suggestion
460
- ),
461
- requestId
609
+ )
462
610
  );
463
611
  }
464
612
  if (status === 429) {
465
- return attachRequestId(
613
+ return finalize(
466
614
  createRateLimitError(
467
615
  parsed.errorMessage,
468
616
  retryAfter,
469
617
  errorDetails,
470
618
  parsed.userMessage,
471
619
  suggestion
472
- ),
473
- requestId
620
+ )
474
621
  );
475
622
  }
476
623
  if (status === 503) {
477
- return attachRequestId(
624
+ return finalize(
478
625
  createServiceUnavailableError(
479
626
  parsed.errorMessage,
480
627
  retryAfter,
481
628
  errorDetails,
482
629
  parsed.userMessage,
483
630
  suggestion
484
- ),
485
- requestId
631
+ )
486
632
  );
487
633
  }
488
- return attachRequestId(
634
+ return finalize(
489
635
  createNetworkError(
490
636
  parsed.errorMessage,
491
637
  status,
492
638
  errorDetails,
493
639
  parsed.userMessage,
494
640
  suggestion
495
- ),
496
- requestId
641
+ )
497
642
  );
498
643
  }
499
644
  async function httpFetch(url, options) {
@@ -506,6 +651,7 @@ async function httpFetch(url, options) {
506
651
  debug,
507
652
  retry,
508
653
  onUnauthorized,
654
+ errorFamily,
509
655
  ...requestInit
510
656
  } = options || {};
511
657
  const baseUrl = resolveApiUrl(apiUrl);
@@ -558,6 +704,8 @@ async function httpFetch(url, options) {
558
704
  headers: redactSensitiveHeaders(response.headers)
559
705
  });
560
706
  if (!response.ok) {
707
+ const parsed = await parseErrorBody(response);
708
+ const commerceEnvelope = errorFamily === "commerce" ? parseCommerceErrorEnvelope(parsed.body, requestId) : void 0;
561
709
  if (isUsageLimitExceededResponse(response)) {
562
710
  const limit = parseInt(
563
711
  response.headers.get("X-Usage-Limit") || "0",
@@ -571,7 +719,7 @@ async function httpFetch(url, options) {
571
719
  response.headers.get("X-Usage-Remaining") || "0",
572
720
  10
573
721
  );
574
- throw attachRequestId(
722
+ const usageError = attachRequestId(
575
723
  createUsageLimitError(
576
724
  `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
577
725
  { limit, current, remaining },
@@ -585,9 +733,9 @@ async function httpFetch(url, options) {
585
733
  ),
586
734
  requestId
587
735
  );
736
+ throw errorFamily === "commerce" ? enhanceCommerceError(usageError, parsed.body, requestId) : usageError;
588
737
  }
589
- const parsed = await parseErrorBody(response);
590
- if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && parsed.reason === "token_expired") {
738
+ if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && (commerceEnvelope?.reason ?? parsed.reason) === "token_expired") {
591
739
  hasRetried401 = true;
592
740
  try {
593
741
  const newToken = await onUnauthorized();
@@ -609,13 +757,18 @@ async function httpFetch(url, options) {
609
757
  parsed,
610
758
  details,
611
759
  requestId,
612
- retryAfter
760
+ retryAfter.seconds,
761
+ errorFamily
613
762
  );
614
763
  const method2 = (requestInit.method || "GET").toUpperCase();
615
764
  const isTerminal = error instanceof RateLimitError || error instanceof UsageLimitError;
616
- if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method2) && !isTerminal && !NON_RETRYABLE_STATUSES.includes(response.status) && retryConfig.retryableStatuses.includes(response.status)) {
765
+ const responseAllowsRetry = isCommerceSDKError(error) ? error.retryable : true;
766
+ if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method2) && !isTerminal && responseAllowsRetry && retryAfter.permitsAutomaticRetry && !NON_RETRYABLE_STATUSES.includes(response.status) && retryConfig.retryableStatuses.includes(response.status)) {
617
767
  lastError = error;
618
- const retryDelay = retryConfig.retryDelay(attempt);
768
+ const retryDelay = Math.max(
769
+ retryConfig.retryDelay(attempt),
770
+ (retryAfter.seconds ?? 0) * 1e3
771
+ );
619
772
  debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
620
773
  await delay(retryDelay);
621
774
  continue;
@@ -685,87 +838,45 @@ async function httpFetch(url, options) {
685
838
  throw lastError ?? new NetworkError("Request failed after retries");
686
839
  }
687
840
 
688
- // src/core/api/endpoints.ts
689
- var COMMERCE_ENDPOINTS = {
690
- orders: {
691
- create: "/api/orders/create",
692
- update: "/api/orders/update",
693
- confirmPayment: "/api/orders/confirm-payment",
694
- byPayment: "/api/orders/by-payment",
695
- cancel: "/api/orders/cancel",
696
- resolveCancelRefund: "/api/orders/resolve-cancel-refund",
697
- checkout: "/api/orders/checkout",
698
- createFulfillment: "/api/orders/create-fulfillment",
699
- updateFulfillment: "/api/orders/update-fulfillment"
700
- },
701
- transactions: {
702
- update: "/api/transactions/update"
703
- },
704
- returns: {
705
- create: "/api/returns/create",
706
- update: "/api/returns/update",
707
- returnRefund: "/api/returns/return-refund"
708
- },
709
- fulfillmentOrders: {
710
- prepare: "/api/fulfillment-orders/prepare-fulfillment-order"
711
- },
712
- fulfillments: {
713
- bulkImport: "/api/fulfillments/bulk-import"
714
- },
715
- carts: {
716
- mine: "/api/carts/mine",
717
- merge: "/api/carts/merge",
718
- addItem: "/api/carts/add-item",
719
- updateItem: "/api/carts/update-item",
720
- removeItem: "/api/carts/remove-item",
721
- applyDiscount: "/api/carts/apply-discount",
722
- removeDiscount: "/api/carts/remove-discount",
723
- clear: "/api/carts/clear"
724
- },
725
- products: {
726
- stockCheck: "/api/products/stock-check",
727
- stockSnapshot: "/api/products/stock",
728
- listingGroups: "/api/products/listing-groups",
729
- listingGroupsCatalog: "/api/products/listing-groups/catalog",
730
- listingGroupsQuery: "/api/products/listing-groups/query",
731
- listingGroupsQueryCatalog: "/api/products/listing-groups/query/catalog",
732
- detail: "/api/products/detail",
733
- detailCatalog: "/api/products/detail/catalog",
734
- upsert: "/api/products/upsert"
735
- }
736
- };
737
- var COMMERCE_ENDPOINT_PATHS = Object.values(
738
- COMMERCE_ENDPOINTS
739
- ).flatMap((group) => Object.values(group));
740
- var MEMBERSHIP_ENDPOINTS = {
741
- subscribe: "/api/memberships/subscribe",
742
- cancel: (id) => `/api/memberships/${id}/cancel`,
743
- me: "/api/memberships/me"
744
- };
745
-
746
841
  // src/core/internal/utils/query-string.ts
747
- function productDetailQuery(params) {
748
- const search = new URLSearchParams();
749
- if ("slug" in params) {
750
- search.set("slug", params.slug);
751
- } else {
752
- search.set("id", params.id);
842
+ function normalizedMarket(value) {
843
+ const market = value?.trim();
844
+ return market || void 0;
845
+ }
846
+ function appendProductLocaleSearchParams(search, options) {
847
+ if (options?.locale) search.set("locale", options.locale);
848
+ if (options?.fallbackLocale !== void 0) {
849
+ search.set(
850
+ "fallbackLocale",
851
+ options.fallbackLocale === false ? "none" : options.fallbackLocale
852
+ );
753
853
  }
754
- return `${COMMERCE_ENDPOINTS.products.detail}?${search}`;
755
854
  }
756
- function productDetailCatalogQuery(params) {
855
+ function productDetailSearchParams(params) {
757
856
  const search = new URLSearchParams();
758
857
  if ("slug" in params) {
759
858
  search.set("slug", params.slug);
760
859
  } else {
761
860
  search.set("id", params.id);
762
861
  }
763
- return `${COMMERCE_ENDPOINTS.products.detailCatalog}?${search}`;
862
+ const market = normalizedMarket(params.market);
863
+ if (market) search.set("market", market);
864
+ appendProductLocaleSearchParams(search, params);
865
+ return search.toString();
764
866
  }
765
- function listingGroupsCatalogQuery(params) {
766
- return `${COMMERCE_ENDPOINTS.products.listingGroupsCatalog}?ids=${params.productIds.map(encodeURIComponent).join(",")}`;
867
+ function listingGroupsSearchParams(params) {
868
+ const ids = params.productIds.map(encodeURIComponent).join(",");
869
+ const search = new URLSearchParams();
870
+ const market = normalizedMarket(params.market);
871
+ if (market) search.set("market", market);
872
+ appendProductLocaleSearchParams(search, params);
873
+ const query = search.toString();
874
+ return `ids=${ids}${query ? `&${query}` : ""}`;
767
875
  }
768
876
  function appendListingGroupsQuerySearchParams(search, options) {
877
+ const market = normalizedMarket(options?.market);
878
+ if (market) search.set("market", market);
879
+ appendProductLocaleSearchParams(search, options);
769
880
  if (options?.page != null) search.set("page", String(options.page));
770
881
  if (options?.limit != null) search.set("limit", String(options.limit));
771
882
  if (options?.sort != null) {
@@ -776,20 +887,13 @@ function appendListingGroupsQuerySearchParams(search, options) {
776
887
  search.set("whereJson", JSON.stringify(options.where));
777
888
  }
778
889
  }
779
- function listingGroupsQueryUrl(options) {
780
- const search = new URLSearchParams();
781
- appendListingGroupsQuerySearchParams(search, options);
782
- const query = search.toString();
783
- return `${COMMERCE_ENDPOINTS.products.listingGroupsQuery}${query ? `?${query}` : ""}`;
784
- }
785
- function listingGroupsQueryCatalogUrl(options) {
890
+ function listingPageSearchParams(options) {
786
891
  const search = new URLSearchParams();
787
892
  appendListingGroupsQuerySearchParams(search, options);
788
- const query = search.toString();
789
- return `${COMMERCE_ENDPOINTS.products.listingGroupsQueryCatalog}${query ? `?${query}` : ""}`;
893
+ return search.toString();
790
894
  }
791
- function stockSnapshotQuery(params) {
792
- return `${COMMERCE_ENDPOINTS.products.stockSnapshot}?variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
895
+ function stockSnapshotSearchParams(params) {
896
+ return `variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
793
897
  }
794
898
 
795
899
  // src/core/collection/http-client.ts
@@ -832,10 +936,15 @@ var HttpClient = class {
832
936
  throw err;
833
937
  }
834
938
  }
835
- buildUrl(endpoint, options) {
836
- if (!options) return endpoint;
837
- const queryString = stringify(options, { addQueryPrefix: true });
838
- return queryString ? `${endpoint}${queryString}` : endpoint;
939
+ buildUrl(endpoint2, options) {
940
+ if (!options) return endpoint2;
941
+ const { fallbackLocale, ...rest } = options;
942
+ const queryOptions = fallbackLocale === void 0 ? rest : {
943
+ ...rest,
944
+ "fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
945
+ };
946
+ const queryString = stringify(queryOptions, { addQueryPrefix: true });
947
+ return queryString ? `${endpoint2}${queryString}` : endpoint2;
839
948
  }
840
949
  assertJsonResponse(response) {
841
950
  const contentType = response.headers.get("content-type");
@@ -984,39 +1093,39 @@ var ReadOnlyCollectionClient = class extends HttpClient {
984
1093
  from(collection) {
985
1094
  return new ReadOnlyCollectionQueryBuilder(this, collection);
986
1095
  }
987
- async requestFind(endpoint, options) {
988
- const url = this.buildUrl(endpoint, options);
1096
+ async requestFind(endpoint2, options) {
1097
+ const url = this.buildUrl(endpoint2, options);
989
1098
  const response = await this.fetchWithTracking(url, {
990
1099
  ...this.defaultOptions,
991
1100
  method: "GET"
992
1101
  });
993
1102
  return this.parseFindResponse(response);
994
1103
  }
995
- async requestFindEndpoint(endpoint, data) {
996
- const response = await this.fetchWithTracking(endpoint, {
1104
+ async requestFindEndpoint(endpoint2, data) {
1105
+ const response = await this.fetchWithTracking(endpoint2, {
997
1106
  ...this.defaultOptions,
998
1107
  method: "POST",
999
1108
  body: data ? JSON.stringify(data) : void 0
1000
1109
  });
1001
1110
  return this.parseFindResponse(response);
1002
1111
  }
1003
- async requestFindEndpointGet(endpoint) {
1004
- const response = await this.fetchWithTracking(endpoint, {
1112
+ async requestFindEndpointGet(endpoint2) {
1113
+ const response = await this.fetchWithTracking(endpoint2, {
1005
1114
  ...this.defaultOptions,
1006
1115
  method: "GET"
1007
1116
  });
1008
1117
  return this.parseFindResponse(response);
1009
1118
  }
1010
- async requestFindById(endpoint, options) {
1011
- const url = this.buildUrl(endpoint, options);
1119
+ async requestFindById(endpoint2, options) {
1120
+ const url = this.buildUrl(endpoint2, options);
1012
1121
  const response = await this.fetchWithTracking(url, {
1013
1122
  ...this.defaultOptions,
1014
1123
  method: "GET"
1015
1124
  });
1016
1125
  return this.parseDocumentResponse(response);
1017
1126
  }
1018
- async requestCount(endpoint, options) {
1019
- const url = this.buildUrl(endpoint, options);
1127
+ async requestCount(endpoint2, options) {
1128
+ const url = this.buildUrl(endpoint2, options);
1020
1129
  const response = await this.fetchWithTracking(url, {
1021
1130
  ...this.defaultOptions,
1022
1131
  method: "GET"
@@ -1026,53 +1135,347 @@ var ReadOnlyCollectionClient = class extends HttpClient {
1026
1135
  };
1027
1136
 
1028
1137
  // src/core/api/parse-response.ts
1029
- async function parseApiResponse(response, endpoint) {
1030
- let data;
1138
+ async function parseApiResponse(response, endpoint2, options = {}) {
1139
+ if (response.status === 204 || response.headers.get("content-length") === "0") {
1140
+ return void 0;
1141
+ }
1142
+ let parsed;
1031
1143
  try {
1032
- data = await response.json();
1144
+ parsed = await response.json();
1033
1145
  } catch {
1034
1146
  throw createApiError(
1035
- `Invalid JSON response from ${endpoint}`,
1147
+ `Invalid JSON response from ${endpoint2}`,
1036
1148
  response.status,
1037
1149
  void 0,
1038
1150
  "Server returned an invalid response.",
1039
1151
  "Check if the API endpoint is available."
1040
1152
  );
1041
1153
  }
1154
+ if (parsed === null || typeof parsed !== "object") {
1155
+ return parsed;
1156
+ }
1157
+ const data = parsed;
1042
1158
  if (data.error) {
1043
1159
  const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
1044
1160
  const reason = typeof data.reason === "string" ? data.reason : void 0;
1045
1161
  const requestId = response.headers.get("x-request-id") ?? void 0;
1046
- const retryAfterRaw = response.headers.get("Retry-After");
1047
- const retryAfter = retryAfterRaw ? parseInt(retryAfterRaw, 10) || void 0 : void 0;
1162
+ const retryAfter = parseRetryAfter(response).seconds;
1163
+ let error;
1048
1164
  if (reason === "validation_failed") {
1049
- throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId);
1050
- }
1051
- if (reason === "token_expired" || reason === "token_invalid" || reason === "preview_token_invalid" || reason === "preview_token_required" || reason === "key_invalid" || reason === "key_revoked") {
1052
- throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId);
1165
+ error = createValidationError(errorMessage, data, errorMessage);
1166
+ } else if (reason === "token_expired" || reason === "token_invalid" || reason === "preview_token_invalid" || reason === "preview_token_required" || reason === "key_invalid" || reason === "key_revoked") {
1167
+ error = createAuthError(errorMessage, data, errorMessage);
1168
+ } else if (reason === "forbidden") {
1169
+ error = createPermissionError(errorMessage, data, errorMessage);
1170
+ } else if (reason === "rate_limit_exceeded") {
1171
+ error = createRateLimitError(errorMessage, retryAfter, data, errorMessage);
1172
+ } else if (reason === "not_found") {
1173
+ error = createNotFoundError(errorMessage, data, errorMessage);
1174
+ } else if (reason === "conflict") {
1175
+ error = createConflictError(errorMessage, data, errorMessage);
1176
+ } else {
1177
+ error = createApiError(
1178
+ errorMessage,
1179
+ response.status,
1180
+ data,
1181
+ errorMessage,
1182
+ "An error occurred while processing the request."
1183
+ );
1053
1184
  }
1054
- if (reason === "forbidden") {
1055
- throw attachRequestId(createPermissionError(errorMessage, data, errorMessage), requestId);
1185
+ const withRequestId = attachRequestId(error, requestId);
1186
+ if (retryAfter !== void 0) Object.assign(withRequestId, { retryAfter });
1187
+ throw options.errorFamily === "commerce" ? enhanceCommerceError(withRequestId, data, requestId) : withRequestId;
1188
+ }
1189
+ return data;
1190
+ }
1191
+
1192
+ // ../../internal/http-contracts/src/index.ts
1193
+ var operationBrand = /* @__PURE__ */ Symbol("sdk-http-operation");
1194
+ var operation = (collection, method, path) => Object.freeze({
1195
+ [operationBrand]: true,
1196
+ collection,
1197
+ method,
1198
+ path
1199
+ });
1200
+ var COMMERCE_ENDPOINT_OPERATIONS = {
1201
+ products: {
1202
+ detail: operation("products", "get", "/detail"),
1203
+ detailCatalog: operation("products", "get", "/detail/catalog"),
1204
+ listingGroups: operation("products", "get", "/listing-groups"),
1205
+ listingGroupsCatalog: operation(
1206
+ "products",
1207
+ "get",
1208
+ "/listing-groups/catalog"
1209
+ ),
1210
+ listingGroupsQuery: operation("products", "post", "/listing-groups/query"),
1211
+ listingGroupsQueryGet: operation(
1212
+ "products",
1213
+ "get",
1214
+ "/listing-groups/query"
1215
+ ),
1216
+ listingGroupsQueryCatalog: operation(
1217
+ "products",
1218
+ "get",
1219
+ "/listing-groups/query/catalog"
1220
+ ),
1221
+ stockCheck: operation("products", "post", "/stock-check"),
1222
+ stockSnapshot: operation("products", "get", "/stock"),
1223
+ upsert: operation("products", "post", "/upsert")
1224
+ },
1225
+ orders: {
1226
+ create: operation("orders", "post", "/create"),
1227
+ update: operation("orders", "post", "/update"),
1228
+ confirmPayment: operation("orders", "post", "/confirm-payment"),
1229
+ byPayment: operation("orders", "get", "/by-payment"),
1230
+ cancel: operation("orders", "post", "/cancel"),
1231
+ resolveCancelRefund: operation("orders", "post", "/resolve-cancel-refund"),
1232
+ checkout: operation("orders", "post", "/checkout"),
1233
+ createFulfillment: operation("orders", "post", "/create-fulfillment"),
1234
+ updateFulfillment: operation("orders", "post", "/update-fulfillment")
1235
+ },
1236
+ checkouts: {
1237
+ detail: operation("checkouts", "post", "/detail"),
1238
+ query: operation("checkouts", "post", "/query")
1239
+ },
1240
+ transactions: {
1241
+ update: operation("transactions", "post", "/update")
1242
+ },
1243
+ returns: {
1244
+ create: operation("returns", "post", "/create"),
1245
+ update: operation("returns", "post", "/update"),
1246
+ returnRefund: operation("returns", "post", "/return-refund")
1247
+ },
1248
+ fulfillmentOrders: {
1249
+ prepare: operation(
1250
+ "fulfillment-orders",
1251
+ "post",
1252
+ "/prepare-fulfillment-order"
1253
+ )
1254
+ },
1255
+ fulfillments: {
1256
+ bulkImport: operation("fulfillments", "post", "/bulk-import")
1257
+ },
1258
+ carts: {
1259
+ create: operation("carts", "post", "/create"),
1260
+ retrieve: operation("carts", "post", "/retrieve"),
1261
+ mine: operation("carts", "post", "/mine"),
1262
+ merge: operation("carts", "post", "/merge"),
1263
+ addItem: operation("carts", "post", "/add-item"),
1264
+ updateItem: operation("carts", "post", "/update-item"),
1265
+ removeItem: operation("carts", "post", "/remove-item"),
1266
+ updateDiscountCodes: operation("carts", "post", "/update-discount-codes"),
1267
+ updateAttributes: operation("carts", "post", "/update-attributes"),
1268
+ clear: operation("carts", "post", "/clear")
1269
+ },
1270
+ paymentSessions: {
1271
+ create: operation("payment-sessions", "post", "/create"),
1272
+ retrieve: operation("payment-sessions", "post", "/retrieve"),
1273
+ cancel: operation("payment-sessions", "post", "/cancel"),
1274
+ server: {
1275
+ create: operation("payment-sessions", "post", "/server/create"),
1276
+ retrieve: operation("payment-sessions", "post", "/server/retrieve"),
1277
+ cancel: operation("payment-sessions", "post", "/server/cancel"),
1278
+ confirm: operation("payment-sessions", "post", "/server/confirm")
1279
+ },
1280
+ custom: {
1281
+ create: operation("orders", "post", "/custom-payment-sessions"),
1282
+ confirm: operation("orders", "post", "/custom-payment-sessions/confirm")
1056
1283
  }
1057
- if (reason === "rate_limit_exceeded") {
1058
- throw attachRequestId(createRateLimitError(errorMessage, retryAfter, data, errorMessage), requestId);
1284
+ },
1285
+ shippingPolicies: {
1286
+ calculate: operation("shipping-policies", "post", "/calculate")
1287
+ },
1288
+ discounts: {
1289
+ validate: operation("discounts", "post", "/validate")
1290
+ }
1291
+ };
1292
+ var MEMBERSHIP_ENDPOINT_OPERATIONS = {
1293
+ subscribe: operation(null, "post", "/memberships/subscribe"),
1294
+ cancel: operation(null, "post", "/memberships/:id/cancel"),
1295
+ me: operation(null, "get", "/memberships/me")
1296
+ };
1297
+ var EVENTS_ENDPOINT_OPERATIONS = {
1298
+ occurrences: {
1299
+ range: operation("event-occurrences", "get", "/range"),
1300
+ admissionAvailability: operation(
1301
+ "event-occurrences",
1302
+ "get",
1303
+ "/admission-availability"
1304
+ )
1305
+ }
1306
+ };
1307
+ function resolveOperationTemplate(descriptor) {
1308
+ return descriptor.collection ? `/api/${descriptor.collection}${descriptor.path}` : `/api${descriptor.path}`;
1309
+ }
1310
+ function resolveOperationPath(descriptor, options) {
1311
+ const path = resolveOperationTemplate(descriptor).replace(
1312
+ /:([A-Za-z][A-Za-z0-9_]*)/g,
1313
+ (_, key) => {
1314
+ const value = options?.pathParams?.[key];
1315
+ if (value === void 0) {
1316
+ throw new TypeError(`Missing path parameter: ${key}`);
1317
+ }
1318
+ return encodeURIComponent(value);
1059
1319
  }
1060
- if (reason === "not_found") {
1061
- throw attachRequestId(createNotFoundError(errorMessage, data, errorMessage), requestId);
1320
+ );
1321
+ const unresolved = path.match(/:([A-Za-z][A-Za-z0-9_]*)/);
1322
+ if (unresolved) {
1323
+ throw new TypeError(`Missing path parameter: ${unresolved[1]}`);
1324
+ }
1325
+ const query = options?.query?.toString().replace(/^\?/, "");
1326
+ return query ? `${path}?${query}` : path;
1327
+ }
1328
+ function resolveOperationMethod(descriptor) {
1329
+ return descriptor.method.toUpperCase();
1330
+ }
1331
+
1332
+ // src/core/api/endpoints.ts
1333
+ var endpoint = (method, path) => ({ method, path });
1334
+ var sharedEndpoint = (descriptor) => descriptor;
1335
+ function resolveOperationMethod2(descriptor) {
1336
+ return "collection" in descriptor ? resolveOperationMethod(descriptor) : descriptor.method;
1337
+ }
1338
+ function resolveOperationPath2(descriptor, options) {
1339
+ if ("collection" in descriptor) {
1340
+ return resolveOperationPath(descriptor, options);
1341
+ }
1342
+ const query = options?.query?.toString().replace(/^\?/, "");
1343
+ return query ? `${descriptor.path}?${query}` : descriptor.path;
1344
+ }
1345
+ var COMMERCE_ENDPOINTS = {
1346
+ products: {
1347
+ detail: endpoint("GET", "/api/products/detail"),
1348
+ detailCatalog: endpoint("GET", "/api/products/detail/catalog"),
1349
+ listingGroups: endpoint("GET", "/api/products/listing-groups"),
1350
+ listingGroupsCatalog: endpoint(
1351
+ "GET",
1352
+ "/api/products/listing-groups/catalog"
1353
+ ),
1354
+ listingGroupsQuery: endpoint("GET", "/api/products/listing-groups/query"),
1355
+ listingGroupsQueryCatalog: endpoint(
1356
+ "GET",
1357
+ "/api/products/listing-groups/query/catalog"
1358
+ ),
1359
+ stockCheck: endpoint("POST", "/api/products/stock-check"),
1360
+ stockSnapshot: endpoint("GET", "/api/products/stock"),
1361
+ upsert: endpoint("POST", "/api/products/upsert")
1362
+ },
1363
+ orders: {
1364
+ update: endpoint("POST", "/api/orders/update"),
1365
+ byPayment: endpoint("GET", "/api/orders/by-payment"),
1366
+ cancel: endpoint("POST", "/api/orders/cancel"),
1367
+ resolveCancelRefund: endpoint("POST", "/api/orders/resolve-cancel-refund"),
1368
+ createFulfillment: endpoint("POST", "/api/orders/create-fulfillment"),
1369
+ updateFulfillment: endpoint("POST", "/api/orders/update-fulfillment")
1370
+ },
1371
+ checkouts: {
1372
+ create: endpoint("POST", "/api/orders/checkout"),
1373
+ retrieve: endpoint("POST", "/api/checkouts/detail"),
1374
+ server: {
1375
+ create: endpoint("POST", "/api/orders/checkout"),
1376
+ retrieve: endpoint("POST", "/api/checkouts/detail"),
1377
+ query: endpoint("POST", "/api/checkouts/query")
1062
1378
  }
1063
- if (reason === "conflict") {
1064
- throw attachRequestId(createConflictError(errorMessage, data, errorMessage), requestId);
1379
+ },
1380
+ returns: {
1381
+ create: endpoint("POST", "/api/returns/create"),
1382
+ update: endpoint("POST", "/api/returns/update"),
1383
+ returnRefund: endpoint("POST", "/api/returns/return-refund")
1384
+ },
1385
+ fulfillmentOrders: {
1386
+ prepare: endpoint(
1387
+ "POST",
1388
+ "/api/fulfillment-orders/prepare-fulfillment-order"
1389
+ )
1390
+ },
1391
+ fulfillments: {
1392
+ bulkImport: endpoint("POST", "/api/fulfillments/bulk-import")
1393
+ },
1394
+ carts: {
1395
+ create: endpoint("POST", "/api/carts/create"),
1396
+ retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),
1397
+ mine: endpoint("POST", "/api/carts/mine"),
1398
+ merge: endpoint("POST", "/api/carts/merge"),
1399
+ server: {
1400
+ // Server credentials are an authorization lane, not a second Cart
1401
+ // transport. These must stay bound to the registered shared operations.
1402
+ create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),
1403
+ retrieve: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.retrieve),
1404
+ mine: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.mine),
1405
+ merge: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.merge),
1406
+ addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),
1407
+ updateItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.updateItem),
1408
+ removeItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.removeItem),
1409
+ updateDiscountCodes: sharedEndpoint(
1410
+ COMMERCE_ENDPOINT_OPERATIONS.carts.updateDiscountCodes
1411
+ ),
1412
+ updateAttributes: sharedEndpoint(
1413
+ COMMERCE_ENDPOINT_OPERATIONS.carts.updateAttributes
1414
+ ),
1415
+ clear: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.clear)
1416
+ },
1417
+ addItem: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.addItem),
1418
+ updateItem: endpoint("POST", "/api/carts/update-item"),
1419
+ removeItem: endpoint("POST", "/api/carts/remove-item"),
1420
+ updateDiscountCodes: endpoint("POST", "/api/carts/update-discount-codes"),
1421
+ updateAttributes: endpoint("POST", "/api/carts/update-attributes"),
1422
+ clear: endpoint("POST", "/api/carts/clear")
1423
+ },
1424
+ paymentSessions: {
1425
+ create: endpoint("POST", "/api/payment-sessions/create"),
1426
+ retrieve: endpoint("POST", "/api/payment-sessions/retrieve"),
1427
+ cancel: endpoint("POST", "/api/payment-sessions/cancel"),
1428
+ custom: {
1429
+ create: sharedEndpoint(
1430
+ COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.create
1431
+ ),
1432
+ confirm: sharedEndpoint(
1433
+ COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.custom.confirm
1434
+ )
1435
+ },
1436
+ server: {
1437
+ create: endpoint("POST", "/api/payment-sessions/server/create"),
1438
+ retrieve: endpoint("POST", "/api/payment-sessions/server/retrieve"),
1439
+ cancel: endpoint("POST", "/api/payment-sessions/server/cancel"),
1440
+ confirm: endpoint("POST", "/api/payment-sessions/server/confirm")
1065
1441
  }
1066
- throw attachRequestId(
1067
- createApiError(errorMessage, response.status, data, errorMessage, "An error occurred while processing the request."),
1068
- requestId
1069
- );
1442
+ },
1443
+ shippingPolicies: {
1444
+ calculate: endpoint("POST", "/api/shipping-policies/calculate")
1070
1445
  }
1071
- return data;
1446
+ };
1447
+ function isCommerceEndpointDescriptor(value) {
1448
+ if (!value || typeof value !== "object") return false;
1449
+ const candidate = value;
1450
+ return typeof candidate.method === "string" && typeof candidate.path === "string";
1451
+ }
1452
+ function flattenEndpointPaths(value) {
1453
+ if (isCommerceEndpointDescriptor(value)) return [resolveOperationPath2(value)];
1454
+ if (!value || typeof value !== "object") return [];
1455
+ return Object.values(value).flatMap((entry) => flattenEndpointPaths(entry));
1456
+ }
1457
+ function flattenEndpointDescriptors(value) {
1458
+ if (isCommerceEndpointDescriptor(value)) return [value];
1459
+ if (!value || typeof value !== "object") return [];
1460
+ return Object.values(value).flatMap(
1461
+ (entry) => flattenEndpointDescriptors(entry)
1462
+ );
1072
1463
  }
1464
+ var COMMERCE_ENDPOINT_PATHS = flattenEndpointPaths(COMMERCE_ENDPOINTS);
1465
+ var COMMERCE_ENDPOINT_DESCRIPTORS = flattenEndpointDescriptors(COMMERCE_ENDPOINTS);
1466
+ var MEMBERSHIP_ENDPOINTS = {
1467
+ subscribe: "/api/memberships/subscribe",
1468
+ cancel: (id) => `/api/memberships/${id}/cancel`,
1469
+ me: "/api/memberships/me"
1470
+ };
1471
+ var MEMBERSHIP_ENDPOINT_PATHS = [
1472
+ MEMBERSHIP_ENDPOINTS.subscribe,
1473
+ MEMBERSHIP_ENDPOINTS.cancel(":id"),
1474
+ MEMBERSHIP_ENDPOINTS.me
1475
+ ];
1073
1476
 
1074
1477
  // src/core/api/customer-scoped-api.ts
1075
- var CustomerScopedApi = class {
1478
+ var CustomerScopedTransport = class {
1076
1479
  constructor(apiName, options) {
1077
1480
  if (options.requiresCredential !== false && !options.secretKey && !options.customerToken) {
1078
1481
  throw createConfigError(
@@ -1090,10 +1493,10 @@ var CustomerScopedApi = class {
1090
1493
  this.onUnauthorized = options.onUnauthorized;
1091
1494
  this.onRequestId = options.onRequestId;
1092
1495
  }
1093
- async request(endpoint, options) {
1496
+ async request(endpoint2, options) {
1094
1497
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1095
1498
  try {
1096
- const response = await httpFetch(endpoint, {
1499
+ const response = await httpFetch(endpoint2, {
1097
1500
  method: options.method,
1098
1501
  apiUrl: this.apiUrl,
1099
1502
  publishableKey: this.publishableKey,
@@ -1103,10 +1506,13 @@ var CustomerScopedApi = class {
1103
1506
  ...options.body !== void 0 && {
1104
1507
  body: JSON.stringify(options.body)
1105
1508
  },
1106
- ...options.headers && { headers: options.headers }
1509
+ ...options.headers && { headers: options.headers },
1510
+ ...options.errorFamily && { errorFamily: options.errorFamily }
1107
1511
  });
1108
1512
  this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1109
- return parseApiResponse(response, endpoint);
1513
+ return parseApiResponse(response, endpoint2, {
1514
+ errorFamily: options.errorFamily
1515
+ });
1110
1516
  } catch (err) {
1111
1517
  const id = err instanceof SDKError ? err.requestId ?? null : null;
1112
1518
  this.onRequestId?.(id);
@@ -1114,6 +1520,26 @@ var CustomerScopedApi = class {
1114
1520
  }
1115
1521
  }
1116
1522
  };
1523
+ var CustomerScopedApi = class {
1524
+ constructor(apiName, options) {
1525
+ this.transport = new CustomerScopedTransport(apiName, options);
1526
+ }
1527
+ requestEndpoint(endpoint2, body, options) {
1528
+ return this.transport.request(resolveOperationPath2(endpoint2, options), {
1529
+ method: resolveOperationMethod2(endpoint2),
1530
+ body,
1531
+ headers: options?.headers
1532
+ });
1533
+ }
1534
+ };
1535
+ var RawCustomerScopedApi = class {
1536
+ constructor(apiName, options) {
1537
+ this.transport = new CustomerScopedTransport(apiName, options);
1538
+ }
1539
+ request(endpoint2, options) {
1540
+ return this.transport.request(endpoint2, options);
1541
+ }
1542
+ };
1117
1543
 
1118
1544
  // src/core/community/community-client.ts
1119
1545
  var DEFAULT_POST_LIST_SORT = "-lastActivityAt";
@@ -1124,7 +1550,7 @@ function unwrapPayloadDoc(value) {
1124
1550
  }
1125
1551
  return value;
1126
1552
  }
1127
- var CommunityClient = class extends CustomerScopedApi {
1553
+ var CommunityClient = class extends RawCustomerScopedApi {
1128
1554
  constructor(options) {
1129
1555
  super("CommunityClient", { ...options, requiresCredential: false });
1130
1556
  }
@@ -1168,11 +1594,11 @@ var CommunityClient = class extends CustomerScopedApi {
1168
1594
  if (params.page !== void 0) urlParams.set("page", String(params.page));
1169
1595
  return `/api/comments/public?${urlParams.toString()}`;
1170
1596
  }
1171
- async execute(endpoint, method, body) {
1172
- return this.request(endpoint, { method, body });
1597
+ async execute(endpoint2, method, body) {
1598
+ return this.request(endpoint2, { method, body });
1173
1599
  }
1174
- async executeDoc(endpoint, method, body) {
1175
- const response = await this.execute(endpoint, method, body);
1600
+ async executeDoc(endpoint2, method, body) {
1601
+ const response = await this.execute(endpoint2, method, body);
1176
1602
  return unwrapPayloadDoc(response);
1177
1603
  }
1178
1604
  createPost(params) {
@@ -1408,56 +1834,1538 @@ var CommunityClient = class extends CustomerScopedApi {
1408
1834
  body
1409
1835
  );
1410
1836
  }
1411
- };
1412
-
1413
- // src/core/content/content-client.ts
1414
- var PublicContentApi = class extends CustomerScopedApi {
1415
- get(endpoint) {
1416
- return this.request(endpoint, { method: "GET" });
1417
- }
1418
- };
1419
- function appendCommonParams(search, options, defaultSort) {
1420
- search.set("sort", options?.sort ?? defaultSort);
1421
- if (options?.page != null) search.set("page", String(options.page));
1422
- if (options?.limit != null) search.set("limit", String(options.limit));
1423
- }
1424
- function linksListPath(options) {
1425
- const search = new URLSearchParams();
1426
- appendCommonParams(search, options, "-publishedAt,-createdAt");
1427
- if (options?.categoryId) search.set("categoryId", options.categoryId);
1428
- if (options?.categorySlug) {
1429
- search.set("categorySlug", options.categorySlug);
1430
- }
1431
- if (options?.tagId) search.set("tagId", options.tagId);
1432
- if (options?.tagSlug) search.set("tagSlug", options.tagSlug);
1433
- if (options?.featured != null) search.set("featured", String(options.featured));
1434
- return `/api/links/storefront?${search}`;
1435
- }
1436
- function galleryItemsListPath(options) {
1437
- const search = new URLSearchParams();
1438
- appendCommonParams(search, options, "manual");
1439
- if (options?.galleryId) search.set("galleryId", options.galleryId);
1440
- if (options?.gallerySlug) search.set("gallerySlug", options.gallerySlug);
1441
- return `/api/gallery-items/storefront?${search}`;
1837
+ };
1838
+
1839
+ // src/core/content/content-client.ts
1840
+ var PublicContentApi = class extends RawCustomerScopedApi {
1841
+ get(endpoint2) {
1842
+ return this.request(endpoint2, { method: "GET" });
1843
+ }
1844
+ };
1845
+ function appendCommonParams(search, options, defaultSort) {
1846
+ search.set("sort", options?.sort ?? defaultSort);
1847
+ if (options?.page != null) search.set("page", String(options.page));
1848
+ if (options?.limit != null) search.set("limit", String(options.limit));
1849
+ }
1850
+ function linksListPath(options) {
1851
+ const search = new URLSearchParams();
1852
+ appendCommonParams(search, options, "-publishedAt,-createdAt");
1853
+ if (options?.categoryId) search.set("categoryId", options.categoryId);
1854
+ if (options?.categorySlug) {
1855
+ search.set("categorySlug", options.categorySlug);
1856
+ }
1857
+ if (options?.tagId) search.set("tagId", options.tagId);
1858
+ if (options?.tagSlug) search.set("tagSlug", options.tagSlug);
1859
+ if (options?.featured != null)
1860
+ search.set("featured", String(options.featured));
1861
+ return `/api/links/storefront?${search}`;
1862
+ }
1863
+ function galleryItemsListPath(options) {
1864
+ const search = new URLSearchParams();
1865
+ appendCommonParams(search, options, "manual");
1866
+ if (options?.galleryId) search.set("galleryId", options.galleryId);
1867
+ if (options?.gallerySlug) search.set("gallerySlug", options.gallerySlug);
1868
+ return `/api/gallery-items/storefront?${search}`;
1869
+ }
1870
+ var ContentClient = class {
1871
+ constructor(options) {
1872
+ const api = new PublicContentApi("ContentClient", {
1873
+ publishableKey: options.publishableKey,
1874
+ apiUrl: options.apiUrl,
1875
+ onRequestId: options.onRequestId,
1876
+ requiresCredential: false
1877
+ });
1878
+ this.links = {
1879
+ list: (params) => api.get(linksListPath(params))
1880
+ };
1881
+ this.galleryItems = {
1882
+ list: (params) => api.get(
1883
+ galleryItemsListPath(params)
1884
+ )
1885
+ };
1886
+ }
1887
+ };
1888
+
1889
+ // src/core/api/canonical-response.ts
1890
+ var CART_STATUSES = ["active", "completed", "abandoned"];
1891
+ var MAX_CART_LINE_QUANTITY = 99;
1892
+ var MAX_COMMERCE_SHORT_TEXT_LENGTH = 200;
1893
+ var MAX_COMMERCE_ADDRESS_LENGTH = 500;
1894
+ var MAX_COMMERCE_EMAIL_LENGTH = 254;
1895
+ var MAX_COMMERCE_PHONE_LENGTH = 32;
1896
+ var MAX_COMMERCE_POSTAL_CODE_LENGTH = 32;
1897
+ var MAX_COMMERCE_EXTENSION_VALUE_LENGTH = 500;
1898
+ var MAX_COMMERCE_RESOURCE_ID_LENGTH = 255;
1899
+ var MAX_COMMERCE_CAPABILITY_LENGTH = 512;
1900
+ var MAX_CART_DISCOUNT_CODE_LENGTH = 128;
1901
+ var ORDER_FINANCIAL_STATUSES = [
1902
+ "pending",
1903
+ "authorized",
1904
+ "expired",
1905
+ "partially_paid",
1906
+ "paid",
1907
+ "canceled",
1908
+ "partially_refunded",
1909
+ "refunded",
1910
+ "reconciliation_required"
1911
+ ];
1912
+ var ORDER_FULFILLMENT_STATUSES = [
1913
+ "unfulfilled",
1914
+ "in_progress",
1915
+ "on_hold",
1916
+ "partially_fulfilled",
1917
+ "shipped",
1918
+ "fulfilled",
1919
+ "canceled"
1920
+ ];
1921
+ var ORDER_RETURN_STATUSES = [
1922
+ "no_return",
1923
+ "return_requested",
1924
+ "in_progress",
1925
+ "returned"
1926
+ ];
1927
+ var ORDER_CONFIRMATION_STATUSES = ["unconfirmed", "confirmed"];
1928
+ var ORDER_PRIMARY_DISPLAY_STATUSES = [
1929
+ "pending",
1930
+ "paid",
1931
+ "canceled",
1932
+ "refunded",
1933
+ "preparing",
1934
+ "shipped",
1935
+ "delivered",
1936
+ "confirmed"
1937
+ ];
1938
+ var CHECKOUT_STATUSES = ["open", "placed", "abandoned"];
1939
+ var ABANDONED_REASONS = ["expired", "customer", "operator"];
1940
+ var PAYMENT_PROVIDERS = ["toss"];
1941
+ var PAYMENT_PROVIDER_STATUSES = [
1942
+ "requires_payment_method",
1943
+ "requires_action",
1944
+ "requires_confirmation",
1945
+ "initializing",
1946
+ "processing",
1947
+ "authorized",
1948
+ "canceling",
1949
+ "unknown",
1950
+ "captured",
1951
+ "failed",
1952
+ "canceled"
1953
+ ];
1954
+ var PAYMENT_FAILURE_REASONS = [
1955
+ "payment_declined",
1956
+ "authentication_failed",
1957
+ "authorization_expired",
1958
+ "payment_method_unavailable",
1959
+ "provider_terminal_failure",
1960
+ "unknown_provider_terminal_failure"
1961
+ ];
1962
+ var CART_WARNING_CODES = [
1963
+ "DISCOUNT_CODE_NOT_HONOURED",
1964
+ "DISCOUNT_CURRENTLY_INACTIVE",
1965
+ "DISCOUNT_CUSTOMER_NOT_ELIGIBLE",
1966
+ "DISCOUNT_CUSTOMER_USAGE_LIMIT_REACHED",
1967
+ "DISCOUNT_ELIGIBLE_CUSTOMER_MISSING",
1968
+ "DISCOUNT_NO_ENTITLED_LINE_ITEMS",
1969
+ "DISCOUNT_NO_ENTITLED_SHIPPING_LINES",
1970
+ "DISCOUNT_NOT_FOUND",
1971
+ "DISCOUNT_PURCHASE_NOT_IN_RANGE",
1972
+ "DISCOUNT_USAGE_LIMIT_REACHED",
1973
+ "MERCHANDISE_NOT_ENOUGH_STOCK",
1974
+ "MERCHANDISE_OUT_OF_STOCK"
1975
+ ];
1976
+ function invalidCanonicalResponse(resource, details) {
1977
+ throw createApiError(
1978
+ `Invalid canonical ${resource} response.`,
1979
+ 502,
1980
+ { resource, ...details },
1981
+ `The server returned an incompatible ${resource} response.`,
1982
+ "Verify that the Console commerce contract is deployed before using this SDK version."
1983
+ );
1984
+ }
1985
+ function fail(resource, path, expected) {
1986
+ invalidCanonicalResponse(resource, { path, expected });
1987
+ }
1988
+ function record(value, resource, path) {
1989
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1990
+ fail(resource, path, "object");
1991
+ }
1992
+ return value;
1993
+ }
1994
+ function exact(value, required, optional, resource, path) {
1995
+ for (const key of required) {
1996
+ if (!(key in value)) fail(resource, `${path}.${key}`, "required field");
1997
+ }
1998
+ const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
1999
+ const unexpected = Object.keys(value).find((key) => !allowed.has(key));
2000
+ if (unexpected) fail(resource, `${path}.${unexpected}`, "no unknown fields");
2001
+ }
2002
+ function string(value, resource, path) {
2003
+ if (typeof value !== "string" || value.length === 0) {
2004
+ fail(resource, path, "non-empty string");
2005
+ }
2006
+ return value;
2007
+ }
2008
+ function boundedString(value, maxLength, resource, path, allowEmpty = false) {
2009
+ if (typeof value !== "string" || !allowEmpty && value.length === 0 || value.length > maxLength) {
2010
+ fail(
2011
+ resource,
2012
+ path,
2013
+ `${allowEmpty ? "" : "non-empty "}string of at most ${maxLength} characters`
2014
+ );
2015
+ }
2016
+ return value;
2017
+ }
2018
+ function nullableString(value, resource, path) {
2019
+ if (value !== null && typeof value !== "string") {
2020
+ fail(resource, path, "string or null");
2021
+ }
2022
+ }
2023
+ function cartLineQuantity(value, resource, path) {
2024
+ const quantity = positiveInteger(value, resource, path);
2025
+ if (quantity > MAX_CART_LINE_QUANTITY) {
2026
+ fail(resource, path, `integer between 1 and ${MAX_CART_LINE_QUANTITY}`);
2027
+ }
2028
+ return quantity;
2029
+ }
2030
+ function boolean(value, resource, path) {
2031
+ if (typeof value !== "boolean") fail(resource, path, "boolean");
2032
+ }
2033
+ function safeMinor(value, resource, path) {
2034
+ if (!Number.isSafeInteger(value) || value < 0) {
2035
+ fail(resource, path, "non-negative safe integer");
2036
+ }
2037
+ return value;
2038
+ }
2039
+ function positiveInteger(value, resource, path) {
2040
+ if (!Number.isSafeInteger(value) || value <= 0) {
2041
+ fail(resource, path, "positive safe integer");
2042
+ }
2043
+ return value;
2044
+ }
2045
+ function enumValue(value, values, resource, path) {
2046
+ if (typeof value !== "string" || !values.includes(value)) {
2047
+ fail(resource, path, values.join(" | "));
2048
+ }
2049
+ return value;
2050
+ }
2051
+ function timestamp(value, resource, path) {
2052
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T.*(?:Z|[+-]\d{2}:\d{2})$/.test(value) || !Number.isFinite(Date.parse(value))) {
2053
+ fail(resource, path, "ISO 8601 timestamp with offset");
2054
+ }
2055
+ }
2056
+ function currency(value, resource, path) {
2057
+ if (typeof value !== "string" || !/^[A-Z]{3}$/.test(value)) {
2058
+ fail(resource, path, "three-letter uppercase currency code");
2059
+ }
2060
+ }
2061
+ function array(value, resource, path) {
2062
+ if (!Array.isArray(value)) fail(resource, path, "array");
2063
+ return value;
2064
+ }
2065
+ function optionalNullableNumber(value, resource, path) {
2066
+ if (value !== void 0 && value !== null && typeof value !== "number") {
2067
+ fail(resource, path, "number or null");
2068
+ }
2069
+ }
2070
+ function validateMediaSize(value, resource, path) {
2071
+ const item = record(value, resource, path);
2072
+ exact(
2073
+ item,
2074
+ [],
2075
+ ["width", "height", "mimeType", "filename", "url"],
2076
+ resource,
2077
+ path
2078
+ );
2079
+ optionalNullableNumber(item.width, resource, `${path}.width`);
2080
+ optionalNullableNumber(item.height, resource, `${path}.height`);
2081
+ for (const key of ["mimeType", "filename", "url"]) {
2082
+ if (item[key] !== void 0)
2083
+ nullableString(item[key], resource, `${path}.${key}`);
2084
+ }
2085
+ }
2086
+ function validateMedia(value, resource, path) {
2087
+ if (typeof value === "string") return;
2088
+ const media = record(value, resource, path);
2089
+ exact(
2090
+ media,
2091
+ [],
2092
+ ["id", "alt", "width", "height", "mimeType", "filename", "url", "sizes"],
2093
+ resource,
2094
+ path
2095
+ );
2096
+ if (media.id !== void 0 && media.id !== null && typeof media.id !== "string" && typeof media.id !== "number") {
2097
+ fail(resource, `${path}.id`, "string, number, or null");
2098
+ }
2099
+ for (const key of ["alt", "mimeType", "filename", "url"]) {
2100
+ if (media[key] !== void 0)
2101
+ nullableString(media[key], resource, `${path}.${key}`);
2102
+ }
2103
+ optionalNullableNumber(media.width, resource, `${path}.width`);
2104
+ optionalNullableNumber(media.height, resource, `${path}.height`);
2105
+ if (media.sizes !== void 0) {
2106
+ const sizes = record(media.sizes, resource, `${path}.sizes`);
2107
+ Object.entries(sizes).forEach(
2108
+ ([key, size]) => validateMediaSize(size, resource, `${path}.sizes.${key}`)
2109
+ );
2110
+ }
2111
+ }
2112
+ function validateReference(value, resource, path) {
2113
+ const ref = record(value, resource, path);
2114
+ exact(ref, ["id", "title", "handle", "image"], [], resource, path);
2115
+ string(ref.id, resource, `${path}.id`);
2116
+ string(ref.title, resource, `${path}.title`);
2117
+ if (ref.handle !== null) string(ref.handle, resource, `${path}.handle`);
2118
+ if (ref.image !== null) validateMedia(ref.image, resource, `${path}.image`);
2119
+ }
2120
+ function validateAdmission(value, resource, path) {
2121
+ const admission = record(value, resource, path);
2122
+ exact(
2123
+ admission,
2124
+ ["eventId", "occurrenceId", "admissionTypeId"],
2125
+ [],
2126
+ resource,
2127
+ path
2128
+ );
2129
+ string(admission.eventId, resource, `${path}.eventId`);
2130
+ string(admission.occurrenceId, resource, `${path}.occurrenceId`);
2131
+ string(admission.admissionTypeId, resource, `${path}.admissionTypeId`);
2132
+ }
2133
+ function compareAdmissions(left, right) {
2134
+ for (const field of ["eventId", "occurrenceId", "admissionTypeId"]) {
2135
+ if (left[field] < right[field]) return -1;
2136
+ if (left[field] > right[field]) return 1;
2137
+ }
2138
+ return 0;
2139
+ }
2140
+ function validateAdmissions(value, resource, path) {
2141
+ const admissions = array(value, resource, path);
2142
+ if (admissions.length > 32) fail(resource, path, "at most 32 admissions");
2143
+ let prior;
2144
+ admissions.forEach((admission, index) => {
2145
+ validateAdmission(admission, resource, `${path}[${index}]`);
2146
+ const item = admission;
2147
+ const comparison = prior ? compareAdmissions(item, prior) : void 0;
2148
+ if (comparison !== void 0 && comparison <= 0) {
2149
+ fail(resource, `${path}[${index}]`, "unique canonical-sorted admissions");
2150
+ }
2151
+ prior = item;
2152
+ });
2153
+ }
2154
+ function validateAttributes(value, resource, path) {
2155
+ const attributes = array(value, resource, path);
2156
+ if (attributes.length > 50) fail(resource, path, "at most 50 attributes");
2157
+ const keys = /* @__PURE__ */ new Set();
2158
+ attributes.forEach((value2, index) => {
2159
+ const itemPath = `${path}[${index}]`;
2160
+ const attribute = record(value2, resource, itemPath);
2161
+ exact(attribute, ["key", "value"], [], resource, itemPath);
2162
+ const key = string(attribute.key, resource, `${itemPath}.key`);
2163
+ if (key.length > 40 || key.startsWith("__") || keys.has(key)) {
2164
+ fail(
2165
+ resource,
2166
+ `${itemPath}.key`,
2167
+ "unique, non-reserved key of at most 40 characters"
2168
+ );
2169
+ }
2170
+ keys.add(key);
2171
+ if (typeof attribute.value !== "string" || attribute.value.length > 500) {
2172
+ fail(resource, `${itemPath}.value`, "string of at most 500 characters");
2173
+ }
2174
+ });
2175
+ }
2176
+ function validateCustomer(value, resource, path) {
2177
+ const customer = record(value, resource, path);
2178
+ exact(customer, ["email"], ["name", "phone"], resource, path);
2179
+ const email = boundedString(
2180
+ customer.email,
2181
+ MAX_COMMERCE_EMAIL_LENGTH,
2182
+ resource,
2183
+ `${path}.email`
2184
+ );
2185
+ if (!/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$/.test(
2186
+ email
2187
+ )) {
2188
+ fail(resource, `${path}.email`, "email address");
2189
+ }
2190
+ if (customer.name !== void 0)
2191
+ boundedString(
2192
+ customer.name,
2193
+ MAX_COMMERCE_SHORT_TEXT_LENGTH,
2194
+ resource,
2195
+ `${path}.name`
2196
+ );
2197
+ if (customer.phone !== void 0)
2198
+ boundedString(
2199
+ customer.phone,
2200
+ MAX_COMMERCE_PHONE_LENGTH,
2201
+ resource,
2202
+ `${path}.phone`
2203
+ );
2204
+ }
2205
+ function validateShippingAddress(value, resource, path) {
2206
+ const address = record(value, resource, path);
2207
+ exact(
2208
+ address,
2209
+ ["recipientName", "phone", "postalCode", "address", "detailAddress"],
2210
+ ["countryCode", "regionCode", "deliveryMessage"],
2211
+ resource,
2212
+ path
2213
+ );
2214
+ boundedString(
2215
+ address.recipientName,
2216
+ MAX_COMMERCE_SHORT_TEXT_LENGTH,
2217
+ resource,
2218
+ `${path}.recipientName`
2219
+ );
2220
+ boundedString(
2221
+ address.phone,
2222
+ MAX_COMMERCE_PHONE_LENGTH,
2223
+ resource,
2224
+ `${path}.phone`
2225
+ );
2226
+ boundedString(
2227
+ address.postalCode,
2228
+ MAX_COMMERCE_POSTAL_CODE_LENGTH,
2229
+ resource,
2230
+ `${path}.postalCode`
2231
+ );
2232
+ for (const key of ["address", "detailAddress"]) {
2233
+ boundedString(
2234
+ address[key],
2235
+ MAX_COMMERCE_ADDRESS_LENGTH,
2236
+ resource,
2237
+ `${path}.${key}`
2238
+ );
2239
+ }
2240
+ if (address.countryCode !== void 0) {
2241
+ if (typeof address.countryCode !== "string" || address.countryCode.trim().length !== 2) {
2242
+ fail(resource, `${path}.countryCode`, "two-letter country code");
2243
+ }
2244
+ }
2245
+ if (address.regionCode !== void 0) {
2246
+ if (typeof address.regionCode !== "string" || address.regionCode.trim().length === 0 || address.regionCode.trim().length > 64) {
2247
+ fail(
2248
+ resource,
2249
+ `${path}.regionCode`,
2250
+ "trimmed string of at most 64 characters"
2251
+ );
2252
+ }
2253
+ }
2254
+ if (address.deliveryMessage !== void 0) {
2255
+ boundedString(
2256
+ address.deliveryMessage,
2257
+ MAX_COMMERCE_EXTENSION_VALUE_LENGTH,
2258
+ resource,
2259
+ `${path}.deliveryMessage`,
2260
+ true
2261
+ );
2262
+ }
2263
+ }
2264
+ function validateOrderReference(value, resource, path) {
2265
+ const order = record(value, resource, path);
2266
+ exact(order, ["id", "orderNumber"], [], resource, path);
2267
+ string(order.id, resource, `${path}.id`);
2268
+ string(order.orderNumber, resource, `${path}.orderNumber`);
2269
+ }
2270
+ function validateIntegrationMetadata(value, resource, path) {
2271
+ const metadata = record(value, resource, path);
2272
+ if (Object.keys(metadata).length > 50)
2273
+ fail(resource, path, "at most 50 entries");
2274
+ Object.entries(metadata).forEach(([key, entry]) => {
2275
+ if (!key || key.length > 40 || key.includes("[") || key.includes("]")) {
2276
+ fail(resource, `${path}.${key}`, "valid metadata key");
2277
+ }
2278
+ if (typeof entry !== "string" || entry.length > 500) {
2279
+ fail(resource, `${path}.${key}`, "string of at most 500 characters");
2280
+ }
2281
+ });
2282
+ }
2283
+ function validateCartItem(value, resource, path) {
2284
+ const item = record(value, resource, path);
2285
+ exact(
2286
+ item,
2287
+ [
2288
+ "id",
2289
+ "product",
2290
+ "variant",
2291
+ "admissions",
2292
+ "quantity",
2293
+ "unitPriceMinor",
2294
+ "discountMinor",
2295
+ "estimatedLineTotalMinor",
2296
+ "requiresShipping"
2297
+ ],
2298
+ [],
2299
+ resource,
2300
+ path
2301
+ );
2302
+ string(item.id, resource, `${path}.id`);
2303
+ validateReference(item.product, resource, `${path}.product`);
2304
+ validateReference(item.variant, resource, `${path}.variant`);
2305
+ validateAdmissions(item.admissions, resource, `${path}.admissions`);
2306
+ cartLineQuantity(item.quantity, resource, `${path}.quantity`);
2307
+ const unitPrice = safeMinor(
2308
+ item.unitPriceMinor,
2309
+ resource,
2310
+ `${path}.unitPriceMinor`
2311
+ );
2312
+ const discount = safeMinor(
2313
+ item.discountMinor,
2314
+ resource,
2315
+ `${path}.discountMinor`
2316
+ );
2317
+ const estimatedLineTotal = safeMinor(
2318
+ item.estimatedLineTotalMinor,
2319
+ resource,
2320
+ `${path}.estimatedLineTotalMinor`
2321
+ );
2322
+ const quantity = item.quantity;
2323
+ const expectedLineTotal = BigInt(unitPrice) * BigInt(quantity) - BigInt(discount);
2324
+ if (expectedLineTotal < 0n || BigInt(estimatedLineTotal) !== expectedLineTotal) {
2325
+ fail(
2326
+ resource,
2327
+ `${path}.estimatedLineTotalMinor`,
2328
+ "unitPriceMinor * quantity - discountMinor"
2329
+ );
2330
+ }
2331
+ boolean(item.requiresShipping, resource, `${path}.requiresShipping`);
2332
+ }
2333
+ function validatePublicCart(value, resource = "Cart") {
2334
+ const cart = record(value, resource, "$");
2335
+ exact(
2336
+ cart,
2337
+ [
2338
+ "id",
2339
+ "status",
2340
+ "revision",
2341
+ "currency",
2342
+ "market",
2343
+ "subtotalMinor",
2344
+ "discountMinor",
2345
+ "estimatedTotalMinor",
2346
+ "discountCodes",
2347
+ "attributes",
2348
+ "items",
2349
+ "expiresAt",
2350
+ "createdAt",
2351
+ "updatedAt"
2352
+ ],
2353
+ [],
2354
+ resource,
2355
+ "$"
2356
+ );
2357
+ string(cart.id, resource, "$.id");
2358
+ enumValue(cart.status, CART_STATUSES, resource, "$.status");
2359
+ safeMinor(cart.revision, resource, "$.revision");
2360
+ currency(cart.currency, resource, "$.currency");
2361
+ const market = record(cart.market, resource, "$.market");
2362
+ exact(market, ["id", "handle", "name"], [], resource, "$.market");
2363
+ for (const key of ["id", "handle", "name"])
2364
+ string(market[key], resource, `$.market.${key}`);
2365
+ const subtotal = safeMinor(cart.subtotalMinor, resource, "$.subtotalMinor");
2366
+ const discount = safeMinor(cart.discountMinor, resource, "$.discountMinor");
2367
+ const estimatedTotal = safeMinor(
2368
+ cart.estimatedTotalMinor,
2369
+ resource,
2370
+ "$.estimatedTotalMinor"
2371
+ );
2372
+ array(cart.discountCodes, resource, "$.discountCodes").forEach(
2373
+ (value2, index) => {
2374
+ const itemPath = `$.discountCodes[${index}]`;
2375
+ const code = record(value2, resource, itemPath);
2376
+ exact(code, ["code", "applicable"], [], resource, itemPath);
2377
+ boundedString(
2378
+ code.code,
2379
+ MAX_CART_DISCOUNT_CODE_LENGTH,
2380
+ resource,
2381
+ `${itemPath}.code`
2382
+ );
2383
+ boolean(code.applicable, resource, `${itemPath}.applicable`);
2384
+ }
2385
+ );
2386
+ validateAttributes(cart.attributes, resource, "$.attributes");
2387
+ const items = array(cart.items, resource, "$.items");
2388
+ items.forEach(
2389
+ (item, index) => validateCartItem(item, resource, `$.items[${index}]`)
2390
+ );
2391
+ const expectedSubtotal = items.reduce((total, value2) => {
2392
+ const item = value2;
2393
+ return total + BigInt(item.unitPriceMinor) * BigInt(item.quantity);
2394
+ }, 0n);
2395
+ const expectedDiscount = items.reduce((total, value2) => {
2396
+ const item = value2;
2397
+ return total + BigInt(item.discountMinor);
2398
+ }, 0n);
2399
+ if (BigInt(subtotal) !== expectedSubtotal) {
2400
+ fail(resource, "$.subtotalMinor", "sum of undiscounted cart line totals");
2401
+ }
2402
+ if (BigInt(discount) !== expectedDiscount) {
2403
+ fail(resource, "$.discountMinor", "sum of cart line discounts");
2404
+ }
2405
+ if (expectedSubtotal - BigInt(discount) < 0n || BigInt(estimatedTotal) !== expectedSubtotal - BigInt(discount)) {
2406
+ fail(resource, "$.estimatedTotalMinor", "subtotalMinor - discountMinor");
2407
+ }
2408
+ timestamp(cart.expiresAt, resource, "$.expiresAt");
2409
+ timestamp(cart.createdAt, resource, "$.createdAt");
2410
+ timestamp(cart.updatedAt, resource, "$.updatedAt");
2411
+ return value;
2412
+ }
2413
+ function validateWarnings(value, resource, path) {
2414
+ array(value, resource, path).forEach((value2, index) => {
2415
+ const itemPath = `${path}[${index}]`;
2416
+ const warning = record(value2, resource, itemPath);
2417
+ exact(warning, ["code", "message", "target"], [], resource, itemPath);
2418
+ enumValue(warning.code, CART_WARNING_CODES, resource, `${itemPath}.code`);
2419
+ string(warning.message, resource, `${itemPath}.message`);
2420
+ string(warning.target, resource, `${itemPath}.target`);
2421
+ });
2422
+ }
2423
+ function validateCartMutationResult(value) {
2424
+ const result = record(value, "Cart mutation result", "$");
2425
+ exact(result, ["cart", "warnings"], [], "Cart mutation result", "$");
2426
+ validatePublicCart(result.cart);
2427
+ validateWarnings(result.warnings, "Cart mutation result", "$.warnings");
2428
+ return value;
2429
+ }
2430
+ function validateCreateCartResult(value) {
2431
+ const result = record(value, "Cart create result", "$");
2432
+ exact(
2433
+ result,
2434
+ ["cart", "warnings", "cartToken"],
2435
+ [],
2436
+ "Cart create result",
2437
+ "$"
2438
+ );
2439
+ const cart = record(result.cart, "Cart create result", "$.cart");
2440
+ validatePublicCart(cart);
2441
+ if (cart.revision !== 0) {
2442
+ fail("Cart create result", "$.cart.revision", "0 for a newly created Cart");
2443
+ }
2444
+ validateWarnings(result.warnings, "Cart create result", "$.warnings");
2445
+ boundedString(
2446
+ result.cartToken,
2447
+ MAX_COMMERCE_CAPABILITY_LENGTH,
2448
+ "Cart create result",
2449
+ "$.cartToken"
2450
+ );
2451
+ return value;
2452
+ }
2453
+ function validateCartMineResult(value) {
2454
+ const result = record(value, "Cart mine result", "$");
2455
+ exact(result, ["cart", "cartToken"], [], "Cart mine result", "$");
2456
+ if (result.cart === null || result.cartToken === null) {
2457
+ if (result.cart !== null || result.cartToken !== null) {
2458
+ fail("Cart mine result", "$", "cart and cartToken must both be null");
2459
+ }
2460
+ } else {
2461
+ validatePublicCart(result.cart);
2462
+ boundedString(
2463
+ result.cartToken,
2464
+ MAX_COMMERCE_CAPABILITY_LENGTH,
2465
+ "Cart mine result",
2466
+ "$.cartToken"
2467
+ );
2468
+ }
2469
+ return value;
2470
+ }
2471
+ function validateCartMergeResult(value) {
2472
+ const result = record(value, "Cart merge result", "$");
2473
+ exact(
2474
+ result,
2475
+ ["cart", "warnings", "cartToken", "resolution", "merged", "claimed"],
2476
+ [],
2477
+ "Cart merge result",
2478
+ "$"
2479
+ );
2480
+ validatePublicCart(result.cart);
2481
+ validateWarnings(result.warnings, "Cart merge result", "$.warnings");
2482
+ boundedString(
2483
+ result.cartToken,
2484
+ MAX_COMMERCE_CAPABILITY_LENGTH,
2485
+ "Cart merge result",
2486
+ "$.cartToken"
2487
+ );
2488
+ const resolution = enumValue(
2489
+ result.resolution,
2490
+ ["unchanged", "claimed", "merged"],
2491
+ "Cart merge result",
2492
+ "$.resolution"
2493
+ );
2494
+ boolean(result.merged, "Cart merge result", "$.merged");
2495
+ boolean(result.claimed, "Cart merge result", "$.claimed");
2496
+ const expected = resolution === "merged" ? [true, false] : resolution === "claimed" ? [false, true] : [false, false];
2497
+ if (result.merged !== expected[0] || result.claimed !== expected[1]) {
2498
+ fail("Cart merge result", "$", "resolution-consistent merged/claimed flags");
2499
+ }
2500
+ return value;
2501
+ }
2502
+ function validatePublicOrderItem(value, resource, path) {
2503
+ const item = record(value, resource, path);
2504
+ exact(
2505
+ item,
2506
+ [
2507
+ "id",
2508
+ "product",
2509
+ "variant",
2510
+ "productTitle",
2511
+ "variantTitle",
2512
+ "sku",
2513
+ "admissions",
2514
+ "quantity",
2515
+ "unitPriceMinor",
2516
+ "discountMinor",
2517
+ "lineTotalMinor",
2518
+ "requiresShipping"
2519
+ ],
2520
+ [],
2521
+ resource,
2522
+ path
2523
+ );
2524
+ string(item.id, resource, `${path}.id`);
2525
+ if (item.product !== null) {
2526
+ validateReference(item.product, resource, `${path}.product`);
2527
+ }
2528
+ if (item.variant !== null) {
2529
+ validateReference(item.variant, resource, `${path}.variant`);
2530
+ }
2531
+ string(item.productTitle, resource, `${path}.productTitle`);
2532
+ nullableString(item.variantTitle, resource, `${path}.variantTitle`);
2533
+ nullableString(item.sku, resource, `${path}.sku`);
2534
+ validateAdmissions(item.admissions, resource, `${path}.admissions`);
2535
+ const quantity = positiveInteger(item.quantity, resource, `${path}.quantity`);
2536
+ const unitPrice = safeMinor(
2537
+ item.unitPriceMinor,
2538
+ resource,
2539
+ `${path}.unitPriceMinor`
2540
+ );
2541
+ const discount = safeMinor(
2542
+ item.discountMinor,
2543
+ resource,
2544
+ `${path}.discountMinor`
2545
+ );
2546
+ const lineTotal = safeMinor(
2547
+ item.lineTotalMinor,
2548
+ resource,
2549
+ `${path}.lineTotalMinor`
2550
+ );
2551
+ const expected = BigInt(unitPrice) * BigInt(quantity) - BigInt(discount);
2552
+ if (expected < 0n || BigInt(lineTotal) !== expected) {
2553
+ fail(
2554
+ resource,
2555
+ `${path}.lineTotalMinor`,
2556
+ "unitPriceMinor * quantity - discountMinor"
2557
+ );
2558
+ }
2559
+ boolean(item.requiresShipping, resource, `${path}.requiresShipping`);
2560
+ }
2561
+ function validatePublicOrderAt(value, resource, path) {
2562
+ const order = record(value, resource, path);
2563
+ exact(
2564
+ order,
2565
+ [
2566
+ "id",
2567
+ "orderNumber",
2568
+ "amounts",
2569
+ "market",
2570
+ "customerSnapshot",
2571
+ "shippingAddress",
2572
+ "attributes",
2573
+ "items",
2574
+ "financialStatus",
2575
+ "fulfillmentStatus",
2576
+ "returnStatus",
2577
+ "confirmationStatus",
2578
+ "primaryDisplayStatus",
2579
+ "placedAt",
2580
+ "createdAt",
2581
+ "updatedAt"
2582
+ ],
2583
+ [],
2584
+ resource,
2585
+ path
2586
+ );
2587
+ string(order.id, resource, `${path}.id`);
2588
+ string(order.orderNumber, resource, `${path}.orderNumber`);
2589
+ const amounts = record(order.amounts, resource, `${path}.amounts`);
2590
+ exact(
2591
+ amounts,
2592
+ [
2593
+ "currency",
2594
+ "subtotalMinor",
2595
+ "shippingMinor",
2596
+ "discountMinor",
2597
+ "totalMinor",
2598
+ "refundedMinor",
2599
+ "currentTotalMinor"
2600
+ ],
2601
+ [],
2602
+ resource,
2603
+ `${path}.amounts`
2604
+ );
2605
+ currency(amounts.currency, resource, `${path}.amounts.currency`);
2606
+ const subtotal = safeMinor(
2607
+ amounts.subtotalMinor,
2608
+ resource,
2609
+ `${path}.amounts.subtotalMinor`
2610
+ );
2611
+ const shipping = safeMinor(
2612
+ amounts.shippingMinor,
2613
+ resource,
2614
+ `${path}.amounts.shippingMinor`
2615
+ );
2616
+ const discount = safeMinor(
2617
+ amounts.discountMinor,
2618
+ resource,
2619
+ `${path}.amounts.discountMinor`
2620
+ );
2621
+ const total = safeMinor(
2622
+ amounts.totalMinor,
2623
+ resource,
2624
+ `${path}.amounts.totalMinor`
2625
+ );
2626
+ const refunded = safeMinor(
2627
+ amounts.refundedMinor,
2628
+ resource,
2629
+ `${path}.amounts.refundedMinor`
2630
+ );
2631
+ const current = safeMinor(
2632
+ amounts.currentTotalMinor,
2633
+ resource,
2634
+ `${path}.amounts.currentTotalMinor`
2635
+ );
2636
+ const expectedTotal = BigInt(subtotal) + BigInt(shipping) - BigInt(discount);
2637
+ if (expectedTotal < 0n || BigInt(total) !== expectedTotal) {
2638
+ fail(
2639
+ resource,
2640
+ `${path}.amounts.totalMinor`,
2641
+ "subtotalMinor + shippingMinor - discountMinor"
2642
+ );
2643
+ }
2644
+ if (BigInt(total) - BigInt(refunded) < 0n || current !== total - refunded) {
2645
+ fail(
2646
+ resource,
2647
+ `${path}.amounts.currentTotalMinor`,
2648
+ "totalMinor - refundedMinor"
2649
+ );
2650
+ }
2651
+ if (order.market !== null) {
2652
+ const market = record(order.market, resource, `${path}.market`);
2653
+ exact(market, ["id", "handle", "name"], [], resource, `${path}.market`);
2654
+ for (const key of ["id", "handle", "name"]) {
2655
+ string(market[key], resource, `${path}.market.${key}`);
2656
+ }
2657
+ }
2658
+ validateCustomer(order.customerSnapshot, resource, `${path}.customerSnapshot`);
2659
+ if (order.shippingAddress !== null) {
2660
+ validateShippingAddress(
2661
+ order.shippingAddress,
2662
+ resource,
2663
+ `${path}.shippingAddress`
2664
+ );
2665
+ }
2666
+ validateAttributes(order.attributes, resource, `${path}.attributes`);
2667
+ const items = array(order.items, resource, `${path}.items`);
2668
+ if (items.length === 0) fail(resource, `${path}.items`, "non-empty array");
2669
+ items.forEach(
2670
+ (item, index) => validatePublicOrderItem(item, resource, `${path}.items[${index}]`)
2671
+ );
2672
+ const expectedSubtotal = items.reduce((sum, value2) => {
2673
+ const item = value2;
2674
+ return sum + BigInt(item.unitPriceMinor) * BigInt(item.quantity);
2675
+ }, 0n);
2676
+ const expectedDiscount = items.reduce((sum, value2) => {
2677
+ const item = value2;
2678
+ return sum + BigInt(item.discountMinor);
2679
+ }, 0n);
2680
+ if (BigInt(subtotal) !== expectedSubtotal) {
2681
+ fail(resource, `${path}.amounts.subtotalMinor`, "sum of line subtotals");
2682
+ }
2683
+ if (BigInt(discount) !== expectedDiscount) {
2684
+ fail(resource, `${path}.amounts.discountMinor`, "sum of line discounts");
2685
+ }
2686
+ enumValue(
2687
+ order.financialStatus,
2688
+ ORDER_FINANCIAL_STATUSES,
2689
+ resource,
2690
+ `${path}.financialStatus`
2691
+ );
2692
+ enumValue(
2693
+ order.fulfillmentStatus,
2694
+ ORDER_FULFILLMENT_STATUSES,
2695
+ resource,
2696
+ `${path}.fulfillmentStatus`
2697
+ );
2698
+ enumValue(
2699
+ order.returnStatus,
2700
+ ORDER_RETURN_STATUSES,
2701
+ resource,
2702
+ `${path}.returnStatus`
2703
+ );
2704
+ enumValue(
2705
+ order.confirmationStatus,
2706
+ ORDER_CONFIRMATION_STATUSES,
2707
+ resource,
2708
+ `${path}.confirmationStatus`
2709
+ );
2710
+ enumValue(
2711
+ order.primaryDisplayStatus,
2712
+ ORDER_PRIMARY_DISPLAY_STATUSES,
2713
+ resource,
2714
+ `${path}.primaryDisplayStatus`
2715
+ );
2716
+ timestamp(order.placedAt, resource, `${path}.placedAt`);
2717
+ timestamp(order.createdAt, resource, `${path}.createdAt`);
2718
+ timestamp(order.updatedAt, resource, `${path}.updatedAt`);
2719
+ }
2720
+ function nullablePositiveInteger(value, resource, path) {
2721
+ if (value !== null) positiveInteger(value, resource, path);
2722
+ }
2723
+ function validatePublicOrderList(value) {
2724
+ const resource = "Order list";
2725
+ const result = record(value, resource, "$");
2726
+ exact(
2727
+ result,
2728
+ [
2729
+ "docs",
2730
+ "totalDocs",
2731
+ "limit",
2732
+ "totalPages",
2733
+ "page",
2734
+ "pagingCounter",
2735
+ "hasPrevPage",
2736
+ "hasNextPage",
2737
+ "prevPage",
2738
+ "nextPage"
2739
+ ],
2740
+ [],
2741
+ resource,
2742
+ "$"
2743
+ );
2744
+ array(result.docs, resource, "$.docs").forEach(
2745
+ (order, index) => validatePublicOrderAt(order, resource, `$.docs[${index}]`)
2746
+ );
2747
+ safeMinor(result.totalDocs, resource, "$.totalDocs");
2748
+ positiveInteger(result.limit, resource, "$.limit");
2749
+ safeMinor(result.totalPages, resource, "$.totalPages");
2750
+ positiveInteger(result.page, resource, "$.page");
2751
+ positiveInteger(result.pagingCounter, resource, "$.pagingCounter");
2752
+ boolean(result.hasPrevPage, resource, "$.hasPrevPage");
2753
+ boolean(result.hasNextPage, resource, "$.hasNextPage");
2754
+ nullablePositiveInteger(result.prevPage, resource, "$.prevPage");
2755
+ nullablePositiveInteger(result.nextPage, resource, "$.nextPage");
2756
+ return value;
2757
+ }
2758
+ function validateCheckoutItem(value, resource, path) {
2759
+ const item = record(value, resource, path);
2760
+ exact(
2761
+ item,
2762
+ [
2763
+ "id",
2764
+ "product",
2765
+ "variant",
2766
+ "productTitle",
2767
+ "variantTitle",
2768
+ "sku",
2769
+ "admissions",
2770
+ "quantity",
2771
+ "unitPriceMinor",
2772
+ "discountMinor",
2773
+ "lineTotalMinor",
2774
+ "requiresShipping"
2775
+ ],
2776
+ [],
2777
+ resource,
2778
+ path
2779
+ );
2780
+ string(item.id, resource, `${path}.id`);
2781
+ validateReference(item.product, resource, `${path}.product`);
2782
+ validateReference(item.variant, resource, `${path}.variant`);
2783
+ string(item.productTitle, resource, `${path}.productTitle`);
2784
+ nullableString(item.variantTitle, resource, `${path}.variantTitle`);
2785
+ nullableString(item.sku, resource, `${path}.sku`);
2786
+ validateAdmissions(item.admissions, resource, `${path}.admissions`);
2787
+ cartLineQuantity(item.quantity, resource, `${path}.quantity`);
2788
+ const unitPrice = safeMinor(
2789
+ item.unitPriceMinor,
2790
+ resource,
2791
+ `${path}.unitPriceMinor`
2792
+ );
2793
+ const discount = safeMinor(
2794
+ item.discountMinor,
2795
+ resource,
2796
+ `${path}.discountMinor`
2797
+ );
2798
+ const lineTotal = safeMinor(
2799
+ item.lineTotalMinor,
2800
+ resource,
2801
+ `${path}.lineTotalMinor`
2802
+ );
2803
+ const expectedLineTotal = BigInt(unitPrice) * BigInt(item.quantity) - BigInt(discount);
2804
+ if (expectedLineTotal < 0n || BigInt(lineTotal) !== expectedLineTotal) {
2805
+ fail(
2806
+ resource,
2807
+ `${path}.lineTotalMinor`,
2808
+ "unitPriceMinor * quantity - discountMinor"
2809
+ );
2810
+ }
2811
+ boolean(item.requiresShipping, resource, `${path}.requiresShipping`);
2812
+ }
2813
+ function validateCheckoutAmounts(value, resource, path) {
2814
+ const amounts = record(value, resource, path);
2815
+ exact(
2816
+ amounts,
2817
+ [
2818
+ "currency",
2819
+ "subtotalMinor",
2820
+ "shippingMinor",
2821
+ "discountMinor",
2822
+ "totalMinor"
2823
+ ],
2824
+ [],
2825
+ resource,
2826
+ path
2827
+ );
2828
+ currency(amounts.currency, resource, `${path}.currency`);
2829
+ const subtotal = safeMinor(
2830
+ amounts.subtotalMinor,
2831
+ resource,
2832
+ `${path}.subtotalMinor`
2833
+ );
2834
+ const shipping = safeMinor(
2835
+ amounts.shippingMinor,
2836
+ resource,
2837
+ `${path}.shippingMinor`
2838
+ );
2839
+ const discount = safeMinor(
2840
+ amounts.discountMinor,
2841
+ resource,
2842
+ `${path}.discountMinor`
2843
+ );
2844
+ const total = safeMinor(amounts.totalMinor, resource, `${path}.totalMinor`);
2845
+ if (BigInt(total) !== BigInt(subtotal) + BigInt(shipping) - BigInt(discount)) {
2846
+ fail(
2847
+ resource,
2848
+ `${path}.totalMinor`,
2849
+ "subtotalMinor + shippingMinor - discountMinor"
2850
+ );
2851
+ }
2852
+ }
2853
+ function validatePaymentSessionReference(value, resource, path) {
2854
+ const session = record(value, resource, path);
2855
+ exact(session, ["id", "provider", "providerStatus"], [], resource, path);
2856
+ string(session.id, resource, `${path}.id`);
2857
+ enumValue(session.provider, PAYMENT_PROVIDERS, resource, `${path}.provider`);
2858
+ enumValue(
2859
+ session.providerStatus,
2860
+ PAYMENT_PROVIDER_STATUSES,
2861
+ resource,
2862
+ `${path}.providerStatus`
2863
+ );
2864
+ }
2865
+ function checkoutVariantKeys(status, placedVia) {
2866
+ const base = [
2867
+ "id",
2868
+ "amounts",
2869
+ "items",
2870
+ "customerSnapshot",
2871
+ "shippingAddress",
2872
+ "attributes",
2873
+ "expiresAt",
2874
+ "createdAt",
2875
+ "updatedAt",
2876
+ "status",
2877
+ "paymentState",
2878
+ "order"
2879
+ ];
2880
+ if (status === "open") return { required: base, optional: [] };
2881
+ if (status === "abandoned") {
2882
+ return {
2883
+ required: [...base, "abandonedAt", "abandonedReason"],
2884
+ optional: []
2885
+ };
2886
+ }
2887
+ return placedVia === "late_capture" ? {
2888
+ required: [
2889
+ ...base,
2890
+ "placedAt",
2891
+ "placedVia",
2892
+ "abandonedAt",
2893
+ "abandonedReason"
2894
+ ],
2895
+ optional: []
2896
+ } : { required: [...base, "placedAt"], optional: [] };
2897
+ }
2898
+ function validateCheckoutCore(value, resource, list, server) {
2899
+ const checkout = record(value, resource, "$");
2900
+ const status = enumValue(
2901
+ checkout.status,
2902
+ CHECKOUT_STATUSES,
2903
+ resource,
2904
+ "$.status"
2905
+ );
2906
+ const keys = checkoutVariantKeys(status, checkout.placedVia);
2907
+ if (list) {
2908
+ keys.required = keys.required.filter(
2909
+ (key) => !["items", "shippingAddress", "attributes"].includes(key)
2910
+ );
2911
+ keys.required.push("clientReferenceId");
2912
+ } else if (server) {
2913
+ keys.required.push("clientReferenceId", "integrationMetadata");
2914
+ }
2915
+ exact(checkout, keys.required, keys.optional, resource, "$");
2916
+ string(checkout.id, resource, "$.id");
2917
+ validateCheckoutAmounts(checkout.amounts, resource, "$.amounts");
2918
+ if (!list) {
2919
+ const items = array(checkout.items, resource, "$.items");
2920
+ if (items.length === 0) fail(resource, "$.items", "non-empty array");
2921
+ items.forEach(
2922
+ (item, index) => validateCheckoutItem(item, resource, `$.items[${index}]`)
2923
+ );
2924
+ const expectedSubtotal = items.reduce((total, value2) => {
2925
+ const item = value2;
2926
+ return total + BigInt(item.unitPriceMinor) * BigInt(item.quantity);
2927
+ }, 0n);
2928
+ const expectedDiscount = items.reduce((total, value2) => {
2929
+ const item = value2;
2930
+ return total + BigInt(item.discountMinor);
2931
+ }, 0n);
2932
+ const amounts = checkout.amounts;
2933
+ if (BigInt(amounts.subtotalMinor) !== expectedSubtotal) {
2934
+ fail(
2935
+ resource,
2936
+ "$.amounts.subtotalMinor",
2937
+ "sum of undiscounted checkout line totals"
2938
+ );
2939
+ }
2940
+ if (BigInt(amounts.discountMinor) !== expectedDiscount) {
2941
+ fail(
2942
+ resource,
2943
+ "$.amounts.discountMinor",
2944
+ "sum of checkout line discounts"
2945
+ );
2946
+ }
2947
+ if (checkout.shippingAddress !== null) {
2948
+ validateShippingAddress(
2949
+ checkout.shippingAddress,
2950
+ resource,
2951
+ "$.shippingAddress"
2952
+ );
2953
+ }
2954
+ validateAttributes(checkout.attributes, resource, "$.attributes");
2955
+ }
2956
+ validateCustomer(checkout.customerSnapshot, resource, "$.customerSnapshot");
2957
+ timestamp(checkout.expiresAt, resource, "$.expiresAt");
2958
+ timestamp(checkout.createdAt, resource, "$.createdAt");
2959
+ timestamp(checkout.updatedAt, resource, "$.updatedAt");
2960
+ const paymentState = record(checkout.paymentState, resource, "$.paymentState");
2961
+ exact(paymentState, ["activePaymentSession"], [], resource, "$.paymentState");
2962
+ if (status === "open") {
2963
+ if (paymentState.activePaymentSession !== null) {
2964
+ validatePaymentSessionReference(
2965
+ paymentState.activePaymentSession,
2966
+ resource,
2967
+ "$.paymentState.activePaymentSession"
2968
+ );
2969
+ }
2970
+ if (checkout.order !== null)
2971
+ fail(resource, "$.order", "null for open Checkout");
2972
+ } else {
2973
+ if (paymentState.activePaymentSession !== null) {
2974
+ fail(
2975
+ resource,
2976
+ "$.paymentState.activePaymentSession",
2977
+ "null for spent Checkout"
2978
+ );
2979
+ }
2980
+ if (status === "placed") {
2981
+ timestamp(checkout.placedAt, resource, "$.placedAt");
2982
+ validateOrderReference(checkout.order, resource, "$.order");
2983
+ if (checkout.placedVia !== void 0 && checkout.placedVia !== "late_capture") {
2984
+ fail(resource, "$.placedVia", "late_capture");
2985
+ }
2986
+ if (checkout.placedVia === "late_capture") {
2987
+ timestamp(checkout.abandonedAt, resource, "$.abandonedAt");
2988
+ enumValue(
2989
+ checkout.abandonedReason,
2990
+ ABANDONED_REASONS,
2991
+ resource,
2992
+ "$.abandonedReason"
2993
+ );
2994
+ }
2995
+ } else {
2996
+ timestamp(checkout.abandonedAt, resource, "$.abandonedAt");
2997
+ enumValue(
2998
+ checkout.abandonedReason,
2999
+ ABANDONED_REASONS,
3000
+ resource,
3001
+ "$.abandonedReason"
3002
+ );
3003
+ if (checkout.order !== null)
3004
+ fail(resource, "$.order", "null for abandoned Checkout");
3005
+ }
3006
+ }
3007
+ if (list || server) {
3008
+ if (checkout.clientReferenceId !== null) {
3009
+ boundedString(
3010
+ checkout.clientReferenceId,
3011
+ MAX_COMMERCE_RESOURCE_ID_LENGTH,
3012
+ resource,
3013
+ "$.clientReferenceId"
3014
+ );
3015
+ }
3016
+ }
3017
+ if (server)
3018
+ validateIntegrationMetadata(
3019
+ checkout.integrationMetadata,
3020
+ resource,
3021
+ "$.integrationMetadata"
3022
+ );
3023
+ }
3024
+ function validatePublicCheckout(value) {
3025
+ validateCheckoutCore(value, "Checkout", false, false);
3026
+ return value;
3027
+ }
3028
+ function validateServerCheckout(value) {
3029
+ validateCheckoutCore(value, "Server Checkout", false, true);
3030
+ return value;
3031
+ }
3032
+ function validateCreateCheckoutResult(value, server) {
3033
+ const resource = server ? "Server Checkout create result" : "Checkout create result";
3034
+ const result = record(value, resource, "$");
3035
+ exact(result, ["checkout", "checkoutToken"], [], resource, "$");
3036
+ if (server) validateServerCheckout(result.checkout);
3037
+ else validatePublicCheckout(result.checkout);
3038
+ boundedString(
3039
+ result.checkoutToken,
3040
+ MAX_COMMERCE_CAPABILITY_LENGTH,
3041
+ resource,
3042
+ "$.checkoutToken"
3043
+ );
3044
+ return value;
3045
+ }
3046
+ function validateCheckoutQueryResult(value) {
3047
+ const result = record(value, "Checkout query result", "$");
3048
+ exact(
3049
+ result,
3050
+ ["data", "hasMore", "nextCursor"],
3051
+ [],
3052
+ "Checkout query result",
3053
+ "$"
3054
+ );
3055
+ array(result.data, "Checkout query result", "$.data").forEach(
3056
+ (item) => validateCheckoutCore(item, "Checkout list item", true, false)
3057
+ );
3058
+ boolean(result.hasMore, "Checkout query result", "$.hasMore");
3059
+ if (result.nextCursor !== null)
3060
+ boundedString(
3061
+ result.nextCursor,
3062
+ MAX_COMMERCE_CAPABILITY_LENGTH,
3063
+ "Checkout query result",
3064
+ "$.nextCursor"
3065
+ );
3066
+ if (result.hasMore === true && result.nextCursor === null) {
3067
+ fail(
3068
+ "Checkout query result",
3069
+ "$.nextCursor",
3070
+ "non-null when hasMore is true"
3071
+ );
3072
+ }
3073
+ return value;
3074
+ }
3075
+ function validateMoney(value, resource, path) {
3076
+ const money = record(value, resource, path);
3077
+ exact(money, ["amountMinor", "currency"], [], resource, path);
3078
+ safeMinor(money.amountMinor, resource, `${path}.amountMinor`);
3079
+ currency(money.currency, resource, `${path}.currency`);
3080
+ }
3081
+ function validateCaptureEvidence(value, resource, path) {
3082
+ const evidence = record(value, resource, path);
3083
+ exact(evidence, ["amountMinor", "currency", "observedAt"], [], resource, path);
3084
+ safeMinor(evidence.amountMinor, resource, `${path}.amountMinor`);
3085
+ currency(evidence.currency, resource, `${path}.currency`);
3086
+ timestamp(evidence.observedAt, resource, `${path}.observedAt`);
3087
+ }
3088
+ function validateNoReconciliation(value, resource, path) {
3089
+ const reconciliation = record(value, resource, path);
3090
+ exact(reconciliation, ["status"], [], resource, path);
3091
+ if (reconciliation.status !== "none") fail(resource, `${path}.status`, "none");
3092
+ }
3093
+ function validateRequiredReconciliation(value, allowed, resource, path) {
3094
+ const reconciliation = record(value, resource, path);
3095
+ exact(reconciliation, ["status", "reasons"], [], resource, path);
3096
+ if (reconciliation.status !== "required")
3097
+ fail(resource, `${path}.status`, "required");
3098
+ const reasons = array(reconciliation.reasons, resource, `${path}.reasons`);
3099
+ if (reasons.length === 0) fail(resource, `${path}.reasons`, "non-empty array");
3100
+ let previous = -1;
3101
+ reasons.forEach((reason, index) => {
3102
+ const current = allowed.indexOf(reason);
3103
+ if (current < 0 || current <= previous) {
3104
+ fail(
3105
+ resource,
3106
+ `${path}.reasons[${index}]`,
3107
+ "unique canonical-sorted reconciliation reason"
3108
+ );
3109
+ }
3110
+ previous = current;
3111
+ });
3112
+ }
3113
+ function validateNextAction(value, resource, path) {
3114
+ const action = record(value, resource, path);
3115
+ exact(
3116
+ action,
3117
+ [
3118
+ "type",
3119
+ "clientKey",
3120
+ "paymentMethodVariantKey",
3121
+ "agreementVariantKey",
3122
+ "providerOrderId",
3123
+ "providerCustomerKey",
3124
+ "orderName"
3125
+ ],
3126
+ ["customerName", "customerEmail"],
3127
+ resource,
3128
+ path
3129
+ );
3130
+ if (action.type !== "toss_widget")
3131
+ fail(resource, `${path}.type`, "toss_widget");
3132
+ for (const key of [
3133
+ "clientKey",
3134
+ "paymentMethodVariantKey",
3135
+ "agreementVariantKey"
3136
+ ]) {
3137
+ boundedString(action[key], 255, resource, `${path}.${key}`);
3138
+ }
3139
+ string(action.providerOrderId, resource, `${path}.providerOrderId`);
3140
+ string(action.providerCustomerKey, resource, `${path}.providerCustomerKey`);
3141
+ boundedString(
3142
+ action.orderName,
3143
+ MAX_COMMERCE_SHORT_TEXT_LENGTH,
3144
+ resource,
3145
+ `${path}.orderName`
3146
+ );
3147
+ if (!/^[A-Za-z0-9_-]{6,64}$/.test(action.providerOrderId)) {
3148
+ fail(resource, `${path}.providerOrderId`, "valid Toss provider order ID");
3149
+ }
3150
+ if (action.providerCustomerKey !== "ANONYMOUS" && !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
3151
+ action.providerCustomerKey
3152
+ )) {
3153
+ fail(resource, `${path}.providerCustomerKey`, "ANONYMOUS or UUIDv4");
3154
+ }
3155
+ if (action.customerName !== void 0)
3156
+ boundedString(
3157
+ action.customerName,
3158
+ MAX_COMMERCE_SHORT_TEXT_LENGTH,
3159
+ resource,
3160
+ `${path}.customerName`
3161
+ );
3162
+ if (action.customerEmail !== void 0)
3163
+ validateCustomer({ email: action.customerEmail }, resource, path);
3164
+ }
3165
+ function validatePublicPaymentSession(value) {
3166
+ const resource = "PaymentSession";
3167
+ const session = record(value, resource, "$");
3168
+ enumValue(session.provider, PAYMENT_PROVIDERS, resource, "$.provider");
3169
+ const status = enumValue(
3170
+ session.providerStatus,
3171
+ PAYMENT_PROVIDER_STATUSES,
3172
+ resource,
3173
+ "$.providerStatus"
3174
+ );
3175
+ const common = [
3176
+ "id",
3177
+ "money",
3178
+ "expiresAt",
3179
+ "sessionRole",
3180
+ "provider",
3181
+ "providerStatus",
3182
+ "presentationStatus",
3183
+ "finalizationStatus",
3184
+ "reconciliation",
3185
+ "order"
3186
+ ];
3187
+ const optional = [];
3188
+ if (status === "requires_payment_method" || status === "requires_action")
3189
+ optional.push("nextAction");
3190
+ else if (status === "captured") common.push("providerEvidence");
3191
+ else if (status === "failed") common.push("failure");
3192
+ else if (status === "canceled") common.push("cancellationReason");
3193
+ exact(session, common, optional, resource, "$");
3194
+ string(session.id, resource, "$.id");
3195
+ validateMoney(session.money, resource, "$.money");
3196
+ if (session.expiresAt !== null)
3197
+ timestamp(session.expiresAt, resource, "$.expiresAt");
3198
+ if (status === "requires_payment_method" || status === "requires_action") {
3199
+ if (session.sessionRole === "active") {
3200
+ if (session.presentationStatus !== "actionable" || session.finalizationStatus !== "not_ready") {
3201
+ fail(resource, "$", "actionable active not-ready state");
3202
+ }
3203
+ if (!("nextAction" in session))
3204
+ fail(resource, "$.nextAction", "required field");
3205
+ validateNextAction(session.nextAction, resource, "$.nextAction");
3206
+ } else if (session.sessionRole === "residual") {
3207
+ if (session.presentationStatus !== "suppressed" || session.finalizationStatus !== "not_ready") {
3208
+ fail(resource, "$", "suppressed residual not-ready state");
3209
+ }
3210
+ if ("nextAction" in session)
3211
+ fail(resource, "$.nextAction", "absent for suppressed state");
3212
+ } else fail(resource, "$.sessionRole", "active | residual");
3213
+ validateNoReconciliation(
3214
+ session.reconciliation,
3215
+ resource,
3216
+ "$.reconciliation"
3217
+ );
3218
+ if (session.order !== null) fail(resource, "$.order", "null");
3219
+ } else if ([
3220
+ "requires_confirmation",
3221
+ "initializing",
3222
+ "processing",
3223
+ "authorized",
3224
+ "canceling"
3225
+ ].includes(status)) {
3226
+ enumValue(
3227
+ session.sessionRole,
3228
+ ["active", "residual"],
3229
+ resource,
3230
+ "$.sessionRole"
3231
+ );
3232
+ if (session.presentationStatus !== "suppressed" || session.finalizationStatus !== "not_ready") {
3233
+ fail(resource, "$", "suppressed not-ready state");
3234
+ }
3235
+ validateNoReconciliation(
3236
+ session.reconciliation,
3237
+ resource,
3238
+ "$.reconciliation"
3239
+ );
3240
+ if (session.order !== null) fail(resource, "$.order", "null");
3241
+ } else if (status === "unknown") {
3242
+ enumValue(
3243
+ session.sessionRole,
3244
+ ["active", "residual"],
3245
+ resource,
3246
+ "$.sessionRole"
3247
+ );
3248
+ if (session.presentationStatus !== "suppressed" || session.finalizationStatus !== "not_ready") {
3249
+ fail(resource, "$", "suppressed not-ready state");
3250
+ }
3251
+ validateRequiredReconciliation(
3252
+ session.reconciliation,
3253
+ ["provider_outcome_unknown"],
3254
+ resource,
3255
+ "$.reconciliation"
3256
+ );
3257
+ if (session.order !== null) fail(resource, "$.order", "null");
3258
+ } else if (status === "captured") {
3259
+ validateCaptureEvidence(
3260
+ session.providerEvidence,
3261
+ resource,
3262
+ "$.providerEvidence"
3263
+ );
3264
+ if (session.presentationStatus !== "suppressed")
3265
+ fail(resource, "$.presentationStatus", "suppressed");
3266
+ if (session.finalizationStatus === "pending") {
3267
+ enumValue(
3268
+ session.sessionRole,
3269
+ ["canonical_candidate", "residual"],
3270
+ resource,
3271
+ "$.sessionRole"
3272
+ );
3273
+ if (session.order !== null)
3274
+ fail(resource, "$.order", "null for pending finalization");
3275
+ const reconciliation = record(
3276
+ session.reconciliation,
3277
+ resource,
3278
+ "$.reconciliation"
3279
+ );
3280
+ if (reconciliation.status === "none")
3281
+ validateNoReconciliation(reconciliation, resource, "$.reconciliation");
3282
+ else
3283
+ validateRequiredReconciliation(
3284
+ reconciliation,
3285
+ [
3286
+ "local_commit_ambiguous",
3287
+ "amount_mismatch",
3288
+ "currency_mismatch",
3289
+ "excess_capture_pending_order"
3290
+ ],
3291
+ resource,
3292
+ "$.reconciliation"
3293
+ );
3294
+ } else if (session.finalizationStatus === "committed") {
3295
+ validateOrderReference(session.order, resource, "$.order");
3296
+ const reconciliation = record(
3297
+ session.reconciliation,
3298
+ resource,
3299
+ "$.reconciliation"
3300
+ );
3301
+ if (reconciliation.status === "none") {
3302
+ enumValue(
3303
+ session.sessionRole,
3304
+ ["canonical", "historical"],
3305
+ resource,
3306
+ "$.sessionRole"
3307
+ );
3308
+ validateNoReconciliation(reconciliation, resource, "$.reconciliation");
3309
+ } else {
3310
+ enumValue(
3311
+ session.sessionRole,
3312
+ ["canonical", "residual"],
3313
+ resource,
3314
+ "$.sessionRole"
3315
+ );
3316
+ validateRequiredReconciliation(
3317
+ reconciliation,
3318
+ [
3319
+ "inventory_unavailable",
3320
+ "admission_unavailable",
3321
+ "amount_mismatch",
3322
+ "currency_mismatch",
3323
+ "excess_capture",
3324
+ "late_capture",
3325
+ "cross_checkout_duplicate"
3326
+ ],
3327
+ resource,
3328
+ "$.reconciliation"
3329
+ );
3330
+ }
3331
+ } else fail(resource, "$.finalizationStatus", "pending | committed");
3332
+ } else if (status === "failed") {
3333
+ if (session.sessionRole !== "historical" || session.presentationStatus !== "suppressed" || session.finalizationStatus !== "not_ready" || session.order !== null) {
3334
+ fail(resource, "$", "historical suppressed failed state");
3335
+ }
3336
+ validateNoReconciliation(
3337
+ session.reconciliation,
3338
+ resource,
3339
+ "$.reconciliation"
3340
+ );
3341
+ const failure = record(session.failure, resource, "$.failure");
3342
+ exact(failure, ["reason"], ["message"], resource, "$.failure");
3343
+ enumValue(
3344
+ failure.reason,
3345
+ PAYMENT_FAILURE_REASONS,
3346
+ resource,
3347
+ "$.failure.reason"
3348
+ );
3349
+ if (failure.message !== void 0)
3350
+ string(failure.message, resource, "$.failure.message");
3351
+ } else {
3352
+ if (session.sessionRole !== "historical" || session.presentationStatus !== "suppressed" || session.finalizationStatus !== "not_ready" || session.order !== null) {
3353
+ fail(resource, "$", "historical suppressed canceled state");
3354
+ }
3355
+ validateNoReconciliation(
3356
+ session.reconciliation,
3357
+ resource,
3358
+ "$.reconciliation"
3359
+ );
3360
+ enumValue(
3361
+ session.cancellationReason,
3362
+ ["expired", "customer", "operator", "provider"],
3363
+ resource,
3364
+ "$.cancellationReason"
3365
+ );
3366
+ }
3367
+ return value;
1442
3368
  }
1443
- var ContentClient = class {
1444
- constructor(options) {
1445
- const api = new PublicContentApi("ContentClient", {
1446
- publishableKey: options.publishableKey,
1447
- apiUrl: options.apiUrl,
1448
- onRequestId: options.onRequestId,
1449
- requiresCredential: false
1450
- });
1451
- this.links = {
1452
- list: (params) => api.get(linksListPath(params))
1453
- };
1454
- this.galleryItems = {
1455
- list: (params) => api.get(
1456
- galleryItemsListPath(params)
1457
- )
1458
- };
1459
- }
1460
- };
1461
3369
 
1462
3370
  // src/core/customer/customer-auth.ts
1463
3371
  var DEFAULT_TIMEOUT2 = 15e3;
@@ -1476,8 +3384,10 @@ var CustomerAuth = class {
1476
3384
  const persist = options?.persist ?? true;
1477
3385
  if (persist) {
1478
3386
  const key = typeof persist === "string" ? persist : "customer-token";
3387
+ const refreshKey = `${key}:refresh`;
1479
3388
  const isBrowser = typeof window !== "undefined";
1480
3389
  this.token = isBrowser ? safeGetItem(key) : null;
3390
+ this.refreshTokenValue = isBrowser ? safeGetItem(refreshKey) : null;
1481
3391
  this.onTokenChange = isBrowser ? (token) => {
1482
3392
  try {
1483
3393
  if (token) localStorage.setItem(key, token);
@@ -1485,9 +3395,18 @@ var CustomerAuth = class {
1485
3395
  } catch {
1486
3396
  }
1487
3397
  } : void 0;
3398
+ this.onRefreshTokenChange = isBrowser ? (refreshToken) => {
3399
+ try {
3400
+ if (refreshToken) localStorage.setItem(refreshKey, refreshToken);
3401
+ else localStorage.removeItem(refreshKey);
3402
+ } catch {
3403
+ }
3404
+ } : void 0;
1488
3405
  } else {
1489
3406
  this.token = options?.token ?? null;
3407
+ this.refreshTokenValue = options?.refreshToken ?? null;
1490
3408
  this.onTokenChange = options?.onTokenChange;
3409
+ this.onRefreshTokenChange = options?.onRefreshTokenChange;
1491
3410
  }
1492
3411
  }
1493
3412
  /**
@@ -1511,13 +3430,17 @@ var CustomerAuth = class {
1511
3430
  }
1512
3431
  );
1513
3432
  this.setToken(result.token);
3433
+ if (result.refreshToken) this.setRefreshToken(result.refreshToken);
1514
3434
  return result;
1515
3435
  }
1516
3436
  /**
1517
- * Refresh the current token. Requires a valid (non-expired) token.
3437
+ * Refresh the current token. Uses a refresh token when available, otherwise
3438
+ * falls back to the legacy bearer-token compatibility path.
1518
3439
  */
1519
3440
  async refreshToken() {
1520
- if (!this.token) throw new ApiError("Not authenticated", 401);
3441
+ if (!this.refreshTokenValue && !this.token) {
3442
+ throw new ApiError("Not authenticated", 401);
3443
+ }
1521
3444
  if (this.refreshPromise) return this.refreshPromise;
1522
3445
  this.refreshPromise = this._doRefreshToken();
1523
3446
  try {
@@ -1527,14 +3450,19 @@ var CustomerAuth = class {
1527
3450
  }
1528
3451
  }
1529
3452
  async _doRefreshToken() {
3453
+ const init = this.refreshTokenValue ? {
3454
+ method: "POST",
3455
+ body: JSON.stringify({ refreshToken: this.refreshTokenValue })
3456
+ } : {
3457
+ method: "POST",
3458
+ headers: { Authorization: `Bearer ${this.token}` }
3459
+ };
1530
3460
  const result = await this.requestJson(
1531
3461
  "/api/customers/refresh",
1532
- {
1533
- method: "POST",
1534
- headers: { Authorization: `Bearer ${this.token}` }
1535
- }
3462
+ init
1536
3463
  );
1537
3464
  this.setToken(result.token);
3465
+ if (result.refreshToken) this.setRefreshToken(result.refreshToken);
1538
3466
  return result;
1539
3467
  }
1540
3468
  /**
@@ -1542,6 +3470,7 @@ var CustomerAuth = class {
1542
3470
  */
1543
3471
  logout() {
1544
3472
  this.setToken(null);
3473
+ this.setRefreshToken(null);
1545
3474
  }
1546
3475
  /**
1547
3476
  * Get the current authenticated customer's profile
@@ -1617,25 +3546,28 @@ var CustomerAuth = class {
1617
3546
  const params = new URLSearchParams();
1618
3547
  if (options?.page) params.set("page", String(options.page));
1619
3548
  if (options?.limit) params.set("limit", String(options.limit));
1620
- if (options?.displayFinancialStatus) {
1621
- params.set("displayFinancialStatus", options.displayFinancialStatus);
3549
+ if (options?.financialStatus) {
3550
+ params.set("financialStatus", options.financialStatus);
1622
3551
  }
1623
- if (options?.displayFulfillmentStatus) {
1624
- params.set("displayFulfillmentStatus", options.displayFulfillmentStatus);
3552
+ if (options?.fulfillmentStatus) {
3553
+ params.set("fulfillmentStatus", options.fulfillmentStatus);
1625
3554
  }
1626
3555
  if (options?.returnStatus) params.set("returnStatus", options.returnStatus);
3556
+ if (options?.confirmationStatus) {
3557
+ params.set("confirmationStatus", options.confirmationStatus);
3558
+ }
1627
3559
  if (options?.primaryDisplayStatus) {
1628
3560
  params.set("primaryDisplayStatus", options.primaryDisplayStatus);
1629
3561
  }
1630
- if (options?.returnDisplayStatus) {
1631
- params.set("returnDisplayStatus", options.returnDisplayStatus);
1632
- }
1633
- if (options?.status) params.set("status", options.status);
1634
3562
  const qs = params.toString();
1635
- return this.requestJson(`/api/customers/me/orders${qs ? `?${qs}` : ""}`, {
1636
- method: "GET",
1637
- headers: { Authorization: `Bearer ${this.token}` }
1638
- });
3563
+ const result = await this.requestJson(
3564
+ `/api/customers/me/orders${qs ? `?${qs}` : ""}`,
3565
+ {
3566
+ method: "GET",
3567
+ headers: { Authorization: `Bearer ${this.token}` }
3568
+ }
3569
+ );
3570
+ return validatePublicOrderList(result);
1639
3571
  }
1640
3572
  /**
1641
3573
  * Get the current token (or null if not authenticated)
@@ -1643,6 +3575,12 @@ var CustomerAuth = class {
1643
3575
  getToken() {
1644
3576
  return this.token;
1645
3577
  }
3578
+ /**
3579
+ * Get the current refresh token (or null if unavailable)
3580
+ */
3581
+ getRefreshToken() {
3582
+ return this.refreshTokenValue;
3583
+ }
1646
3584
  /**
1647
3585
  * Set the token manually (e.g. from SSR)
1648
3586
  */
@@ -1650,6 +3588,13 @@ var CustomerAuth = class {
1650
3588
  this.token = token;
1651
3589
  this.onTokenChange?.(token);
1652
3590
  }
3591
+ /**
3592
+ * Set the refresh token manually (e.g. from SSR cookie)
3593
+ */
3594
+ setRefreshToken(refreshToken) {
3595
+ this.refreshTokenValue = refreshToken;
3596
+ this.onRefreshTokenChange?.(refreshToken);
3597
+ }
1653
3598
  /**
1654
3599
  * Check if the customer is currently authenticated
1655
3600
  */
@@ -1678,91 +3623,362 @@ var CustomerAuth = class {
1678
3623
  }
1679
3624
  };
1680
3625
 
3626
+ // src/core/customer/customer-oauth.ts
3627
+ var DEFAULT_SCOPES = ["openid", "profile", "email"];
3628
+ var DEFAULT_TIMEOUT3 = 15e3;
3629
+ function issuerUrl(issuer, path) {
3630
+ const base = resolveApiUrl(issuer);
3631
+ return new URL(path, base.endsWith("/") ? base : `${base}/`).toString();
3632
+ }
3633
+ function randomBase64Url(bytes) {
3634
+ const buffer = new Uint8Array(bytes);
3635
+ crypto.getRandomValues(buffer);
3636
+ let binary = "";
3637
+ for (const value of buffer) {
3638
+ binary += String.fromCharCode(value);
3639
+ }
3640
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3641
+ }
3642
+ async function sha256Base64Url(value) {
3643
+ const data = new TextEncoder().encode(value);
3644
+ const digest = await crypto.subtle.digest("SHA-256", data);
3645
+ let binary = "";
3646
+ for (const byte of new Uint8Array(digest)) {
3647
+ binary += String.fromCharCode(byte);
3648
+ }
3649
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3650
+ }
3651
+ function normalizeToken(body) {
3652
+ if (body.token_type !== "Bearer") {
3653
+ throw new Error("Unsupported customer OAuth token type");
3654
+ }
3655
+ return {
3656
+ accessToken: body.access_token,
3657
+ expiresAt: Date.now() + body.expires_in * 1e3,
3658
+ expiresIn: body.expires_in,
3659
+ ...body.id_token ? { idToken: body.id_token } : {},
3660
+ refreshToken: body.refresh_token,
3661
+ ...body.scope ? { scope: body.scope } : {},
3662
+ tokenType: "Bearer"
3663
+ };
3664
+ }
3665
+ var CustomerOAuth = class {
3666
+ constructor(config) {
3667
+ if (!config.clientId) throw new Error("customer OAuth clientId is required");
3668
+ if (!config.issuer) throw new Error("customer OAuth issuer is required");
3669
+ this.clientId = config.clientId;
3670
+ this.issuer = config.issuer;
3671
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT3;
3672
+ }
3673
+ async createAuthorizationUrl(input) {
3674
+ const codeVerifier = randomBase64Url(48);
3675
+ const codeChallenge = await sha256Base64Url(codeVerifier);
3676
+ const state = randomBase64Url(32);
3677
+ const nonce = randomBase64Url(32);
3678
+ const scopes = input.scopes ?? DEFAULT_SCOPES;
3679
+ const url = new URL(issuerUrl(this.issuer, "customer-oauth/authorize"));
3680
+ url.searchParams.set("response_type", "code");
3681
+ url.searchParams.set("client_id", this.clientId);
3682
+ url.searchParams.set("redirect_uri", input.redirectUri);
3683
+ url.searchParams.set("scope", scopes.join(" "));
3684
+ url.searchParams.set("state", state);
3685
+ url.searchParams.set("nonce", nonce);
3686
+ url.searchParams.set("code_challenge", codeChallenge);
3687
+ url.searchParams.set("code_challenge_method", "S256");
3688
+ return {
3689
+ authorizationUrl: url.toString(),
3690
+ codeChallenge,
3691
+ codeVerifier,
3692
+ nonce,
3693
+ returnTo: input.returnTo ?? null,
3694
+ state
3695
+ };
3696
+ }
3697
+ parseCallback(callbackUrl, options) {
3698
+ const url = new URL(callbackUrl);
3699
+ const error = url.searchParams.get("error");
3700
+ if (error) {
3701
+ throw new Error(
3702
+ url.searchParams.get("error_description") ?? `OAuth error: ${error}`
3703
+ );
3704
+ }
3705
+ const code = url.searchParams.get("code");
3706
+ const state = url.searchParams.get("state");
3707
+ if (!code || !state) throw new Error("OAuth callback is missing code/state");
3708
+ if (state !== options.expectedState) throw new Error("OAuth state mismatch");
3709
+ return { code, state };
3710
+ }
3711
+ async exchangeCode(input) {
3712
+ const body = new URLSearchParams({
3713
+ client_id: this.clientId,
3714
+ code: input.code,
3715
+ code_verifier: input.codeVerifier,
3716
+ grant_type: "authorization_code",
3717
+ redirect_uri: input.redirectUri
3718
+ });
3719
+ return this.tokenRequest(body);
3720
+ }
3721
+ async refresh(input) {
3722
+ const body = new URLSearchParams({
3723
+ client_id: this.clientId,
3724
+ grant_type: "refresh_token",
3725
+ refresh_token: input.refreshToken
3726
+ });
3727
+ return this.tokenRequest(body);
3728
+ }
3729
+ async logout(input) {
3730
+ const body = { client_id: this.clientId };
3731
+ if (input.refreshToken) body.refresh_token = input.refreshToken;
3732
+ if (input.postLogoutRedirectUri) {
3733
+ body.post_logout_redirect_uri = input.postLogoutRedirectUri;
3734
+ }
3735
+ const response = await httpFetch("/customer-oauth/logout", {
3736
+ apiUrl: this.issuer,
3737
+ method: "POST",
3738
+ body: JSON.stringify(body),
3739
+ headers: { "Content-Type": "application/json" },
3740
+ timeout: this.timeout,
3741
+ retry: { maxRetries: 0 }
3742
+ });
3743
+ return parseApiResponse(
3744
+ response,
3745
+ "/customer-oauth/logout"
3746
+ );
3747
+ }
3748
+ verifyIdToken() {
3749
+ throw new Error(
3750
+ "Customer OAuth ID token verification is not implemented; treat idToken as opaque."
3751
+ );
3752
+ }
3753
+ async tokenRequest(body) {
3754
+ const response = await httpFetch("/api/customer-oauth/token", {
3755
+ apiUrl: this.issuer,
3756
+ method: "POST",
3757
+ body,
3758
+ headers: {
3759
+ "Content-Type": "application/x-www-form-urlencoded"
3760
+ },
3761
+ timeout: this.timeout,
3762
+ retry: { maxRetries: 0 }
3763
+ });
3764
+ return normalizeToken(
3765
+ await parseApiResponse(
3766
+ response,
3767
+ "/api/customer-oauth/token"
3768
+ )
3769
+ );
3770
+ }
3771
+ };
3772
+
1681
3773
  // src/core/customer/customer-namespace.ts
1682
3774
  var CustomerNamespace = class {
1683
3775
  constructor(publishableKey, options, apiUrl) {
1684
3776
  this.auth = new CustomerAuth(publishableKey, options, apiUrl);
3777
+ if (options?.oauth) {
3778
+ this.oauth = new CustomerOAuth(options.oauth);
3779
+ }
1685
3780
  }
1686
3781
  };
1687
3782
 
3783
+ // src/core/api/commerce-idempotency.ts
3784
+ var UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
3785
+ var PREFIXED_BASE64URL_PATTERN = /^ik_[A-Za-z0-9_-]{22}$/;
3786
+ function isCommerceIdempotencyKey(value) {
3787
+ return typeof value === "string" && value.length <= 255 && (UUID_V4_PATTERN.test(value) || PREFIXED_BASE64URL_PATTERN.test(value));
3788
+ }
3789
+ function assertCommerceIdempotencyKey(value) {
3790
+ if (isCommerceIdempotencyKey(value)) return;
3791
+ throw createValidationError(
3792
+ "idempotencyKey must be a UUIDv4 or ik_-prefixed 128-bit base64url value.",
3793
+ { field: "idempotencyKey" }
3794
+ );
3795
+ }
3796
+ function createCommerceIdempotencyKey() {
3797
+ return globalThis.crypto.randomUUID();
3798
+ }
3799
+
1688
3800
  // src/core/api/cart-api.ts
3801
+ var MAX_CART_LINE_ADMISSIONS = 32;
1689
3802
  var CartApi = class extends CustomerScopedApi {
1690
3803
  constructor(options) {
1691
3804
  super("CartApi", { ...options, requiresCredential: false });
3805
+ this.serverTransport = Boolean(options.secretKey);
1692
3806
  }
1693
- async execute(endpoint, method, body) {
1694
- return this.request(endpoint, { method, body });
3807
+ endpoint(key) {
3808
+ return this.serverTransport ? COMMERCE_ENDPOINTS.carts.server[key] : COMMERCE_ENDPOINTS.carts[key];
1695
3809
  }
1696
- /**
1697
- * Create a cart and receive its `cartToken`. Store the token and pass it to
1698
- * every subsequent cart operation.
1699
- */
1700
- createCart(params = {}) {
1701
- return this.execute("/api/carts/create", "POST", params);
3810
+ execute(endpoint2, body, idempotencyKey) {
3811
+ return this.requestEndpoint(endpoint2, body, {
3812
+ ...idempotencyKey && {
3813
+ headers: { "X-Idempotency-Key": idempotencyKey }
3814
+ }
3815
+ });
1702
3816
  }
1703
- getCart(cartToken) {
1704
- return this.execute("/api/carts/get", "POST", { cartToken });
3817
+ create(params = {}) {
3818
+ return this.execute(this.endpoint("create"), params).then(
3819
+ (value) => validateCreateCartResult(value)
3820
+ );
1705
3821
  }
1706
- merge(params) {
1707
- return this.execute(
1708
- COMMERCE_ENDPOINTS.carts.merge,
1709
- "POST",
1710
- params
3822
+ retrieve(params) {
3823
+ return this.execute(this.endpoint("retrieve"), params).then(
3824
+ (value) => validatePublicCart(value)
1711
3825
  );
1712
3826
  }
1713
- /**
1714
- * Resolve the authenticated customer's active cart by JWT (no `cartToken`
1715
- * required). Returns the cart and its capability handle, or both `null` when
1716
- * the customer has no active cart. Requires a customer token.
1717
- */
1718
- mine() {
1719
- return this.execute(
1720
- COMMERCE_ENDPOINTS.carts.mine,
1721
- "POST",
1722
- {}
3827
+ mine(params = {}) {
3828
+ const endpoint2 = this.endpoint("mine");
3829
+ return this.execute(endpoint2, params).then(
3830
+ (value) => validateCartMineResult(value)
3831
+ );
3832
+ }
3833
+ merge(params) {
3834
+ const { idempotencyKey, ...body } = params;
3835
+ assertCommerceIdempotencyKey(idempotencyKey);
3836
+ const endpoint2 = this.endpoint("merge");
3837
+ return this.execute(endpoint2, body, idempotencyKey).then(
3838
+ (value) => validateCartMergeResult(value)
1723
3839
  );
1724
3840
  }
1725
3841
  addItem(params) {
1726
- return this.execute(
1727
- COMMERCE_ENDPOINTS.carts.addItem,
1728
- "POST",
1729
- params
3842
+ return this.mutate(this.endpoint("addItem"), params);
3843
+ }
3844
+ mutate(endpoint2, params) {
3845
+ const { idempotencyKey, ...body } = params;
3846
+ assertCommerceIdempotencyKey(idempotencyKey);
3847
+ return this.execute(endpoint2, body, idempotencyKey).then(
3848
+ (value) => validateCartMutationResult(value)
1730
3849
  );
1731
3850
  }
1732
3851
  updateItem(params) {
1733
- return this.execute(
1734
- COMMERCE_ENDPOINTS.carts.updateItem,
1735
- "POST",
1736
- params
1737
- );
3852
+ return this.mutate(this.endpoint("updateItem"), params);
1738
3853
  }
1739
3854
  removeItem(params) {
1740
- return this.execute(
1741
- COMMERCE_ENDPOINTS.carts.removeItem,
1742
- "POST",
1743
- params
3855
+ return this.mutate(this.endpoint("removeItem"), params);
3856
+ }
3857
+ clear(params) {
3858
+ return this.mutate(this.endpoint("clear"), params);
3859
+ }
3860
+ updateDiscountCodes(params) {
3861
+ return this.mutate(this.endpoint("updateDiscountCodes"), params);
3862
+ }
3863
+ updateAttributes(params) {
3864
+ return this.mutate(this.endpoint("updateAttributes"), params);
3865
+ }
3866
+ };
3867
+
3868
+ // src/core/api/checkout-api.ts
3869
+ var CheckoutApi = class extends CustomerScopedApi {
3870
+ constructor(options) {
3871
+ super("CheckoutApi", { ...options, requiresCredential: false });
3872
+ }
3873
+ post(endpoint2, body, idempotencyKey) {
3874
+ return this.requestEndpoint(endpoint2, body, {
3875
+ ...idempotencyKey && {
3876
+ headers: { "X-Idempotency-Key": idempotencyKey }
3877
+ }
3878
+ });
3879
+ }
3880
+ async publicCheckout(result) {
3881
+ return validatePublicCheckout(await result);
3882
+ }
3883
+ async serverCheckout(result) {
3884
+ return validateServerCheckout(await result);
3885
+ }
3886
+ async createResult(result) {
3887
+ return validateCreateCheckoutResult(
3888
+ await result,
3889
+ false
1744
3890
  );
1745
3891
  }
1746
- applyDiscount(params) {
1747
- return this.execute(
1748
- COMMERCE_ENDPOINTS.carts.applyDiscount,
1749
- "POST",
1750
- params
3892
+ async createServerResult(result) {
3893
+ return validateCreateCheckoutResult(
3894
+ await result,
3895
+ true
1751
3896
  );
1752
3897
  }
1753
- removeDiscount(params) {
1754
- return this.execute(
1755
- COMMERCE_ENDPOINTS.carts.removeDiscount,
1756
- "POST",
1757
- params
3898
+ create(params) {
3899
+ const { idempotencyKey, ...body } = params;
3900
+ assertCommerceIdempotencyKey(idempotencyKey);
3901
+ return this.createResult(
3902
+ this.post(COMMERCE_ENDPOINTS.checkouts.create, body, idempotencyKey)
1758
3903
  );
1759
3904
  }
1760
- clearCart(params) {
1761
- return this.execute(
1762
- COMMERCE_ENDPOINTS.carts.clear,
1763
- "POST",
3905
+ createServer(params) {
3906
+ const { idempotencyKey, ...body } = params;
3907
+ assertCommerceIdempotencyKey(idempotencyKey);
3908
+ return this.createServerResult(
3909
+ this.post(
3910
+ COMMERCE_ENDPOINTS.checkouts.server.create,
3911
+ body,
3912
+ idempotencyKey
3913
+ )
3914
+ );
3915
+ }
3916
+ retrieve(params) {
3917
+ return this.publicCheckout(
3918
+ this.post(COMMERCE_ENDPOINTS.checkouts.retrieve, params)
3919
+ );
3920
+ }
3921
+ retrieveServer(params) {
3922
+ return this.serverCheckout(
3923
+ this.post(COMMERCE_ENDPOINTS.checkouts.server.retrieve, params)
3924
+ );
3925
+ }
3926
+ async query(params = {}) {
3927
+ const result = await this.post(
3928
+ COMMERCE_ENDPOINTS.checkouts.server.query,
1764
3929
  params
1765
3930
  );
3931
+ return validateCheckoutQueryResult(result);
3932
+ }
3933
+ };
3934
+
3935
+ // src/core/api/payment-session-api.ts
3936
+ var PaymentSessionApi = class extends CustomerScopedApi {
3937
+ constructor(options) {
3938
+ super("PaymentSessionApi", { ...options, requiresCredential: false });
3939
+ this.serverTransport = Boolean(options.secretKey);
3940
+ }
3941
+ post(endpoint2, body, idempotencyKey) {
3942
+ return this.requestEndpoint(endpoint2, body, {
3943
+ ...idempotencyKey && {
3944
+ headers: { "X-Idempotency-Key": idempotencyKey }
3945
+ }
3946
+ });
3947
+ }
3948
+ async paymentSession(result) {
3949
+ return validatePublicPaymentSession(await result);
3950
+ }
3951
+ create(params) {
3952
+ const { idempotencyKey, ...body } = params;
3953
+ assertCommerceIdempotencyKey(idempotencyKey);
3954
+ return this.paymentSession(
3955
+ this.post(
3956
+ this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.create : COMMERCE_ENDPOINTS.paymentSessions.create,
3957
+ body,
3958
+ idempotencyKey
3959
+ )
3960
+ );
3961
+ }
3962
+ retrieve(params) {
3963
+ const endpoint2 = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve : COMMERCE_ENDPOINTS.paymentSessions.retrieve;
3964
+ return this.paymentSession(this.post(endpoint2, params));
3965
+ }
3966
+ cancel(params) {
3967
+ const { idempotencyKey, ...body } = params;
3968
+ assertCommerceIdempotencyKey(idempotencyKey);
3969
+ const endpoint2 = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel : COMMERCE_ENDPOINTS.paymentSessions.cancel;
3970
+ return this.paymentSession(this.post(endpoint2, body, idempotencyKey));
3971
+ }
3972
+ confirm(params) {
3973
+ const { idempotencyKey, ...body } = params;
3974
+ assertCommerceIdempotencyKey(idempotencyKey);
3975
+ return this.paymentSession(
3976
+ this.post(
3977
+ COMMERCE_ENDPOINTS.paymentSessions.server.confirm,
3978
+ body,
3979
+ idempotencyKey
3980
+ )
3981
+ );
1766
3982
  }
1767
3983
  };
1768
3984
 
@@ -2765,9 +4981,13 @@ function resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) {
2765
4981
  return getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)?.id ?? null;
2766
4982
  }
2767
4983
  function buildSelectionPrice(variants) {
2768
- const { min, max } = getMinMax(variants.map((variant) => variant.price));
4984
+ const { min, max } = getMinMax(
4985
+ variants.map((variant) => variant.resolvedPrice?.amount ?? variant.price)
4986
+ );
2769
4987
  const { min: compareAtMin, max: compareAtMax } = getMinMax(
2770
- variants.map((variant) => variant.compareAtPrice)
4988
+ variants.map(
4989
+ (variant) => variant.resolvedPrice?.compareAtPrice ?? variant.compareAtPrice
4990
+ )
2771
4991
  );
2772
4992
  return {
2773
4993
  min,
@@ -2827,8 +5047,8 @@ function buildSelectionStock(selectedVariant, matchingVariants) {
2827
5047
  return {
2828
5048
  availableForSale: getVariantAvailableForSale(selectedVariant),
2829
5049
  isUnlimited: selectedVariant.isUnlimited,
2830
- stock: selectedVariant.stock,
2831
- reservedStock: selectedVariant.reservedStock,
5050
+ stock: "stock" in selectedVariant ? selectedVariant.stock : null,
5051
+ reservedStock: "reservedStock" in selectedVariant ? selectedVariant.reservedStock : null,
2832
5052
  availableStock
2833
5053
  };
2834
5054
  }
@@ -3210,6 +5430,9 @@ function compareVariantOrder(a, b) {
3210
5430
  }
3211
5431
  function getVariantAvailableForSale(variant) {
3212
5432
  if (variant.isActive === false) return false;
5433
+ if (typeof variant.availableForSale === "boolean") {
5434
+ return variant.availableForSale;
5435
+ }
3213
5436
  if (variant.isUnlimited) return true;
3214
5437
  if (variant.inventoryPolicy === "continue") return true;
3215
5438
  return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0;
@@ -3323,7 +5546,7 @@ function buildProductListingCard(item, options = {}) {
3323
5546
  { listing: { selectionHintVariant } },
3324
5547
  options
3325
5548
  ),
3326
- title: product.title,
5549
+ title: product.title ?? "",
3327
5550
  representativeVariant,
3328
5551
  primaryImage: listingPrimaryMedia,
3329
5552
  priceRange,
@@ -3510,6 +5733,11 @@ function productDetailResultFromError(error) {
3510
5733
  if (!reason) return void 0;
3511
5734
  return { found: false, reason };
3512
5735
  }
5736
+ var MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE = "Market listing pages do not support base price filters or price sorts.";
5737
+ var BASE_PRICE_RANGE_SORT_FIELDS = /* @__PURE__ */ new Set([
5738
+ "priceRange.minVariantPrice.amount",
5739
+ "priceRange.maxVariantPrice.amount"
5740
+ ]);
3513
5741
  function nonEmpty(values) {
3514
5742
  return values?.length ? values : void 0;
3515
5743
  }
@@ -3557,14 +5785,34 @@ function buildProductListingPageWhere(params) {
3557
5785
  if (clauses.length === 1) return clauses[0];
3558
5786
  return { and: clauses };
3559
5787
  }
3560
- function buildProductListingPageUrl(params) {
5788
+ function productListingPageUsesBasePriceSort(sort) {
5789
+ const values = Array.isArray(sort) ? sort : sort ? [sort] : [];
5790
+ return values.some(
5791
+ (value) => BASE_PRICE_RANGE_SORT_FIELDS.has(String(value).replace(/^-/, ""))
5792
+ );
5793
+ }
5794
+ function assertMarketListingPageQuerySupported(params) {
5795
+ if (!params.market?.trim()) return;
5796
+ const priceFilter = params.filters?.price;
5797
+ if (priceFilter?.min != null || priceFilter?.max != null || productListingPageUsesBasePriceSort(params.sort)) {
5798
+ throw new TypeError(MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE);
5799
+ }
5800
+ }
5801
+ function buildProductListingPageRequest(params) {
5802
+ assertMarketListingPageQuerySupported(params);
3561
5803
  const options = {
5804
+ market: params.market,
5805
+ locale: params.locale,
5806
+ fallbackLocale: params.fallbackLocale,
3562
5807
  page: params.page,
3563
5808
  limit: params.limit,
3564
5809
  sort: params.sort,
3565
5810
  where: buildProductListingPageWhere(params)
3566
5811
  };
3567
- return params.mode === "full" ? listingGroupsQueryUrl(options) : listingGroupsQueryCatalogUrl(options);
5812
+ return {
5813
+ operation: params.mode === "full" ? COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet : COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog,
5814
+ query: listingPageSearchParams(options)
5815
+ };
3568
5816
  }
3569
5817
  function withProductListingCards(response, options) {
3570
5818
  return {
@@ -3581,30 +5829,15 @@ function isProductUpsertFieldValidationErrorBody(value) {
3581
5829
  return typeof body.error === "string" && typeof body.field === "string" && (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON || reason === PRODUCT_UPSERT_READONLY_FIELD_REASON);
3582
5830
  }
3583
5831
 
3584
- // src/core/api/order-api.ts
3585
- function idempotencyRequestOptions(idempotencyKey) {
3586
- return idempotencyKey ? { headers: { "X-Idempotency-Key": idempotencyKey } } : void 0;
3587
- }
3588
- function splitIdempotencyKey(params) {
3589
- const { idempotencyKey, ...body } = params;
3590
- return { body, idempotencyKey };
3591
- }
3592
-
3593
5832
  // src/core/commerce/commerce-client.ts
3594
5833
  var BrowserCommerceApi = class extends CustomerScopedApi {
3595
- post(endpoint, body, requestOptions) {
3596
- return this.request(endpoint, {
3597
- method: "POST",
3598
- body,
3599
- headers: requestOptions?.headers
3600
- });
3601
- }
3602
- get(endpoint) {
3603
- return this.request(endpoint, { method: "GET" });
5834
+ requestEndpoint(endpoint2, body, options) {
5835
+ return super.requestEndpoint(endpoint2, body, options);
3604
5836
  }
3605
5837
  };
3606
5838
  var CommerceClient = class {
3607
5839
  constructor(options) {
5840
+ this.market = options.market;
3608
5841
  const cartApi = new CartApi({
3609
5842
  publishableKey: options.publishableKey,
3610
5843
  apiUrl: options.apiUrl,
@@ -3612,6 +5845,20 @@ var CommerceClient = class {
3612
5845
  onUnauthorized: options.onUnauthorized,
3613
5846
  onRequestId: options.onRequestId
3614
5847
  });
5848
+ const checkoutApi = new CheckoutApi({
5849
+ publishableKey: options.publishableKey,
5850
+ apiUrl: options.apiUrl,
5851
+ customerToken: options.customerToken,
5852
+ onUnauthorized: options.onUnauthorized,
5853
+ onRequestId: options.onRequestId
5854
+ });
5855
+ const paymentSessionApi = new PaymentSessionApi({
5856
+ publishableKey: options.publishableKey,
5857
+ apiUrl: options.apiUrl,
5858
+ customerToken: options.customerToken,
5859
+ onUnauthorized: options.onUnauthorized,
5860
+ onRequestId: options.onRequestId
5861
+ });
3615
5862
  const api = new BrowserCommerceApi("CommerceClient", {
3616
5863
  publishableKey: options.publishableKey,
3617
5864
  apiUrl: options.apiUrl,
@@ -3620,29 +5867,42 @@ var CommerceClient = class {
3620
5867
  onRequestId: options.onRequestId
3621
5868
  });
3622
5869
  this.product = {
3623
- stockCheck: (params) => api.post(
3624
- COMMERCE_ENDPOINTS.products.stockCheck,
5870
+ stockCheck: (params) => api.requestEndpoint(
5871
+ COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck,
3625
5872
  params
3626
5873
  ),
3627
- stockSnapshot: (params) => api.get(stockSnapshotQuery(params)),
3628
- listingGroups: (params) => api.get(
3629
- listingGroupsCatalogQuery(params)
5874
+ stockSnapshot: (params) => api.requestEndpoint(
5875
+ COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot,
5876
+ void 0,
5877
+ { query: stockSnapshotSearchParams(params) }
5878
+ ),
5879
+ listingGroups: (params) => api.requestEndpoint(
5880
+ COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,
5881
+ void 0,
5882
+ { query: listingGroupsSearchParams(this.withMarket(params)) }
3630
5883
  ),
3631
- listingGroupsCatalog: (params) => api.get(
3632
- listingGroupsCatalogQuery(params)
5884
+ listingGroupsCatalog: (params) => api.requestEndpoint(
5885
+ COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog,
5886
+ void 0,
5887
+ { query: listingGroupsSearchParams(this.withMarket(params)) }
3633
5888
  ),
3634
5889
  listingPage: async (params = {}) => {
3635
5890
  const catalogParams = {
3636
5891
  ...params,
3637
5892
  mode: "catalog"
3638
5893
  };
3639
- const response = await api.get(buildProductListingPageUrl(catalogParams));
3640
- return withProductListingCards(response, catalogParams);
5894
+ const request = buildProductListingPageRequest(
5895
+ this.withMarket(catalogParams)
5896
+ );
5897
+ const response = await api.requestEndpoint(request.operation, void 0, { query: request.query });
5898
+ return withProductListingCards(response, this.withMarket(catalogParams));
3641
5899
  },
3642
5900
  detail: async (params) => {
3643
5901
  try {
3644
- const product = await api.get(
3645
- productDetailQuery(params)
5902
+ const product = await api.requestEndpoint(
5903
+ COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,
5904
+ void 0,
5905
+ { query: productDetailSearchParams(this.withMarket(params)) }
3646
5906
  );
3647
5907
  return { found: true, product };
3648
5908
  } catch (err) {
@@ -3653,8 +5913,10 @@ var CommerceClient = class {
3653
5913
  },
3654
5914
  detailCatalog: async (params) => {
3655
5915
  try {
3656
- const product = await api.get(
3657
- productDetailCatalogQuery(params)
5916
+ const product = await api.requestEndpoint(
5917
+ COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog,
5918
+ void 0,
5919
+ { query: productDetailSearchParams(this.withMarket(params)) }
3658
5920
  );
3659
5921
  return { found: true, product };
3660
5922
  } catch (err) {
@@ -3664,39 +5926,51 @@ var CommerceClient = class {
3664
5926
  }
3665
5927
  }
3666
5928
  };
3667
- this.cart = {
3668
- create: cartApi.createCart.bind(cartApi),
3669
- get: cartApi.getCart.bind(cartApi),
5929
+ this.carts = {
5930
+ create: (params) => cartApi.create(this.withMarket(params ?? {})),
5931
+ retrieve: cartApi.retrieve.bind(cartApi),
3670
5932
  addItem: cartApi.addItem.bind(cartApi),
3671
5933
  updateItem: cartApi.updateItem.bind(cartApi),
3672
5934
  removeItem: cartApi.removeItem.bind(cartApi),
3673
- applyDiscount: cartApi.applyDiscount.bind(cartApi),
3674
- removeDiscount: cartApi.removeDiscount.bind(cartApi),
3675
- clear: cartApi.clearCart.bind(cartApi),
5935
+ updateDiscountCodes: cartApi.updateDiscountCodes.bind(cartApi),
5936
+ updateAttributes: cartApi.updateAttributes.bind(cartApi),
5937
+ clear: cartApi.clear.bind(cartApi),
3676
5938
  merge: cartApi.merge.bind(cartApi),
3677
5939
  mine: cartApi.mine.bind(cartApi)
3678
5940
  };
3679
5941
  this.orders = {
3680
- checkout: (params) => {
3681
- const { body, idempotencyKey } = splitIdempotencyKey(params);
3682
- return api.post(
3683
- "/api/orders/checkout",
3684
- body,
3685
- idempotencyRequestOptions(idempotencyKey)
3686
- );
3687
- },
3688
5942
  listMine: (params) => options.customerAuth.getMyOrders(params)
3689
5943
  };
5944
+ this.checkouts = {
5945
+ create: checkoutApi.create.bind(checkoutApi),
5946
+ retrieve: checkoutApi.retrieve.bind(checkoutApi)
5947
+ };
5948
+ this.paymentSessions = {
5949
+ create: paymentSessionApi.create.bind(paymentSessionApi),
5950
+ retrieve: (params) => paymentSessionApi.retrieve(params),
5951
+ cancel: (params) => paymentSessionApi.cancel(params)
5952
+ };
3690
5953
  this.discounts = {
3691
- validate: (params) => api.post("/api/discounts/validate", params)
5954
+ validate: (params) => api.requestEndpoint(
5955
+ COMMERCE_ENDPOINT_OPERATIONS.discounts.validate,
5956
+ params
5957
+ )
3692
5958
  };
3693
5959
  this.shipping = {
3694
- calculate: (params) => api.post(
3695
- "/api/shipping-policies/calculate",
5960
+ calculate: (params) => api.requestEndpoint(
5961
+ COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate,
3696
5962
  params
3697
5963
  )
3698
5964
  };
3699
5965
  }
5966
+ getDefaultMarket() {
5967
+ return this.market;
5968
+ }
5969
+ withMarket(params) {
5970
+ const defaultMarket = this.market?.trim();
5971
+ if (!defaultMarket || params.market?.trim()) return params;
5972
+ return { ...params, market: defaultMarket };
5973
+ }
3700
5974
  };
3701
5975
 
3702
5976
  // src/core/events/events-client.ts
@@ -3716,7 +5990,17 @@ var EventsClient = class {
3716
5990
  getRange(params) {
3717
5991
  return this.execute(
3718
5992
  buildRangeEndpoint(params),
3719
- "GET",
5993
+ resolveOperationMethod(EVENTS_ENDPOINT_OPERATIONS.occurrences.range),
5994
+ void 0,
5995
+ { useCustomerAuth: false }
5996
+ );
5997
+ }
5998
+ getAdmissionAvailability(params) {
5999
+ return this.execute(
6000
+ buildAdmissionAvailabilityEndpoint(params),
6001
+ resolveOperationMethod(
6002
+ EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability
6003
+ ),
3720
6004
  void 0,
3721
6005
  { useCustomerAuth: false }
3722
6006
  );
@@ -3745,11 +6029,11 @@ var EventsClient = class {
3745
6029
  { useCustomerAuth: false }
3746
6030
  );
3747
6031
  }
3748
- async execute(endpoint, method, body, options = {}) {
6032
+ async execute(endpoint2, method, body, options = {}) {
3749
6033
  const useCustomerAuth = options.useCustomerAuth === true;
3750
6034
  const token = useCustomerAuth ? typeof this.customerToken === "function" ? this.customerToken() : this.customerToken : void 0;
3751
6035
  try {
3752
- const response = await httpFetch(endpoint, {
6036
+ const response = await httpFetch(endpoint2, {
3753
6037
  method,
3754
6038
  apiUrl: this.apiUrl,
3755
6039
  publishableKey: this.publishableKey,
@@ -3758,7 +6042,7 @@ var EventsClient = class {
3758
6042
  ...body !== void 0 && { body: JSON.stringify(body) }
3759
6043
  });
3760
6044
  this.onRequestId?.(response.headers.get("x-request-id") ?? null);
3761
- return parseApiResponse(response, endpoint);
6045
+ return parseApiResponse(response, endpoint2);
3762
6046
  } catch (err) {
3763
6047
  const id = err instanceof SDKError ? err.requestId ?? null : null;
3764
6048
  this.onRequestId?.(id);
@@ -3797,7 +6081,17 @@ function buildRangeEndpoint(params) {
3797
6081
  appendValues(urlParams, "categorySlug", params.categorySlug);
3798
6082
  appendValues(urlParams, "tag", params.tag);
3799
6083
  appendValues(urlParams, "tagSlug", params.tagSlug);
3800
- return `/api/event-occurrences/range?${urlParams.toString()}`;
6084
+ return resolveOperationPath(EVENTS_ENDPOINT_OPERATIONS.occurrences.range, {
6085
+ query: urlParams
6086
+ });
6087
+ }
6088
+ function buildAdmissionAvailabilityEndpoint(params) {
6089
+ const urlParams = new URLSearchParams();
6090
+ urlParams.set("occurrence", params.occurrence);
6091
+ return resolveOperationPath(
6092
+ EVENTS_ENDPOINT_OPERATIONS.occurrences.admissionAvailability,
6093
+ { query: urlParams }
6094
+ );
3801
6095
  }
3802
6096
  function formatDateParam(value) {
3803
6097
  return value instanceof Date ? value.toISOString() : value;
@@ -3810,15 +6104,62 @@ function appendValues(params, key, value) {
3810
6104
  }
3811
6105
  }
3812
6106
 
6107
+ // src/core/market/market-discovery.ts
6108
+ function toMarketDTO(row) {
6109
+ return {
6110
+ id: row.id,
6111
+ handle: row.handle,
6112
+ name: row.name,
6113
+ countryCode: row.countryCode,
6114
+ targetCountries: (row.targetCountries ?? []).map((c) => c.countryCode),
6115
+ currency: row.currency,
6116
+ isPrimary: row.isPrimary === true,
6117
+ isActive: row.isActive === true
6118
+ };
6119
+ }
6120
+ var MarketDiscovery = class {
6121
+ constructor(read) {
6122
+ this.read = read;
6123
+ }
6124
+ async list() {
6125
+ const res = await this.read({
6126
+ where: { isActive: { equals: true } },
6127
+ limit: 100
6128
+ });
6129
+ if (res.hasNextPage) {
6130
+ console.warn(
6131
+ "[markets.list] more than 100 active markets; results truncated to 100."
6132
+ );
6133
+ }
6134
+ return res.docs.map(toMarketDTO);
6135
+ }
6136
+ async default() {
6137
+ const res = await this.read({
6138
+ where: { isPrimary: { equals: true }, isActive: { equals: true } },
6139
+ limit: 1
6140
+ });
6141
+ const row = res.docs[0];
6142
+ return row ? toMarketDTO(row) : null;
6143
+ }
6144
+ };
6145
+
3813
6146
  // src/core/client/client.ts
3814
6147
  var BrowserMembershipApi = class extends CustomerScopedApi {
3815
6148
  me() {
3816
- return this.request(MEMBERSHIP_ENDPOINTS.me, {
3817
- method: "GET"
3818
- });
6149
+ return this.requestEndpoint(
6150
+ MEMBERSHIP_ENDPOINT_OPERATIONS.me
6151
+ );
6152
+ }
6153
+ cancel(params) {
6154
+ const { id, immediate } = params;
6155
+ return this.requestEndpoint(
6156
+ MEMBERSHIP_ENDPOINT_OPERATIONS.cancel,
6157
+ immediate !== void 0 ? { immediate } : {},
6158
+ { pathParams: { id } }
6159
+ );
3819
6160
  }
3820
6161
  };
3821
- var Client = class {
6162
+ var Client = class _Client {
3822
6163
  constructor(options) {
3823
6164
  this.lastRequestId = null;
3824
6165
  const publishableKey = options.publishableKey;
@@ -3850,6 +6191,7 @@ var Client = class {
3850
6191
  this.commerce = new CommerceClient({
3851
6192
  publishableKey: this.config.publishableKey,
3852
6193
  apiUrl: this.config.apiUrl,
6194
+ market: this.config.market,
3853
6195
  customerToken: () => this.customer.auth.getToken(),
3854
6196
  onUnauthorized,
3855
6197
  onRequestId,
@@ -3882,6 +6224,9 @@ var Client = class {
3882
6224
  onRequestId,
3883
6225
  this.config.apiUrl
3884
6226
  );
6227
+ this.markets = new MarketDiscovery(
6228
+ (options2) => this.collections.from("markets").find(options2)
6229
+ );
3885
6230
  const membershipApi = new BrowserMembershipApi("MembershipApi", {
3886
6231
  publishableKey: this.config.publishableKey,
3887
6232
  apiUrl: this.config.apiUrl,
@@ -3890,12 +6235,23 @@ var Client = class {
3890
6235
  onRequestId
3891
6236
  });
3892
6237
  this.memberships = {
3893
- me: membershipApi.me.bind(membershipApi)
6238
+ me: membershipApi.me.bind(membershipApi),
6239
+ cancel: membershipApi.cancel.bind(membershipApi)
3894
6240
  };
3895
6241
  }
3896
6242
  getState() {
3897
6243
  return { ...this.state };
3898
6244
  }
6245
+ withMarket(market) {
6246
+ return new _Client({
6247
+ ...this.config,
6248
+ customer: this.config.customer?.persist === false ? {
6249
+ ...this.config.customer,
6250
+ token: this.customer.auth.getToken() ?? void 0
6251
+ } : this.config.customer,
6252
+ market
6253
+ });
6254
+ }
3899
6255
  getConfig() {
3900
6256
  return { ...this.config };
3901
6257
  }
@@ -3961,6 +6317,7 @@ var COMMERCE_NOTIFICATION_EVENTS = [
3961
6317
  "returnRequested",
3962
6318
  "returnApproved",
3963
6319
  "returnRejected",
6320
+ "returnCanceled",
3964
6321
  "returnCompleted"
3965
6322
  ];
3966
6323
  function isStringOrNumber(value) {
@@ -4049,7 +6406,7 @@ function isCommerceNotificationWebhookEvent(event) {
4049
6406
  if (notification.event === "fulfillmentShipped") {
4050
6407
  return sourceCollection === "fulfillments" && matchesOptionalId(data.fulfillmentId, sourceId) && typeof notification.fulfillmentId === "string" && notification.fulfillmentId.length > 0 && matchesOptionalId(notification.fulfillmentId, sourceId) && matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) && matchesOptionalId(changeSourceId, notification.fulfillmentId);
4051
6408
  }
4052
- if (notification.event === "returnRequested" || notification.event === "returnApproved" || notification.event === "returnRejected" || notification.event === "returnCompleted") {
6409
+ if (notification.event === "returnRequested" || notification.event === "returnApproved" || notification.event === "returnRejected" || notification.event === "returnCanceled" || notification.event === "returnCompleted") {
4053
6410
  return sourceCollection === "returns" && matchesOptionalId(data.returnId, sourceId) && typeof notification.returnId === "string" && notification.returnId.length > 0 && matchesOptionalId(notification.returnId, sourceId) && matchesOptionalId(data.returnId, notification.returnId) && matchesOptionalId(changeSourceId, notification.returnId);
4054
6411
  }
4055
6412
  return false;
@@ -4083,8 +6440,8 @@ function createCommerceEmailWebhookHandler(handlers) {
4083
6440
  function isWebhookCollection(event, collection) {
4084
6441
  return isValidWebhookEvent(event) && event.collection === collection;
4085
6442
  }
4086
- function isWebhookOperation(event, operation) {
4087
- return isValidWebhookEvent(event) && event.operation === operation;
6443
+ function isWebhookOperation(event, operation2) {
6444
+ return isValidWebhookEvent(event) && event.operation === operation2;
4088
6445
  }
4089
6446
  var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
4090
6447
  function isRecord2(value) {
@@ -4111,7 +6468,7 @@ function createCustomerAuthWebhookHandler(handlers) {
4111
6468
  await handlers.unhandled?.(event);
4112
6469
  };
4113
6470
  }
4114
- async function verifySignature(payload, secret, signature, timestamp, deliveryId) {
6471
+ async function verifySignature(payload, secret, signature, timestamp2, deliveryId) {
4115
6472
  const encoder = new TextEncoder();
4116
6473
  const key = await crypto.subtle.importKey(
4117
6474
  "raw",
@@ -4130,12 +6487,12 @@ async function verifySignature(payload, secret, signature, timestamp, deliveryId
4130
6487
  "HMAC",
4131
6488
  key,
4132
6489
  sigBytes,
4133
- encoder.encode(`${timestamp}.${deliveryId}.${payload}`)
6490
+ encoder.encode(`${timestamp2}.${deliveryId}.${payload}`)
4134
6491
  );
4135
6492
  }
4136
- function timestampIsFresh(timestamp, toleranceSeconds) {
4137
- if (!/^\d+$/.test(timestamp)) return false;
4138
- const timestampMs = Number(timestamp);
6493
+ function timestampIsFresh(timestamp2, toleranceSeconds) {
6494
+ if (!/^\d+$/.test(timestamp2)) return false;
6495
+ const timestampMs = Number(timestamp2);
4139
6496
  if (!Number.isFinite(timestampMs)) return false;
4140
6497
  const skewMs = Math.abs(Date.now() - timestampMs);
4141
6498
  return skewMs <= toleranceSeconds * 1e3;
@@ -4145,14 +6502,14 @@ async function handleWebhook(request, handler, options) {
4145
6502
  const rawBody = await request.text();
4146
6503
  if (options?.secret) {
4147
6504
  const signature = request.headers.get("x-webhook-signature") || "";
4148
- const timestamp = request.headers.get("x-webhook-timestamp") || "";
6505
+ const timestamp2 = request.headers.get("x-webhook-timestamp") || "";
4149
6506
  const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
4150
6507
  const toleranceSeconds = options.toleranceSeconds ?? 300;
4151
- const valid = Boolean(timestamp && deliveryId) && timestampIsFresh(timestamp, toleranceSeconds) && await verifySignature(
6508
+ const valid = Boolean(timestamp2 && deliveryId) && timestampIsFresh(timestamp2, toleranceSeconds) && await verifySignature(
4152
6509
  rawBody,
4153
6510
  options.secret,
4154
6511
  signature,
4155
- timestamp,
6512
+ timestamp2,
4156
6513
  deliveryId
4157
6514
  );
4158
6515
  if (!valid) {
@@ -4216,12 +6573,21 @@ var INTERNAL_COLLECTIONS = [
4216
6573
  "analytics-event-schemas",
4217
6574
  "subscriptions",
4218
6575
  "billing-history",
6576
+ "usage-rate-cards",
6577
+ "usage-invoices",
4219
6578
  "inventory-reservations",
4220
6579
  "inventory-adjustments",
6580
+ "payment-sessions",
6581
+ "payment-event-inbox",
6582
+ "payment-refund-attempts",
6583
+ "portone-payment-interactions",
4221
6584
  "commerce-notification-intents",
6585
+ "commerce-idempotency-records",
4222
6586
  "product-collection-items",
4223
6587
  "order-status-logs",
6588
+ "fulfillment-events",
4224
6589
  "tenant-commerce-config",
6590
+ "customer-oauth-clients",
4225
6591
  "api-keys",
4226
6592
  "personal-access-tokens",
4227
6593
  "tenant-entitlements",
@@ -4229,12 +6595,18 @@ var INTERNAL_COLLECTIONS = [
4229
6595
  "direct-upload-sessions",
4230
6596
  "webhook-events",
4231
6597
  "webhook-deliveries",
6598
+ "webhook-outbox-deliveries",
4232
6599
  "audit-logs",
4233
6600
  "plans",
4234
6601
  "webhooks",
6602
+ "custom-field-definitions",
4235
6603
  "event-registrations",
6604
+ "event-admission-holds",
6605
+ "event-admission-types",
4236
6606
  "customer-payment-methods",
4237
- "tenant-payment-credentials"
6607
+ "tenant-payment-credentials",
6608
+ "commerce-payment-accounts",
6609
+ "payment-provider-customer-aliases"
4238
6610
  ];
4239
6611
  var COLLECTIONS = [
4240
6612
  "tenants",
@@ -4293,6 +6665,7 @@ var COLLECTIONS = [
4293
6665
  "event-occurrences",
4294
6666
  "event-tags",
4295
6667
  "membership-plans",
6668
+ "membership-plan-prices",
4296
6669
  "customer-memberships"
4297
6670
  ];
4298
6671
  var SERVER_ONLY_COLLECTIONS = [
@@ -4301,9 +6674,14 @@ var SERVER_ONLY_COLLECTIONS = [
4301
6674
  "images",
4302
6675
  "videos",
4303
6676
  "orders",
6677
+ "order-tags",
4304
6678
  "order-items",
4305
6679
  "returns",
4306
6680
  "return-items",
6681
+ "refunds",
6682
+ "refund-line-items",
6683
+ "order-edit-sessions",
6684
+ "order-staged-changes",
4307
6685
  "fulfillment-orders",
4308
6686
  "fulfillment-order-items",
4309
6687
  "fulfillments",
@@ -4316,6 +6694,8 @@ var SERVER_ONLY_COLLECTIONS = [
4316
6694
  "cart-items",
4317
6695
  "checkouts",
4318
6696
  "checkout-items",
6697
+ "draft-orders",
6698
+ "draft-order-items",
4319
6699
  "posts",
4320
6700
  "comments",
4321
6701
  "reactions",
@@ -4711,9 +7091,9 @@ var generateOrderNumber = () => {
4711
7091
  const year = now.getFullYear().toString().slice(-2);
4712
7092
  const month = (now.getMonth() + 1).toString().padStart(2, "0");
4713
7093
  const day = now.getDate().toString().padStart(2, "0");
4714
- const array = new Uint32Array(1);
4715
- globalThis.crypto.getRandomValues(array);
4716
- const random = ((array[0] ?? 0) % 1e6).toString().padStart(6, "0");
7094
+ const array2 = new Uint32Array(1);
7095
+ globalThis.crypto.getRandomValues(array2);
7096
+ const random = ((array2[0] ?? 0) % 1e6).toString().padStart(6, "0");
4717
7097
  return `${year}${month}${day}${random}`;
4718
7098
  };
4719
7099
 
@@ -4764,7 +7144,7 @@ function createAnalytics(config) {
4764
7144
  }, destroy() {
4765
7145
  } };
4766
7146
  }
4767
- const endpoint = config.endpoint ?? `${resolveApiUrl()}/api/analytics/collect`;
7147
+ const endpoint2 = config.endpoint ?? `${resolveApiUrl()}/api/analytics/collect`;
4768
7148
  const respectDnt = config.respectDnt !== false;
4769
7149
  function isDntActive() {
4770
7150
  if (!respectDnt) return false;
@@ -4805,10 +7185,10 @@ function createAnalytics(config) {
4805
7185
  try {
4806
7186
  if (typeof navigator.sendBeacon === "function") {
4807
7187
  const blob = new Blob([body], { type: "text/plain" });
4808
- const sent = navigator.sendBeacon(endpoint, blob);
7188
+ const sent = navigator.sendBeacon(endpoint2, blob);
4809
7189
  if (sent) return;
4810
7190
  }
4811
- fetch(endpoint, {
7191
+ fetch(endpoint2, {
4812
7192
  method: "POST",
4813
7193
  keepalive: true,
4814
7194
  headers: { "Content-Type": "application/json" },
@@ -4958,11 +7338,11 @@ export {
4958
7338
  ApiError,
4959
7339
  AuthError,
4960
7340
  COLLECTIONS,
7341
+ COMMERCE_ERROR_CODES,
4961
7342
  COMMERCE_NOTIFICATION_EVENTS,
4962
7343
  COMMERCE_NOTIFICATION_EVENT_TYPE,
4963
7344
  COMMERCE_NOTIFICATION_OPERATION,
4964
7345
  CUSTOMER_PASSWORD_RESET_OPERATION,
4965
- CartApi,
4966
7346
  CommerceClient,
4967
7347
  CommunityClient,
4968
7348
  ConfigError,
@@ -4970,10 +7350,12 @@ export {
4970
7350
  ContentClient,
4971
7351
  CustomerAuth,
4972
7352
  CustomerNamespace,
7353
+ CustomerOAuth,
4973
7354
  EventsClient,
4974
7355
  GoneError,
4975
7356
  IMAGE_SIZES,
4976
7357
  INTERNAL_COLLECTIONS,
7358
+ MAX_CART_LINE_ADMISSIONS,
4977
7359
  NetworkError,
4978
7360
  NotFoundError,
4979
7361
  ORDER_CHANGED_EVENT_TYPE,
@@ -4991,6 +7373,7 @@ export {
4991
7373
  TimeoutError,
4992
7374
  UsageLimitError,
4993
7375
  ValidationError,
7376
+ assertCommerceIdempotencyKey,
4994
7377
  buildProductHref,
4995
7378
  buildProductListingCard,
4996
7379
  buildProductListingGroupProjection,
@@ -5001,6 +7384,7 @@ export {
5001
7384
  createAuthError,
5002
7385
  createClient2 as createClient,
5003
7386
  createCommerceEmailWebhookHandler,
7387
+ createCommerceIdempotencyKey,
5004
7388
  createCommerceNotificationWebhookHandler,
5005
7389
  createConflictError,
5006
7390
  createCustomerAuthWebhookHandler,
@@ -5031,7 +7415,9 @@ export {
5031
7415
  handleWebhook,
5032
7416
  isApiError,
5033
7417
  isAuthError,
7418
+ isCommerceIdempotencyKey,
5034
7419
  isCommerceNotificationWebhookEvent,
7420
+ isCommerceSDKError,
5035
7421
  isConfigError,
5036
7422
  isConflictError,
5037
7423
  isCustomerPasswordResetWebhookEvent,