@01.software/sdk 0.48.0 → 0.51.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 (74) hide show
  1. package/CHANGELOG.md +157 -1
  2. package/MIGRATION.md +56 -0
  3. package/README.md +276 -49
  4. package/dist/client.cjs +375 -161
  5. package/dist/client.cjs.map +1 -1
  6. package/dist/client.d.cts +7 -6
  7. package/dist/client.d.ts +7 -6
  8. package/dist/client.js +375 -161
  9. package/dist/client.js.map +1 -1
  10. package/dist/{collection-client-CBup9yOx.d.cts → collection-client-CWAeuzV4.d.cts} +6 -4
  11. package/dist/{collection-client-D3ExJU-7.d.ts → collection-client-hYvVfHIm.d.ts} +6 -4
  12. package/dist/{const-k9gHylYa.d.ts → const-D8LixhAJ.d.cts} +5 -5
  13. package/dist/{const-BXEi1Kix.d.cts → const-JD8obaKg.d.ts} +5 -5
  14. package/dist/embedded-admin/server.cjs +306 -0
  15. package/dist/embedded-admin/server.cjs.map +1 -0
  16. package/dist/embedded-admin/server.d.cts +33 -0
  17. package/dist/embedded-admin/server.d.ts +33 -0
  18. package/dist/embedded-admin/server.js +288 -0
  19. package/dist/embedded-admin/server.js.map +1 -0
  20. package/dist/embedded-admin.cjs +400 -0
  21. package/dist/embedded-admin.cjs.map +1 -0
  22. package/dist/embedded-admin.d.cts +61 -0
  23. package/dist/embedded-admin.d.ts +61 -0
  24. package/dist/embedded-admin.js +377 -0
  25. package/dist/embedded-admin.js.map +1 -0
  26. package/dist/errors.cjs +64 -15
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts +13 -4
  29. package/dist/errors.d.ts +13 -4
  30. package/dist/errors.js +64 -15
  31. package/dist/errors.js.map +1 -1
  32. package/dist/{index-BCM9CTL7.d.cts → index-B0Hjh3Ey.d.ts} +72 -10
  33. package/dist/{index-CHGGkcLj.d.ts → index-Bu0kCc6o.d.cts} +72 -10
  34. package/dist/index.cjs +470 -429
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +9 -67
  37. package/dist/index.d.ts +9 -67
  38. package/dist/index.js +470 -429
  39. package/dist/index.js.map +1 -1
  40. package/dist/{payload-types-B6AZQcB7.d.cts → payload-types-BOsckg8B.d.cts} +396 -57
  41. package/dist/{payload-types-B6AZQcB7.d.ts → payload-types-BOsckg8B.d.ts} +396 -57
  42. package/dist/query.cjs +115 -70
  43. package/dist/query.cjs.map +1 -1
  44. package/dist/query.d.cts +5 -5
  45. package/dist/query.d.ts +5 -5
  46. package/dist/query.js +115 -70
  47. package/dist/query.js.map +1 -1
  48. package/dist/realtime.d.cts +2 -2
  49. package/dist/realtime.d.ts +2 -2
  50. package/dist/server.cjs +591 -186
  51. package/dist/server.cjs.map +1 -1
  52. package/dist/server.d.cts +8 -7
  53. package/dist/server.d.ts +8 -7
  54. package/dist/server.js +591 -186
  55. package/dist/server.js.map +1 -1
  56. package/dist/storefront-cache.cjs +22 -0
  57. package/dist/storefront-cache.cjs.map +1 -1
  58. package/dist/storefront-cache.js +22 -0
  59. package/dist/storefront-cache.js.map +1 -1
  60. package/dist/{types-ByD2zii1.d.ts → types-5ZlcAFuU.d.ts} +2 -2
  61. package/dist/{types-8us-_C-Q.d.cts → types-B14sEt1z.d.cts} +2 -2
  62. package/dist/{types-CM2je9Kw.d.cts → types-Bj8j7VHU.d.ts} +107 -26
  63. package/dist/{types-DbA5V3mt.d.ts → types-CM5qiR2k.d.cts} +107 -26
  64. package/dist/ui/form.d.cts +1 -1
  65. package/dist/ui/form.d.ts +1 -1
  66. package/dist/ui/video.d.cts +1 -1
  67. package/dist/ui/video.d.ts +1 -1
  68. package/dist/webhook.cjs +124 -80
  69. package/dist/webhook.cjs.map +1 -1
  70. package/dist/webhook.d.cts +21 -5
  71. package/dist/webhook.d.ts +21 -5
  72. package/dist/webhook.js +124 -80
  73. package/dist/webhook.js.map +1 -1
  74. package/package.json +27 -5
@@ -25,6 +25,24 @@ __export(storefront_cache_exports, {
25
25
  module.exports = __toCommonJS(storefront_cache_exports);
26
26
 
27
27
  // src/core/errors.ts
28
+ var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
29
+ var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
30
+ function defineSDKErrorBrand(error) {
31
+ Object.defineProperty(error, SDK_ERROR_BRAND, {
32
+ value: true,
33
+ enumerable: false,
34
+ configurable: false,
35
+ writable: false
36
+ });
37
+ }
38
+ function defineSDKErrorType(error, type) {
39
+ Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {
40
+ value: type,
41
+ enumerable: false,
42
+ configurable: false,
43
+ writable: false
44
+ });
45
+ }
28
46
  var SDKError = class extends Error {
29
47
  constructor(code, message, status, details, userMessage, suggestion, requestId) {
30
48
  super(message);
@@ -35,6 +53,7 @@ var SDKError = class extends Error {
35
53
  this.userMessage = userMessage;
36
54
  this.suggestion = suggestion;
37
55
  this.requestId = requestId;
56
+ defineSDKErrorBrand(this);
38
57
  if (Error.captureStackTrace) {
39
58
  Error.captureStackTrace(this, new.target);
40
59
  }
@@ -55,6 +74,7 @@ var SDKError = class extends Error {
55
74
  ...this.kind !== void 0 && { kind: this.kind },
56
75
  ...this.reason !== void 0 && { reason: this.reason },
57
76
  ...this.rawReason !== void 0 && { rawReason: this.rawReason },
77
+ ...this.apiReason !== void 0 && { apiReason: this.apiReason },
58
78
  ...this.retryable !== void 0 && { retryable: this.retryable },
59
79
  ...this.retryAfter !== void 0 && { retryAfter: this.retryAfter }
60
80
  };
@@ -100,6 +120,7 @@ var COMMERCE_ERROR_CODES = [
100
120
  "payment_session_not_cancelable",
101
121
  "payment_session_conflict",
102
122
  "provider_identity_mismatch",
123
+ "managed_refund_attestation_forbidden",
103
124
  "payment_method_unavailable",
104
125
  "provider_unavailable",
105
126
  "lock_timeout",
@@ -171,6 +192,7 @@ var ValidationError = class extends SDKError {
171
192
  constructor(message, details, userMessage, suggestion, status = 400) {
172
193
  super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
173
194
  this.name = "ValidationError";
195
+ defineSDKErrorType(this, "ValidationError");
174
196
  }
175
197
  };
176
198
  var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storefront-cache.ts","../src/core/errors.ts","../src/utils/storefront-cache.ts"],"sourcesContent":["export * from './utils/storefront-cache'\n","export class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'capacity_exceeded',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!(error instanceof SDKError) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (error instanceof ValidationError) return true\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return error instanceof ServiceUnavailableError\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return error instanceof UsageLimitError\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return error instanceof PermissionError\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return error instanceof NotFoundError\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return error instanceof ConflictError\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createValidationError } from '../errors'\n\nconst CACHE_RESOURCE_VERSION = 'storefront:v1'\n\nexport type StorefrontCacheScope = {\n /**\n * Tenant identifier for the public storefront read.\n */\n tenantId: string | number\n /**\n * Stable, non-secret scope for publishable-key variance. Use a short key id,\n * key fingerprint, or \"default\" when a tenant has one public cache view.\n */\n publishableKeyScope?: string | number\n}\n\nexport type StorefrontCacheProductDetailIdentity =\n | { id: string | number; slug?: never }\n | { id?: never; slug: string }\n\nfunction invalidResourceInput(message: string) {\n return createValidationError(message)\n}\n\nfunction encodeResourceSegment(value: unknown, label: string): string {\n if (typeof value !== 'string' && typeof value !== 'number') {\n throw invalidResourceInput(`${label} must be a string or number`)\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw invalidResourceInput(`${label} must be a finite number`)\n }\n const segment = String(value).trim()\n if (!segment) {\n throw invalidResourceInput(`${label} must not be empty`)\n }\n return encodeURIComponent(segment)\n}\n\nfunction scopedResource(scope: StorefrontCacheScope, resource: string): string {\n if (scope == null || typeof scope !== 'object') {\n throw invalidResourceInput('cache scope must be an object')\n }\n const candidate = scope as {\n tenantId?: unknown\n publishableKeyScope?: unknown\n }\n const tenantId = encodeResourceSegment(candidate.tenantId, 'tenantId')\n const publishableKeyScopeValue =\n candidate.publishableKeyScope === undefined\n ? 'default'\n : candidate.publishableKeyScope\n const publishableKeyScope = encodeResourceSegment(\n publishableKeyScopeValue,\n 'publishableKeyScope',\n )\n\n return `${CACHE_RESOURCE_VERSION}:tenant:${tenantId}:key:${publishableKeyScope}:resource:${resource}`\n}\n\nfunction listResource(scope: StorefrontCacheScope, collection: string): string {\n return scopedResource(scope, `${collection}:list`)\n}\n\nfunction idDetailResource(\n scope: StorefrontCacheScope,\n collection: string,\n id: string | number,\n): string {\n return scopedResource(\n scope,\n `${collection}:detail:id:${encodeResourceSegment(id, 'resource id')}`,\n )\n}\n\nfunction productDetailResource(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n): string {\n const candidate = (identity ?? {}) as {\n id?: unknown\n slug?: unknown\n }\n const hasIdField = candidate.id !== undefined\n const hasSlugField = candidate.slug !== undefined\n\n if (hasIdField === hasSlugField) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n\n if (hasIdField) {\n if (\n (typeof candidate.id !== 'string' && typeof candidate.id !== 'number') ||\n String(candidate.id).trim() === ''\n ) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return idDetailResource(scope, 'products', candidate.id as string | number)\n }\n if (typeof candidate.slug !== 'string' || candidate.slug.trim() === '') {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return scopedResource(\n scope,\n `products:detail:slug:${encodeResourceSegment(\n candidate.slug as string,\n 'resource slug',\n )}`,\n )\n}\n\nexport const storefrontCacheResources = {\n productListing(scope: StorefrontCacheScope): string {\n return listResource(scope, 'products')\n },\n productDetail(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n ): string {\n return productDetailResource(scope, identity)\n },\n} as const\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAalC,YACE,MACA,SACA,QACA,SACA,aACA,YACA,WACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,YAAY;AAEjB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,SAAS,UAAa,EAAE,MAAM,KAAK,KAAK;AAAA,MACjD,GAAI,KAAK,WAAW,UAAa,EAAE,QAAQ,KAAK,OAAO;AAAA,MACvD,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,IACrE;AAAA,EACF;AACF;AAOO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqBA,IAAM,0BAA+C,IAAI;AAAA,EACvD;AACF;AAkIO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YACE,SACA,SACA,aACA,YACA,SAAS,KACT;AACA,UAAM,oBAAoB,SAAS,QAAQ,SAAS,aAAa,UAAU;AAC3E,SAAK,OAAO;AAAA,EACd;AACF;AAiSO,IAAM,wBAAwB,CACnC,SACA,SACA,aACA,YACA,WACG,IAAI,gBAAgB,SAAS,SAAS,aAAa,YAAY,MAAM;;;AChnB1E,IAAM,yBAAyB;AAkB/B,SAAS,qBAAqB,SAAiB;AAC7C,SAAO,sBAAsB,OAAO;AACtC;AAEA,SAAS,sBAAsB,OAAgB,OAAuB;AACpE,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,UAAM,qBAAqB,GAAG,KAAK,6BAA6B;AAAA,EAClE;AACA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,qBAAqB,GAAG,KAAK,0BAA0B;AAAA,EAC/D;AACA,QAAM,UAAU,OAAO,KAAK,EAAE,KAAK;AACnC,MAAI,CAAC,SAAS;AACZ,UAAM,qBAAqB,GAAG,KAAK,oBAAoB;AAAA,EACzD;AACA,SAAO,mBAAmB,OAAO;AACnC;AAEA,SAAS,eAAe,OAA6B,UAA0B;AAC7E,MAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,UAAM,qBAAqB,+BAA+B;AAAA,EAC5D;AACA,QAAM,YAAY;AAIlB,QAAM,WAAW,sBAAsB,UAAU,UAAU,UAAU;AACrE,QAAM,2BACJ,UAAU,wBAAwB,SAC9B,YACA,UAAU;AAChB,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AAEA,SAAO,GAAG,sBAAsB,WAAW,QAAQ,QAAQ,mBAAmB,aAAa,QAAQ;AACrG;AAEA,SAAS,aAAa,OAA6B,YAA4B;AAC7E,SAAO,eAAe,OAAO,GAAG,UAAU,OAAO;AACnD;AAEA,SAAS,iBACP,OACA,YACA,IACQ;AACR,SAAO;AAAA,IACL;AAAA,IACA,GAAG,UAAU,cAAc,sBAAsB,IAAI,aAAa,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,sBACP,OACA,UACQ;AACR,QAAM,YAAa,YAAY,CAAC;AAIhC,QAAM,aAAa,UAAU,OAAO;AACpC,QAAM,eAAe,UAAU,SAAS;AAExC,MAAI,eAAe,cAAc;AAC/B,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY;AACd,QACG,OAAO,UAAU,OAAO,YAAY,OAAO,UAAU,OAAO,YAC7D,OAAO,UAAU,EAAE,EAAE,KAAK,MAAM,IAChC;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,OAAO,YAAY,UAAU,EAAqB;AAAA,EAC5E;AACA,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,KAAK,MAAM,IAAI;AACtE,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,wBAAwB;AAAA,MACtB,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,eAAe,OAAqC;AAClD,WAAO,aAAa,OAAO,UAAU;AAAA,EACvC;AAAA,EACA,cACE,OACA,UACQ;AACR,WAAO,sBAAsB,OAAO,QAAQ;AAAA,EAC9C;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/storefront-cache.ts","../src/core/errors.ts","../src/utils/storefront-cache.ts"],"sourcesContent":["export * from './utils/storefront-cache'\n","const SDK_ERROR_BRAND = Symbol.for('@01.software/sdk/SDKError')\nconst SDK_ERROR_TYPE_BRAND = Symbol.for('@01.software/sdk/SDKError.type')\n\ntype SDKErrorType =\n | 'NetworkError'\n | 'ValidationError'\n | 'ApiError'\n | 'ConfigError'\n | 'TimeoutError'\n | 'GoneError'\n | 'ServiceUnavailableError'\n | 'UsageLimitError'\n | 'AuthError'\n | 'PermissionError'\n | 'NotFoundError'\n | 'ConflictError'\n | 'RateLimitError'\n\nfunction defineSDKErrorBrand(error: SDKError): void {\n Object.defineProperty(error, SDK_ERROR_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nfunction defineSDKErrorType(error: SDKError, type: SDKErrorType): void {\n Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {\n value: type,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nexport class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n /** Machine-readable reason from a non-commerce API response. */\n readonly apiReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n defineSDKErrorBrand(this)\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.apiReason !== undefined && { apiReason: this.apiReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'managed_refund_attestation_forbidden',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'capacity_exceeded',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\n/** @internal Apply a non-commerce reason without canonical-commerce validation. */\nexport function enhanceNonCommerceError(\n error: SDKError,\n reason: unknown,\n): SDKError {\n if (typeof reason === 'string') Object.assign(error, { apiReason: reason })\n return error\n}\n\n/**\n * Read the server-provided machine reason across strict commerce and\n * non-commerce SDK errors. Unknown commerce reasons are returned verbatim.\n */\nexport function getSDKErrorReason(error: SDKError): string | undefined {\n if (error.kind !== 'commerce') return error.apiReason\n return error.reason === 'unknown_commerce_error'\n ? error.rawReason\n : error.reason\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!isSDKError(error) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n defineSDKErrorType(this, 'NetworkError')\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n defineSDKErrorType(this, 'ValidationError')\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n defineSDKErrorType(this, 'ApiError')\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n defineSDKErrorType(this, 'ConfigError')\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n defineSDKErrorType(this, 'TimeoutError')\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n defineSDKErrorType(this, 'GoneError')\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'ServiceUnavailableError')\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n defineSDKErrorType(this, 'UsageLimitError')\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n defineSDKErrorType(this, 'AuthError')\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n defineSDKErrorType(this, 'PermissionError')\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n defineSDKErrorType(this, 'NotFoundError')\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n defineSDKErrorType(this, 'ConflictError')\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'RateLimitError')\n }\n}\n\nfunction hasBrandedSDKErrorShape(error: unknown): error is SDKError {\n if (error === null || typeof error !== 'object') return false\n\n const candidate = error as Record<PropertyKey, unknown>\n return (\n candidate[SDK_ERROR_BRAND] === true &&\n typeof candidate.name === 'string' &&\n typeof candidate.code === 'string' &&\n typeof candidate.message === 'string' &&\n (candidate.status === undefined || typeof candidate.status === 'number') &&\n (candidate.userMessage === undefined ||\n typeof candidate.userMessage === 'string') &&\n (candidate.suggestion === undefined ||\n typeof candidate.suggestion === 'string') &&\n (candidate.requestId === undefined ||\n typeof candidate.requestId === 'string') &&\n (candidate.kind === undefined || candidate.kind === 'commerce') &&\n (candidate.reason === undefined || typeof candidate.reason === 'string') &&\n (candidate.rawReason === undefined ||\n typeof candidate.rawReason === 'string') &&\n (candidate.apiReason === undefined ||\n typeof candidate.apiReason === 'string') &&\n (candidate.retryable === undefined ||\n typeof candidate.retryable === 'boolean') &&\n (candidate.retryAfter === undefined ||\n typeof candidate.retryAfter === 'number') &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nfunction hasSDKErrorType(error: unknown, type: SDKErrorType): boolean {\n return (\n hasBrandedSDKErrorShape(error) &&\n (error as unknown as Record<PropertyKey, unknown>)[SDK_ERROR_TYPE_BRAND] ===\n type\n )\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError || hasBrandedSDKErrorShape(error)\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError || hasSDKErrorType(error, 'NetworkError')\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (\n error instanceof ValidationError ||\n hasSDKErrorType(error, 'ValidationError')\n ) {\n return true\n }\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError || hasSDKErrorType(error, 'ApiError')\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError || hasSDKErrorType(error, 'ConfigError')\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError || hasSDKErrorType(error, 'TimeoutError')\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError || hasSDKErrorType(error, 'GoneError')\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return (\n error instanceof ServiceUnavailableError ||\n hasSDKErrorType(error, 'ServiceUnavailableError')\n )\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return (\n error instanceof UsageLimitError ||\n hasSDKErrorType(error, 'UsageLimitError')\n )\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError || hasSDKErrorType(error, 'AuthError')\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return (\n error instanceof PermissionError ||\n hasSDKErrorType(error, 'PermissionError')\n )\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return (\n error instanceof NotFoundError || hasSDKErrorType(error, 'NotFoundError')\n )\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return (\n error instanceof ConflictError || hasSDKErrorType(error, 'ConflictError')\n )\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return (\n error instanceof RateLimitError || hasSDKErrorType(error, 'RateLimitError')\n )\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createValidationError } from '../errors'\n\nconst CACHE_RESOURCE_VERSION = 'storefront:v1'\n\nexport type StorefrontCacheScope = {\n /**\n * Tenant identifier for the public storefront read.\n */\n tenantId: string | number\n /**\n * Stable, non-secret scope for publishable-key variance. Use a short key id,\n * key fingerprint, or \"default\" when a tenant has one public cache view.\n */\n publishableKeyScope?: string | number\n}\n\nexport type StorefrontCacheProductDetailIdentity =\n | { id: string | number; slug?: never }\n | { id?: never; slug: string }\n\nfunction invalidResourceInput(message: string) {\n return createValidationError(message)\n}\n\nfunction encodeResourceSegment(value: unknown, label: string): string {\n if (typeof value !== 'string' && typeof value !== 'number') {\n throw invalidResourceInput(`${label} must be a string or number`)\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw invalidResourceInput(`${label} must be a finite number`)\n }\n const segment = String(value).trim()\n if (!segment) {\n throw invalidResourceInput(`${label} must not be empty`)\n }\n return encodeURIComponent(segment)\n}\n\nfunction scopedResource(scope: StorefrontCacheScope, resource: string): string {\n if (scope == null || typeof scope !== 'object') {\n throw invalidResourceInput('cache scope must be an object')\n }\n const candidate = scope as {\n tenantId?: unknown\n publishableKeyScope?: unknown\n }\n const tenantId = encodeResourceSegment(candidate.tenantId, 'tenantId')\n const publishableKeyScopeValue =\n candidate.publishableKeyScope === undefined\n ? 'default'\n : candidate.publishableKeyScope\n const publishableKeyScope = encodeResourceSegment(\n publishableKeyScopeValue,\n 'publishableKeyScope',\n )\n\n return `${CACHE_RESOURCE_VERSION}:tenant:${tenantId}:key:${publishableKeyScope}:resource:${resource}`\n}\n\nfunction listResource(scope: StorefrontCacheScope, collection: string): string {\n return scopedResource(scope, `${collection}:list`)\n}\n\nfunction idDetailResource(\n scope: StorefrontCacheScope,\n collection: string,\n id: string | number,\n): string {\n return scopedResource(\n scope,\n `${collection}:detail:id:${encodeResourceSegment(id, 'resource id')}`,\n )\n}\n\nfunction productDetailResource(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n): string {\n const candidate = (identity ?? {}) as {\n id?: unknown\n slug?: unknown\n }\n const hasIdField = candidate.id !== undefined\n const hasSlugField = candidate.slug !== undefined\n\n if (hasIdField === hasSlugField) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n\n if (hasIdField) {\n if (\n (typeof candidate.id !== 'string' && typeof candidate.id !== 'number') ||\n String(candidate.id).trim() === ''\n ) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return idDetailResource(scope, 'products', candidate.id as string | number)\n }\n if (typeof candidate.slug !== 'string' || candidate.slug.trim() === '') {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return scopedResource(\n scope,\n `products:detail:slug:${encodeResourceSegment(\n candidate.slug as string,\n 'resource slug',\n )}`,\n )\n}\n\nexport const storefrontCacheResources = {\n productListing(scope: StorefrontCacheScope): string {\n return listResource(scope, 'products')\n },\n productDetail(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n ): string {\n return productDetailResource(scope, identity)\n },\n} as const\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAM,kBAAkB,uBAAO,IAAI,2BAA2B;AAC9D,IAAM,uBAAuB,uBAAO,IAAI,gCAAgC;AAiBxE,SAAS,oBAAoB,OAAuB;AAClD,SAAO,eAAe,OAAO,iBAAiB;AAAA,IAC5C,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,SAAS,mBAAmB,OAAiB,MAA0B;AACrE,SAAO,eAAe,OAAO,sBAAsB;AAAA,IACjD,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAelC,YACE,MACA,SACA,QACA,SACA,aACA,YACA,WACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,wBAAoB,IAAI;AAExB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,SAAS,UAAa,EAAE,MAAM,KAAK,KAAK;AAAA,MACjD,GAAI,KAAK,WAAW,UAAa,EAAE,QAAQ,KAAK,OAAO;AAAA,MACvD,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,IACrE;AAAA,EACF;AACF;AAOO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqBA,IAAM,0BAA+C,IAAI;AAAA,EACvD;AACF;AAuJO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YACE,SACA,SACA,aACA,YACA,SAAS,KACT;AACA,UAAM,oBAAoB,SAAS,QAAQ,SAAS,aAAa,UAAU;AAC3E,SAAK,OAAO;AACZ,uBAAmB,MAAM,iBAAiB;AAAA,EAC5C;AACF;AAuWO,IAAM,wBAAwB,CACnC,SACA,SACA,aACA,YACA,WACG,IAAI,gBAAgB,SAAS,SAAS,aAAa,YAAY,MAAM;;;ACrvB1E,IAAM,yBAAyB;AAkB/B,SAAS,qBAAqB,SAAiB;AAC7C,SAAO,sBAAsB,OAAO;AACtC;AAEA,SAAS,sBAAsB,OAAgB,OAAuB;AACpE,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,UAAM,qBAAqB,GAAG,KAAK,6BAA6B;AAAA,EAClE;AACA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,qBAAqB,GAAG,KAAK,0BAA0B;AAAA,EAC/D;AACA,QAAM,UAAU,OAAO,KAAK,EAAE,KAAK;AACnC,MAAI,CAAC,SAAS;AACZ,UAAM,qBAAqB,GAAG,KAAK,oBAAoB;AAAA,EACzD;AACA,SAAO,mBAAmB,OAAO;AACnC;AAEA,SAAS,eAAe,OAA6B,UAA0B;AAC7E,MAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,UAAM,qBAAqB,+BAA+B;AAAA,EAC5D;AACA,QAAM,YAAY;AAIlB,QAAM,WAAW,sBAAsB,UAAU,UAAU,UAAU;AACrE,QAAM,2BACJ,UAAU,wBAAwB,SAC9B,YACA,UAAU;AAChB,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AAEA,SAAO,GAAG,sBAAsB,WAAW,QAAQ,QAAQ,mBAAmB,aAAa,QAAQ;AACrG;AAEA,SAAS,aAAa,OAA6B,YAA4B;AAC7E,SAAO,eAAe,OAAO,GAAG,UAAU,OAAO;AACnD;AAEA,SAAS,iBACP,OACA,YACA,IACQ;AACR,SAAO;AAAA,IACL;AAAA,IACA,GAAG,UAAU,cAAc,sBAAsB,IAAI,aAAa,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,sBACP,OACA,UACQ;AACR,QAAM,YAAa,YAAY,CAAC;AAIhC,QAAM,aAAa,UAAU,OAAO;AACpC,QAAM,eAAe,UAAU,SAAS;AAExC,MAAI,eAAe,cAAc;AAC/B,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY;AACd,QACG,OAAO,UAAU,OAAO,YAAY,OAAO,UAAU,OAAO,YAC7D,OAAO,UAAU,EAAE,EAAE,KAAK,MAAM,IAChC;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,OAAO,YAAY,UAAU,EAAqB;AAAA,EAC5E;AACA,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,KAAK,MAAM,IAAI;AACtE,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,wBAAwB;AAAA,MACtB,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,eAAe,OAAqC;AAClD,WAAO,aAAa,OAAO,UAAU;AAAA,EACvC;AAAA,EACA,cACE,OACA,UACQ;AACR,WAAO,sBAAsB,OAAO,QAAQ;AAAA,EAC9C;AACF;","names":[]}
@@ -1,4 +1,22 @@
1
1
  // src/core/errors.ts
2
+ var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
3
+ var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
4
+ function defineSDKErrorBrand(error) {
5
+ Object.defineProperty(error, SDK_ERROR_BRAND, {
6
+ value: true,
7
+ enumerable: false,
8
+ configurable: false,
9
+ writable: false
10
+ });
11
+ }
12
+ function defineSDKErrorType(error, type) {
13
+ Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {
14
+ value: type,
15
+ enumerable: false,
16
+ configurable: false,
17
+ writable: false
18
+ });
19
+ }
2
20
  var SDKError = class extends Error {
3
21
  constructor(code, message, status, details, userMessage, suggestion, requestId) {
4
22
  super(message);
@@ -9,6 +27,7 @@ var SDKError = class extends Error {
9
27
  this.userMessage = userMessage;
10
28
  this.suggestion = suggestion;
11
29
  this.requestId = requestId;
30
+ defineSDKErrorBrand(this);
12
31
  if (Error.captureStackTrace) {
13
32
  Error.captureStackTrace(this, new.target);
14
33
  }
@@ -29,6 +48,7 @@ var SDKError = class extends Error {
29
48
  ...this.kind !== void 0 && { kind: this.kind },
30
49
  ...this.reason !== void 0 && { reason: this.reason },
31
50
  ...this.rawReason !== void 0 && { rawReason: this.rawReason },
51
+ ...this.apiReason !== void 0 && { apiReason: this.apiReason },
32
52
  ...this.retryable !== void 0 && { retryable: this.retryable },
33
53
  ...this.retryAfter !== void 0 && { retryAfter: this.retryAfter }
34
54
  };
@@ -74,6 +94,7 @@ var COMMERCE_ERROR_CODES = [
74
94
  "payment_session_not_cancelable",
75
95
  "payment_session_conflict",
76
96
  "provider_identity_mismatch",
97
+ "managed_refund_attestation_forbidden",
77
98
  "payment_method_unavailable",
78
99
  "provider_unavailable",
79
100
  "lock_timeout",
@@ -145,6 +166,7 @@ var ValidationError = class extends SDKError {
145
166
  constructor(message, details, userMessage, suggestion, status = 400) {
146
167
  super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
147
168
  this.name = "ValidationError";
169
+ defineSDKErrorType(this, "ValidationError");
148
170
  }
149
171
  };
150
172
  var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors.ts","../src/utils/storefront-cache.ts"],"sourcesContent":["export class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'capacity_exceeded',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!(error instanceof SDKError) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (error instanceof ValidationError) return true\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return error instanceof ServiceUnavailableError\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return error instanceof UsageLimitError\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return error instanceof PermissionError\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return error instanceof NotFoundError\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return error instanceof ConflictError\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createValidationError } from '../errors'\n\nconst CACHE_RESOURCE_VERSION = 'storefront:v1'\n\nexport type StorefrontCacheScope = {\n /**\n * Tenant identifier for the public storefront read.\n */\n tenantId: string | number\n /**\n * Stable, non-secret scope for publishable-key variance. Use a short key id,\n * key fingerprint, or \"default\" when a tenant has one public cache view.\n */\n publishableKeyScope?: string | number\n}\n\nexport type StorefrontCacheProductDetailIdentity =\n | { id: string | number; slug?: never }\n | { id?: never; slug: string }\n\nfunction invalidResourceInput(message: string) {\n return createValidationError(message)\n}\n\nfunction encodeResourceSegment(value: unknown, label: string): string {\n if (typeof value !== 'string' && typeof value !== 'number') {\n throw invalidResourceInput(`${label} must be a string or number`)\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw invalidResourceInput(`${label} must be a finite number`)\n }\n const segment = String(value).trim()\n if (!segment) {\n throw invalidResourceInput(`${label} must not be empty`)\n }\n return encodeURIComponent(segment)\n}\n\nfunction scopedResource(scope: StorefrontCacheScope, resource: string): string {\n if (scope == null || typeof scope !== 'object') {\n throw invalidResourceInput('cache scope must be an object')\n }\n const candidate = scope as {\n tenantId?: unknown\n publishableKeyScope?: unknown\n }\n const tenantId = encodeResourceSegment(candidate.tenantId, 'tenantId')\n const publishableKeyScopeValue =\n candidate.publishableKeyScope === undefined\n ? 'default'\n : candidate.publishableKeyScope\n const publishableKeyScope = encodeResourceSegment(\n publishableKeyScopeValue,\n 'publishableKeyScope',\n )\n\n return `${CACHE_RESOURCE_VERSION}:tenant:${tenantId}:key:${publishableKeyScope}:resource:${resource}`\n}\n\nfunction listResource(scope: StorefrontCacheScope, collection: string): string {\n return scopedResource(scope, `${collection}:list`)\n}\n\nfunction idDetailResource(\n scope: StorefrontCacheScope,\n collection: string,\n id: string | number,\n): string {\n return scopedResource(\n scope,\n `${collection}:detail:id:${encodeResourceSegment(id, 'resource id')}`,\n )\n}\n\nfunction productDetailResource(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n): string {\n const candidate = (identity ?? {}) as {\n id?: unknown\n slug?: unknown\n }\n const hasIdField = candidate.id !== undefined\n const hasSlugField = candidate.slug !== undefined\n\n if (hasIdField === hasSlugField) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n\n if (hasIdField) {\n if (\n (typeof candidate.id !== 'string' && typeof candidate.id !== 'number') ||\n String(candidate.id).trim() === ''\n ) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return idDetailResource(scope, 'products', candidate.id as string | number)\n }\n if (typeof candidate.slug !== 'string' || candidate.slug.trim() === '') {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return scopedResource(\n scope,\n `products:detail:slug:${encodeResourceSegment(\n candidate.slug as string,\n 'resource slug',\n )}`,\n )\n}\n\nexport const storefrontCacheResources = {\n productListing(scope: StorefrontCacheScope): string {\n return listResource(scope, 'products')\n },\n productDetail(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n ): string {\n return productDetailResource(scope, identity)\n },\n} as const\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/utils/storefront-cache.ts"],"sourcesContent":["const SDK_ERROR_BRAND = Symbol.for('@01.software/sdk/SDKError')\nconst SDK_ERROR_TYPE_BRAND = Symbol.for('@01.software/sdk/SDKError.type')\n\ntype SDKErrorType =\n | 'NetworkError'\n | 'ValidationError'\n | 'ApiError'\n | 'ConfigError'\n | 'TimeoutError'\n | 'GoneError'\n | 'ServiceUnavailableError'\n | 'UsageLimitError'\n | 'AuthError'\n | 'PermissionError'\n | 'NotFoundError'\n | 'ConflictError'\n | 'RateLimitError'\n\nfunction defineSDKErrorBrand(error: SDKError): void {\n Object.defineProperty(error, SDK_ERROR_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nfunction defineSDKErrorType(error: SDKError, type: SDKErrorType): void {\n Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {\n value: type,\n enumerable: false,\n configurable: false,\n writable: false,\n })\n}\n\nexport class SDKError extends Error {\n readonly code: string\n readonly status?: number\n readonly details?: unknown\n readonly userMessage?: string\n readonly suggestion?: string\n readonly requestId?: string\n readonly kind?: 'commerce'\n readonly reason?: CommerceErrorCode | 'unknown_commerce_error'\n readonly rawReason?: string\n /** Machine-readable reason from a non-commerce API response. */\n readonly apiReason?: string\n readonly retryable?: boolean\n readonly retryAfter?: number\n\n constructor(\n code: string,\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n this.code = code\n this.status = status\n this.details = details\n this.userMessage = userMessage\n this.suggestion = suggestion\n this.requestId = requestId\n defineSDKErrorBrand(this)\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, new.target)\n }\n }\n\n getUserMessage(): string {\n return this.userMessage || this.message\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n details: this.details,\n userMessage: this.userMessage,\n suggestion: this.suggestion,\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n ...(this.kind !== undefined && { kind: this.kind }),\n ...(this.reason !== undefined && { reason: this.reason }),\n ...(this.rawReason !== undefined && { rawReason: this.rawReason }),\n ...(this.apiReason !== undefined && { apiReason: this.apiReason }),\n ...(this.retryable !== undefined && { retryable: this.retryable }),\n ...(this.retryAfter !== undefined && { retryAfter: this.retryAfter }),\n }\n }\n}\n\n/**\n * Canonical Cart/Checkout/PaymentSession error reasons. This public SDK mirror\n * intentionally does not import the private contracts package; parity is\n * enforced by a type test.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'validation_failed',\n 'bad_request',\n 'unauthorized',\n 'forbidden',\n 'account_suspended',\n 'key_invalid',\n 'pat_tenant_header_forbidden',\n 'tenant_mismatch',\n 'test_tenant_expired',\n 'token_invalid',\n 'token_expired',\n 'origin_not_allowed',\n 'server_credentials_required',\n 'role_denied',\n 'scope_denied',\n 'feature_disabled',\n 'not_found',\n 'conflict',\n 'locked',\n 'cart_revision_conflict',\n 'rate_limit_exceeded',\n 'usage_limit_exceeded',\n 'service_unavailable',\n 'idempotency_conflict',\n 'idempotency_in_progress',\n 'idempotency_key_required',\n 'invalid_idempotency_key',\n 'cart_not_active',\n 'cart_locked',\n 'cart_empty',\n 'cart_market_unavailable',\n 'cart_market_mismatch',\n 'checkout_not_open',\n 'checkout_already_open',\n 'payment_slot_held',\n 'reservation_expired',\n 'payment_session_not_cancelable',\n 'payment_session_conflict',\n 'provider_identity_mismatch',\n 'managed_refund_attestation_forbidden',\n 'payment_method_unavailable',\n 'provider_unavailable',\n 'lock_timeout',\n 'price_changed',\n 'pricing_fact_in_use',\n 'insufficient_stock',\n 'reservation_conflict',\n 'stock_lock_unavailable',\n 'variant_not_found',\n 'variant_stock_write_failed',\n 'stock_invariant_violation',\n 'payment_confirmation_in_flight',\n 'checkout_reservation_release_requires_transaction',\n 'admission_metadata_invalid',\n 'admission_metadata_required',\n 'capacity_exceeded',\n 'occurrence_lock_unavailable',\n 'occurrence_not_open',\n 'admission_type_capacity_exceeded',\n 'admission_type_occurrence_mismatch',\n 'admission_hold_expired',\n 'admission_hold_checkout_item_conflict',\n 'admission_hold_checkout_conflict',\n 'admission_hold_quantity_mismatch',\n 'admission_hold_unbound',\n 'admission_hold_missing',\n 'admission_hold_checkout_item_missing',\n 'admission_hold_expiry_failed',\n 'admission_hold_expiry_requires_transaction',\n 'admission_hold_line_item_mismatch',\n 'admission_materialization_failed',\n 'variant_inactive',\n 'variant_product_mismatch',\n 'product_not_public',\n 'market_not_found',\n 'market_shipping_currency_unsupported',\n 'missing_market_rate',\n 'missing_shipping_amount',\n 'no_enabled_payment_provider',\n 'product_market_unavailable',\n 'unsupported_currency',\n 'missing_price_row',\n 'payment_provider_currency_unsupported',\n 'discount_code_not_found',\n 'discount_not_started',\n 'discount_expired',\n 'discount_usage_limit',\n 'discount_per_customer_limit',\n 'discount_customer_required',\n 'discount_first_order_only',\n 'discount_customer_not_eligible',\n 'discount_customer_excluded',\n 'discount_items_required',\n 'discount_product_not_eligible',\n 'discount_product_excluded',\n 'discount_min_order_amount',\n 'discount_currency_scope_required',\n 'discount_allocation_method_unsupported',\n 'currency_mismatch',\n 'customer_token_required',\n 'market_required',\n 'server_derived',\n 'internal_error',\n] as const\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number]\n\ntype CommerceSDKErrorBase = SDKError & {\n readonly kind: 'commerce'\n readonly requestId: string\n readonly retryable: boolean\n readonly retryAfter?: number\n readonly details?: Record<string, unknown>\n}\n\nexport type CommerceSDKError = CommerceSDKErrorBase &\n (\n | { readonly reason: CommerceErrorCode; readonly rawReason?: never }\n | {\n readonly reason: 'unknown_commerce_error'\n readonly rawReason: string\n }\n )\n\nconst COMMERCE_ERROR_CODE_SET: ReadonlySet<string> = new Set(\n COMMERCE_ERROR_CODES,\n)\nconst COMMERCE_ERROR_ENVELOPE_KEYS = new Set([\n 'error',\n 'reason',\n 'requestId',\n 'retryable',\n 'details',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport type CommerceErrorEnvelope = {\n error: string\n reason: string\n requestId: string\n retryable: boolean\n details?: Record<string, unknown>\n}\n\nfunction commerceProtocolError(\n issue: string,\n trustedRequestId?: string,\n): SDKError {\n return createApiError(\n 'Invalid canonical commerce error response.',\n 502,\n { protocol: 'commerce-error-envelope', issue },\n 'The server returned an incompatible commerce error response.',\n 'Verify that the Console commerce contract is deployed before using this SDK version.',\n trustedRequestId,\n )\n}\n\n/** @internal Strictly parse a canonical commerce error without retaining its raw body. */\nexport function parseCommerceErrorEnvelope(\n body: unknown,\n headerRequestId?: string,\n): CommerceErrorEnvelope {\n if (headerRequestId === undefined) {\n throw commerceProtocolError('missing_request_id_header')\n }\n if (headerRequestId.length === 0) {\n throw commerceProtocolError('empty_request_id_header')\n }\n if (!isPlainRecord(body)) {\n throw commerceProtocolError('expected_object', headerRequestId)\n }\n if (Object.keys(body).some((key) => !COMMERCE_ERROR_ENVELOPE_KEYS.has(key))) {\n throw commerceProtocolError('unexpected_field', headerRequestId)\n }\n if (\n typeof body.error !== 'string' ||\n body.error.length === 0 ||\n typeof body.reason !== 'string' ||\n body.reason.length === 0 ||\n typeof body.requestId !== 'string' ||\n body.requestId.length === 0 ||\n (body.retryable !== undefined && typeof body.retryable !== 'boolean') ||\n (body.details !== undefined && !isPlainRecord(body.details))\n ) {\n throw commerceProtocolError('invalid_field', headerRequestId)\n }\n\n if (headerRequestId !== undefined && headerRequestId !== body.requestId) {\n throw commerceProtocolError('request_id_mismatch', headerRequestId)\n }\n\n return {\n error: body.error,\n reason: body.reason,\n requestId: body.requestId,\n retryable: body.retryable === true,\n ...(body.details === undefined ? {} : { details: body.details }),\n }\n}\n\n/** @internal Validate and apply the canonical commerce error envelope. */\nexport function enhanceCommerceError(\n error: SDKError,\n body: unknown,\n headerRequestId?: string,\n): SDKError {\n const envelope = parseCommerceErrorEnvelope(body, headerRequestId)\n\n const known = COMMERCE_ERROR_CODE_SET.has(envelope.reason)\n Object.assign(error, {\n code: envelope.reason,\n kind: 'commerce' as const,\n reason: known\n ? (envelope.reason as CommerceErrorCode)\n : 'unknown_commerce_error',\n ...(known ? {} : { rawReason: envelope.reason }),\n requestId: envelope.requestId,\n retryable: envelope.retryable,\n details: envelope.details,\n })\n return error\n}\n\n/** @internal Apply a non-commerce reason without canonical-commerce validation. */\nexport function enhanceNonCommerceError(\n error: SDKError,\n reason: unknown,\n): SDKError {\n if (typeof reason === 'string') Object.assign(error, { apiReason: reason })\n return error\n}\n\n/**\n * Read the server-provided machine reason across strict commerce and\n * non-commerce SDK errors. Unknown commerce reasons are returned verbatim.\n */\nexport function getSDKErrorReason(error: SDKError): string | undefined {\n if (error.kind !== 'commerce') return error.apiReason\n return error.reason === 'unknown_commerce_error'\n ? error.rawReason\n : error.reason\n}\n\nexport function isCommerceSDKError(error: unknown): error is CommerceSDKError {\n if (!isSDKError(error) || error.kind !== 'commerce') return false\n if (\n typeof error.requestId !== 'string' ||\n typeof error.retryable !== 'boolean' ||\n (error.retryAfter !== undefined &&\n (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0)) ||\n typeof error.reason !== 'string'\n ) {\n return false\n }\n return error.reason === 'unknown_commerce_error'\n ? typeof error.rawReason === 'string'\n : COMMERCE_ERROR_CODE_SET.has(error.reason) && error.rawReason === undefined\n}\n\nexport class NetworkError extends SDKError {\n constructor(\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('NETWORK_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'NetworkError'\n defineSDKErrorType(this, 'NetworkError')\n }\n}\n\nexport class ValidationError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status = 400,\n ) {\n super('VALIDATION_ERROR', message, status, details, userMessage, suggestion)\n this.name = 'ValidationError'\n defineSDKErrorType(this, 'ValidationError')\n }\n}\n\nexport class ApiError extends SDKError {\n constructor(\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'API_ERROR',\n message,\n status,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'ApiError'\n defineSDKErrorType(this, 'ApiError')\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('CONFIG_ERROR', message, undefined, details, userMessage, suggestion)\n this.name = 'ConfigError'\n defineSDKErrorType(this, 'ConfigError')\n }\n}\n\nexport class TimeoutError extends SDKError {\n constructor(\n message = 'Request timed out.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('TIMEOUT_ERROR', message, 408, details, userMessage, suggestion)\n this.name = 'TimeoutError'\n defineSDKErrorType(this, 'TimeoutError')\n }\n}\n\nexport class GoneError extends SDKError {\n constructor(\n message = 'The requested resource is no longer available.',\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('GONE_ERROR', message, 410, details, userMessage, suggestion)\n this.name = 'GoneError'\n defineSDKErrorType(this, 'GoneError')\n }\n}\n\nexport class ServiceUnavailableError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message = 'Service temporarily unavailable.',\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super(\n 'SERVICE_UNAVAILABLE_ERROR',\n message,\n 503,\n details,\n userMessage,\n suggestion,\n )\n this.name = 'ServiceUnavailableError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'ServiceUnavailableError')\n }\n}\n\nexport class UsageLimitError extends SDKError {\n readonly usage: { limit: number; current: number; remaining: number }\n\n constructor(\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n ) {\n super('USAGE_LIMIT_ERROR', message, 429, details, userMessage, suggestion)\n this.name = 'UsageLimitError'\n this.usage = usage\n defineSDKErrorType(this, 'UsageLimitError')\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n usage: this.usage,\n }\n }\n}\n\nexport class AuthError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'auth_error',\n message,\n 401,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'AuthError'\n defineSDKErrorType(this, 'AuthError')\n }\n}\n\nexport class PermissionError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'permission_error',\n message,\n 403,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'PermissionError'\n defineSDKErrorType(this, 'PermissionError')\n }\n}\n\nexport class NotFoundError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'not_found',\n message,\n 404,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'NotFoundError'\n defineSDKErrorType(this, 'NotFoundError')\n }\n}\n\nexport class ConflictError extends SDKError {\n constructor(\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super('conflict', message, 409, details, userMessage, suggestion, requestId)\n this.name = 'ConflictError'\n defineSDKErrorType(this, 'ConflictError')\n }\n}\n\nexport class RateLimitError extends SDKError {\n readonly retryAfter?: number\n\n constructor(\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n ) {\n super(\n 'rate_limit_exceeded',\n message,\n 429,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n defineSDKErrorType(this, 'RateLimitError')\n }\n}\n\nfunction hasBrandedSDKErrorShape(error: unknown): error is SDKError {\n if (error === null || typeof error !== 'object') return false\n\n const candidate = error as Record<PropertyKey, unknown>\n return (\n candidate[SDK_ERROR_BRAND] === true &&\n typeof candidate.name === 'string' &&\n typeof candidate.code === 'string' &&\n typeof candidate.message === 'string' &&\n (candidate.status === undefined || typeof candidate.status === 'number') &&\n (candidate.userMessage === undefined ||\n typeof candidate.userMessage === 'string') &&\n (candidate.suggestion === undefined ||\n typeof candidate.suggestion === 'string') &&\n (candidate.requestId === undefined ||\n typeof candidate.requestId === 'string') &&\n (candidate.kind === undefined || candidate.kind === 'commerce') &&\n (candidate.reason === undefined || typeof candidate.reason === 'string') &&\n (candidate.rawReason === undefined ||\n typeof candidate.rawReason === 'string') &&\n (candidate.apiReason === undefined ||\n typeof candidate.apiReason === 'string') &&\n (candidate.retryable === undefined ||\n typeof candidate.retryable === 'boolean') &&\n (candidate.retryAfter === undefined ||\n typeof candidate.retryAfter === 'number') &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nfunction hasSDKErrorType(error: unknown, type: SDKErrorType): boolean {\n return (\n hasBrandedSDKErrorShape(error) &&\n (error as unknown as Record<PropertyKey, unknown>)[SDK_ERROR_TYPE_BRAND] ===\n type\n )\n}\n\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError || hasBrandedSDKErrorShape(error)\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError || hasSDKErrorType(error, 'NetworkError')\n}\n\nexport function isValidationError(error: unknown): error is ValidationError {\n if (\n error instanceof ValidationError ||\n hasSDKErrorType(error, 'ValidationError')\n ) {\n return true\n }\n if (error == null || typeof error !== 'object') return false\n\n const candidate = error as {\n code?: unknown\n name?: unknown\n message?: unknown\n getUserMessage?: unknown\n toJSON?: unknown\n }\n return (\n candidate.name === 'ValidationError' &&\n candidate.code === 'VALIDATION_ERROR' &&\n typeof candidate.message === 'string' &&\n typeof candidate.getUserMessage === 'function' &&\n typeof candidate.toJSON === 'function'\n )\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError || hasSDKErrorType(error, 'ApiError')\n}\n\nexport function isConfigError(error: unknown): error is ConfigError {\n return error instanceof ConfigError || hasSDKErrorType(error, 'ConfigError')\n}\n\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError || hasSDKErrorType(error, 'TimeoutError')\n}\n\nexport function isGoneError(error: unknown): error is GoneError {\n return error instanceof GoneError || hasSDKErrorType(error, 'GoneError')\n}\n\nexport function isServiceUnavailableError(\n error: unknown,\n): error is ServiceUnavailableError {\n return (\n error instanceof ServiceUnavailableError ||\n hasSDKErrorType(error, 'ServiceUnavailableError')\n )\n}\n\nexport function isUsageLimitError(error: unknown): error is UsageLimitError {\n return (\n error instanceof UsageLimitError ||\n hasSDKErrorType(error, 'UsageLimitError')\n )\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError || hasSDKErrorType(error, 'AuthError')\n}\n\nexport function isPermissionError(error: unknown): error is PermissionError {\n return (\n error instanceof PermissionError ||\n hasSDKErrorType(error, 'PermissionError')\n )\n}\n\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return (\n error instanceof NotFoundError || hasSDKErrorType(error, 'NotFoundError')\n )\n}\n\nexport function isConflictError(error: unknown): error is ConflictError {\n return (\n error instanceof ConflictError || hasSDKErrorType(error, 'ConflictError')\n )\n}\n\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return (\n error instanceof RateLimitError || hasSDKErrorType(error, 'RateLimitError')\n )\n}\n\nexport const createNetworkError = (\n message: string,\n status?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new NetworkError(message, status, details, userMessage, suggestion)\n\nexport const createValidationError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n status?: number,\n) => new ValidationError(message, details, userMessage, suggestion, status)\n\nexport const createApiError = (\n message: string,\n status: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ApiError(message, status, details, userMessage, suggestion, requestId)\n\nexport const createConfigError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new ConfigError(message, details, userMessage, suggestion)\n\nexport const createTimeoutError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new TimeoutError(message, details, userMessage, suggestion)\n\nexport const createGoneError = (\n message?: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new GoneError(message, details, userMessage, suggestion)\n\nexport const createServiceUnavailableError = (\n message?: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) =>\n new ServiceUnavailableError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n )\n\nexport const createUsageLimitError = (\n message: string,\n usage: { limit: number; current: number; remaining: number },\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n) => new UsageLimitError(message, usage, details, userMessage, suggestion)\n\nexport const createAuthError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new AuthError(message, details, userMessage, suggestion, requestId)\n\nexport const createPermissionError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new PermissionError(message, details, userMessage, suggestion, requestId)\n\nexport const createNotFoundError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new NotFoundError(message, details, userMessage, suggestion, requestId)\n\nexport const createConflictError = (\n message: string,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) => new ConflictError(message, details, userMessage, suggestion, requestId)\n\nexport const createRateLimitError = (\n message: string,\n retryAfter?: number,\n details?: unknown,\n userMessage?: string,\n suggestion?: string,\n requestId?: string,\n) =>\n new RateLimitError(\n message,\n retryAfter,\n details,\n userMessage,\n suggestion,\n requestId,\n )\n","import { createValidationError } from '../errors'\n\nconst CACHE_RESOURCE_VERSION = 'storefront:v1'\n\nexport type StorefrontCacheScope = {\n /**\n * Tenant identifier for the public storefront read.\n */\n tenantId: string | number\n /**\n * Stable, non-secret scope for publishable-key variance. Use a short key id,\n * key fingerprint, or \"default\" when a tenant has one public cache view.\n */\n publishableKeyScope?: string | number\n}\n\nexport type StorefrontCacheProductDetailIdentity =\n | { id: string | number; slug?: never }\n | { id?: never; slug: string }\n\nfunction invalidResourceInput(message: string) {\n return createValidationError(message)\n}\n\nfunction encodeResourceSegment(value: unknown, label: string): string {\n if (typeof value !== 'string' && typeof value !== 'number') {\n throw invalidResourceInput(`${label} must be a string or number`)\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw invalidResourceInput(`${label} must be a finite number`)\n }\n const segment = String(value).trim()\n if (!segment) {\n throw invalidResourceInput(`${label} must not be empty`)\n }\n return encodeURIComponent(segment)\n}\n\nfunction scopedResource(scope: StorefrontCacheScope, resource: string): string {\n if (scope == null || typeof scope !== 'object') {\n throw invalidResourceInput('cache scope must be an object')\n }\n const candidate = scope as {\n tenantId?: unknown\n publishableKeyScope?: unknown\n }\n const tenantId = encodeResourceSegment(candidate.tenantId, 'tenantId')\n const publishableKeyScopeValue =\n candidate.publishableKeyScope === undefined\n ? 'default'\n : candidate.publishableKeyScope\n const publishableKeyScope = encodeResourceSegment(\n publishableKeyScopeValue,\n 'publishableKeyScope',\n )\n\n return `${CACHE_RESOURCE_VERSION}:tenant:${tenantId}:key:${publishableKeyScope}:resource:${resource}`\n}\n\nfunction listResource(scope: StorefrontCacheScope, collection: string): string {\n return scopedResource(scope, `${collection}:list`)\n}\n\nfunction idDetailResource(\n scope: StorefrontCacheScope,\n collection: string,\n id: string | number,\n): string {\n return scopedResource(\n scope,\n `${collection}:detail:id:${encodeResourceSegment(id, 'resource id')}`,\n )\n}\n\nfunction productDetailResource(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n): string {\n const candidate = (identity ?? {}) as {\n id?: unknown\n slug?: unknown\n }\n const hasIdField = candidate.id !== undefined\n const hasSlugField = candidate.slug !== undefined\n\n if (hasIdField === hasSlugField) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n\n if (hasIdField) {\n if (\n (typeof candidate.id !== 'string' && typeof candidate.id !== 'number') ||\n String(candidate.id).trim() === ''\n ) {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return idDetailResource(scope, 'products', candidate.id as string | number)\n }\n if (typeof candidate.slug !== 'string' || candidate.slug.trim() === '') {\n throw invalidResourceInput(\n 'product detail identity must include exactly one non-empty id or slug',\n )\n }\n return scopedResource(\n scope,\n `products:detail:slug:${encodeResourceSegment(\n candidate.slug as string,\n 'resource slug',\n )}`,\n )\n}\n\nexport const storefrontCacheResources = {\n productListing(scope: StorefrontCacheScope): string {\n return listResource(scope, 'products')\n },\n productDetail(\n scope: StorefrontCacheScope,\n identity: StorefrontCacheProductDetailIdentity,\n ): string {\n return productDetailResource(scope, identity)\n },\n} as const\n"],"mappings":";AAAA,IAAM,kBAAkB,uBAAO,IAAI,2BAA2B;AAC9D,IAAM,uBAAuB,uBAAO,IAAI,gCAAgC;AAiBxE,SAAS,oBAAoB,OAAuB;AAClD,SAAO,eAAe,OAAO,iBAAiB;AAAA,IAC5C,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,SAAS,mBAAmB,OAAiB,MAA0B;AACrE,SAAO,eAAe,OAAO,sBAAsB;AAAA,IACjD,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAelC,YACE,MACA,SACA,QACA,SACA,aACA,YACA,WACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,wBAAoB,IAAI;AAExB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,SAAS,UAAa,EAAE,MAAM,KAAK,KAAK;AAAA,MACjD,GAAI,KAAK,WAAW,UAAa,EAAE,QAAQ,KAAK,OAAO;AAAA,MACvD,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,cAAc,UAAa,EAAE,WAAW,KAAK,UAAU;AAAA,MAChE,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,IACrE;AAAA,EACF;AACF;AAOO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqBA,IAAM,0BAA+C,IAAI;AAAA,EACvD;AACF;AAuJO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YACE,SACA,SACA,aACA,YACA,SAAS,KACT;AACA,UAAM,oBAAoB,SAAS,QAAQ,SAAS,aAAa,UAAU;AAC3E,SAAK,OAAO;AACZ,uBAAmB,MAAM,iBAAiB;AAAA,EAC5C;AACF;AAuWO,IAAM,wBAAwB,CACnC,SACA,SACA,aACA,YACA,WACG,IAAI,gBAAgB,SAAS,SAAS,aAAa,YAAY,MAAM;;;ACrvB1E,IAAM,yBAAyB;AAkB/B,SAAS,qBAAqB,SAAiB;AAC7C,SAAO,sBAAsB,OAAO;AACtC;AAEA,SAAS,sBAAsB,OAAgB,OAAuB;AACpE,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,UAAM,qBAAqB,GAAG,KAAK,6BAA6B;AAAA,EAClE;AACA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,qBAAqB,GAAG,KAAK,0BAA0B;AAAA,EAC/D;AACA,QAAM,UAAU,OAAO,KAAK,EAAE,KAAK;AACnC,MAAI,CAAC,SAAS;AACZ,UAAM,qBAAqB,GAAG,KAAK,oBAAoB;AAAA,EACzD;AACA,SAAO,mBAAmB,OAAO;AACnC;AAEA,SAAS,eAAe,OAA6B,UAA0B;AAC7E,MAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;AAC9C,UAAM,qBAAqB,+BAA+B;AAAA,EAC5D;AACA,QAAM,YAAY;AAIlB,QAAM,WAAW,sBAAsB,UAAU,UAAU,UAAU;AACrE,QAAM,2BACJ,UAAU,wBAAwB,SAC9B,YACA,UAAU;AAChB,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AAEA,SAAO,GAAG,sBAAsB,WAAW,QAAQ,QAAQ,mBAAmB,aAAa,QAAQ;AACrG;AAEA,SAAS,aAAa,OAA6B,YAA4B;AAC7E,SAAO,eAAe,OAAO,GAAG,UAAU,OAAO;AACnD;AAEA,SAAS,iBACP,OACA,YACA,IACQ;AACR,SAAO;AAAA,IACL;AAAA,IACA,GAAG,UAAU,cAAc,sBAAsB,IAAI,aAAa,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,sBACP,OACA,UACQ;AACR,QAAM,YAAa,YAAY,CAAC;AAIhC,QAAM,aAAa,UAAU,OAAO;AACpC,QAAM,eAAe,UAAU,SAAS;AAExC,MAAI,eAAe,cAAc;AAC/B,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY;AACd,QACG,OAAO,UAAU,OAAO,YAAY,OAAO,UAAU,OAAO,YAC7D,OAAO,UAAU,EAAE,EAAE,KAAK,MAAM,IAChC;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,OAAO,YAAY,UAAU,EAAqB;AAAA,EAC5E;AACA,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,KAAK,MAAM,IAAI;AACtE,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,wBAAwB;AAAA,MACtB,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,eAAe,OAAqC;AAClD,WAAO,aAAa,OAAO,UAAU;AAAA,EACvC;AAAA,EACA,cACE,OACA,UACQ;AACR,WAAO,sBAAsB,OAAO,QAAQ;AAAA,EAC9C;AACF;","names":[]}
@@ -1,5 +1,5 @@
1
- import { P as Product, a as ProductVariant, M as Market, C as CustomerProfile, b as CustomerProfileStat, c as CustomerProfileList, d as ProductCollection, e as Config } from './payload-types-B6AZQcB7.js';
2
- import { C as Collection } from './const-k9gHylYa.js';
1
+ import { P as Product, a as ProductVariant, M as Market, C as CustomerProfile, b as CustomerProfileStat, c as CustomerProfileList, d as ProductCollection, e as Config } from './payload-types-BOsckg8B.js';
2
+ import { C as Collection } from './const-JD8obaKg.js';
3
3
 
4
4
  type PublicCustomerProfile = Omit<CustomerProfile, 'tenant' | 'customer' | 'isPublic' | 'anonymizedAt' | 'metadata'>;
5
5
  type PublicCustomerProfileListEntry = {
@@ -1,5 +1,5 @@
1
- import { P as Product, a as ProductVariant, M as Market, C as CustomerProfile, b as CustomerProfileStat, c as CustomerProfileList, d as ProductCollection, e as Config } from './payload-types-B6AZQcB7.cjs';
2
- import { C as Collection } from './const-BXEi1Kix.cjs';
1
+ import { P as Product, a as ProductVariant, M as Market, C as CustomerProfile, b as CustomerProfileStat, c as CustomerProfileList, d as ProductCollection, e as Config } from './payload-types-BOsckg8B.cjs';
2
+ import { C as Collection } from './const-D8LixhAJ.cjs';
3
3
 
4
4
  type PublicCustomerProfile = Omit<CustomerProfile, 'tenant' | 'customer' | 'isPublic' | 'anonymizedAt' | 'metadata'>;
5
5
  type PublicCustomerProfileListEntry = {