@01.software/sdk 0.36.0 → 0.37.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.
- package/README.md +71 -6
- package/dist/analytics/react.cjs +33 -9
- package/dist/analytics/react.cjs.map +1 -1
- package/dist/analytics/react.d.cts +1 -1
- package/dist/analytics/react.d.ts +1 -1
- package/dist/analytics/react.js +33 -9
- package/dist/analytics/react.js.map +1 -1
- package/dist/analytics.cjs +30 -8
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.d.cts +6 -0
- package/dist/analytics.d.ts +6 -0
- package/dist/analytics.js +30 -8
- package/dist/analytics.js.map +1 -1
- package/dist/client.cjs +94 -114
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +6 -6
- package/dist/client.d.ts +6 -6
- package/dist/client.js +94 -114
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-Bq5Zd7p7.d.ts → collection-client-DyELGUcL.d.ts} +3 -3
- package/dist/{collection-client-Cv0D2w1Q.d.cts → collection-client-zOmnxwdA.d.cts} +3 -3
- package/dist/{const-DVcM7Ac_.d.cts → const-CK_FPaIn.d.cts} +3 -3
- package/dist/{const-BDUKFP9w.d.ts → const-Dqz05oaG.d.ts} +3 -3
- package/dist/{image-BDz2-AaO.d.cts → image-BDjHp03R.d.cts} +13 -9
- package/dist/{image-BDz2-AaO.d.ts → image-BDjHp03R.d.ts} +13 -9
- package/dist/{index-DTSXUYkr.d.ts → index-DRJs7QIh.d.cts} +9 -6
- package/dist/{index-BHDKJ6B3.d.cts → index-DTqoUZk_.d.ts} +9 -6
- package/dist/index.cjs +172 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +172 -132
- package/dist/index.js.map +1 -1
- package/dist/metadata.cjs +5 -3
- package/dist/metadata.cjs.map +1 -1
- package/dist/metadata.js +5 -3
- package/dist/metadata.js.map +1 -1
- package/dist/{payload-types-BCui2Oml.d.cts → payload-types-CREOjFNT.d.cts} +281 -108
- package/dist/{payload-types-BCui2Oml.d.ts → payload-types-CREOjFNT.d.ts} +281 -108
- package/dist/query.cjs +5 -3
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +5 -5
- package/dist/query.d.ts +5 -5
- package/dist/query.js +5 -3
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +84 -69
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +7 -7
- package/dist/server.d.ts +7 -7
- package/dist/server.js +84 -69
- package/dist/server.js.map +1 -1
- package/dist/{types-Dib-zdK6.d.cts → types-BWMUr3Zw.d.cts} +195 -71
- package/dist/{types-CEzLf3PX.d.cts → types-BkZNhuBh.d.cts} +1 -1
- package/dist/{types-3qV6sY7T.d.ts → types-CxzWHspI.d.ts} +1 -1
- package/dist/{types-DK9EnLwJ.d.ts → types-DMvVHdb1.d.ts} +195 -71
- package/dist/ui/canvas.cjs +15 -5
- package/dist/ui/canvas.cjs.map +1 -1
- package/dist/ui/canvas.d.cts +1 -1
- package/dist/ui/canvas.d.ts +1 -1
- package/dist/ui/canvas.js +15 -5
- package/dist/ui/canvas.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/image.cjs +15 -5
- package/dist/ui/image.cjs.map +1 -1
- package/dist/ui/image.d.cts +1 -1
- package/dist/ui/image.d.ts +1 -1
- package/dist/ui/image.js +15 -5
- package/dist/ui/image.js.map +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.cjs +5 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +4 -4
- package/dist/webhook.d.ts +4 -4
- package/dist/webhook.js +5 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/collection/http-client.ts","../src/core/errors.ts","../src/core/internal/utils/credentials.ts","../src/core/client/types.ts","../src/core/internal/utils/http.ts","../src/core/internal/utils/query-string.ts","../src/utils/types.ts","../src/core/metadata/index.ts","../src/core/collection/query-builder.ts","../src/core/collection/collection-client.ts","../src/core/api/parse-response.ts","../src/core/community/community-client.ts","../src/core/customer/customer-auth.ts","../src/core/customer/customer-namespace.ts","../src/core/api/cart-api.ts","../src/core/api/base-api.ts","../src/core/api/product-api.ts","../src/core/api/order-api.ts","../src/core/commerce/commerce-client.ts","../src/core/events/events-client.ts","../src/core/client/client.ts","../src/core/api/discount-api.ts","../src/core/api/shipping-api.ts","../src/core/commerce/merge-catalog-stock.ts","../src/core/webhook/index.ts","../src/core/collection/const.ts","../src/core/query/realtime.ts","../src/utils/product-selection-media.ts","../src/utils/ecommerce.ts","../src/utils/product-media.ts","../src/utils/product-gallery.ts","../src/utils/image.ts","../src/utils/order/generateOrderNumber.ts","../src/utils/order/formatOrderName.ts","../src/utils/video.ts","../src/analytics.ts","../src/index.ts"],"sourcesContent":["import { stringify } from 'qs-esm'\nimport {\n httpFetch,\n requirePublishableKeyForSecret,\n type FetchOptions,\n} from '../internal/utils'\nimport type {\n ApiQueryOptions,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { SDKError, createApiError } from '../internal/errors'\n\nexport class HttpClient {\n protected publishableKey: string\n protected secretKey?: string\n private getCustomerToken?: () => string | null\n private onUnauthorized?: () => Promise<string | null>\n private onRequestId?: (id: string | null) => void\n private apiUrl?: string\n\n constructor(\n publishableKey: string,\n secretKey?: string,\n getCustomerToken?: () => string | null,\n onUnauthorized?: () => Promise<string | null>,\n onRequestId?: (id: string | null) => void,\n apiUrl?: string,\n ) {\n this.publishableKey = requirePublishableKeyForSecret(\n 'CollectionClient',\n publishableKey,\n secretKey,\n )\n this.secretKey = secretKey\n this.getCustomerToken = getCustomerToken\n this.onUnauthorized = onUnauthorized\n this.onRequestId = onRequestId\n this.apiUrl = apiUrl\n }\n\n protected get defaultOptions(): FetchOptions {\n const opts: FetchOptions = {\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n }\n const token = this.getCustomerToken?.()\n if (token) {\n opts.customerToken = token\n if (this.onUnauthorized) {\n opts.onUnauthorized = this.onUnauthorized\n }\n }\n return opts\n }\n\n protected async fetchWithTracking(url: string, opts: FetchOptions): Promise<Response> {\n try {\n const response = await httpFetch(url, opts)\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return response\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n protected buildUrl(endpoint: string, options?: ApiQueryOptions): string {\n if (!options) return endpoint\n const queryString = stringify(options, { addQueryPrefix: true })\n return queryString ? `${endpoint}${queryString}` : endpoint\n }\n\n protected assertJsonResponse(response: Response): void {\n const contentType = response.headers.get('content-type')\n if (!contentType?.includes('application/json')) {\n throw createApiError('Response is not in JSON format.', response.status, {\n contentType,\n })\n }\n }\n\n /**\n * Parse Payload CMS find response (list query)\n * Returns native Payload response structure\n */\n protected async parseFindResponse<T>(\n response: Response,\n ): Promise<PayloadFindResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a find response\n if (jsonData.docs === undefined) {\n throw createApiError('Invalid find response.', response.status, {\n jsonData,\n })\n }\n\n return {\n docs: jsonData.docs,\n totalDocs: jsonData.totalDocs ?? 0,\n limit: jsonData.limit || 20,\n totalPages: jsonData.totalPages ?? 0,\n page: jsonData.page || 1,\n pagingCounter: jsonData.pagingCounter || 1,\n hasPrevPage: jsonData.hasPrevPage ?? false,\n hasNextPage: jsonData.hasNextPage ?? false,\n prevPage: jsonData.prevPage ?? null,\n nextPage: jsonData.nextPage ?? null,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS mutation response (create/update)\n * Returns native Payload response structure\n */\n protected async parseMutationResponse<T>(\n response: Response,\n ): Promise<PayloadMutationResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a mutation response\n if (jsonData.doc === undefined) {\n throw createApiError('Invalid mutation response.', response.status, {\n jsonData,\n })\n }\n\n return {\n message: jsonData.message || '',\n doc: jsonData.doc,\n errors: jsonData.errors,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS document response (findById/delete)\n * Returns document directly without wrapper\n */\n protected async parseDocumentResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n return jsonData as T\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n}\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\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 }\n }\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 return error instanceof ValidationError\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 { createConfigError } from '../errors'\n\nexport function requirePublishableKeyForSecret(\n apiName: string,\n publishableKey: string | undefined,\n secretKey: string | undefined,\n): string {\n if (secretKey && !publishableKey) {\n throw createConfigError(\n `publishableKey is required for ${apiName} when secretKey is used. ` +\n 'It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.',\n )\n }\n\n return publishableKey ?? ''\n}\n","import type {\n Collection,\n PublicCollection,\n ServerCollection,\n ServerOnlyCollection,\n} from '../collection/const'\nimport type { CollectionType } from '../collection/types'\nimport type { CommunityClient } from '../community/community-client'\nimport type {\n BanCustomerParams,\n CommunityBan,\n UnbanCustomerParams,\n} from '../community/moderation-api'\nimport type { CommerceClient } from '../commerce/commerce-client'\nimport type { ServerCommerceClient } from '../commerce/server-commerce-client'\nimport type { CustomerNamespace } from '../customer/customer-namespace'\nimport type { EventsClient } from '../events/events-client'\nimport type { TenantIntrospectionClient } from '../api/tenant-introspection-api'\n\nexport type {\n Collection,\n PublicCollection,\n ServerCollection,\n ServerOnlyCollection,\n}\n\n// ============================================================================\n// API URL Configuration\n// ============================================================================\n\ndeclare const __DEFAULT_API_URL__: string\n\nexport function resolveApiUrl(apiUrl?: string): string {\n if (apiUrl) {\n return apiUrl.replace(/\\/$/, '')\n }\n\n if (typeof process !== 'undefined' && process.env) {\n const envUrl =\n process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL\n if (envUrl) {\n return envUrl.replace(/\\/$/, '')\n }\n }\n return __DEFAULT_API_URL__\n}\n\n// ============================================================================\n// Client Configuration\n// ============================================================================\n\nexport interface ClientConfig {\n publishableKey: string\n /** API base URL for staging, self-hosted, preview, or proxy deployments. */\n apiUrl?: string\n /**\n * Customer authentication options.\n * Used to initialize CustomerAuth on Client.\n */\n customer?: {\n /**\n * Persist token in localStorage. Defaults to `true`.\n * - `true` (default): uses key `'customer-token'`\n * - `string`: uses the given string as localStorage key\n * - `false`: disables persistence (token/onTokenChange used instead)\n *\n * Handles SSR safely (no-op on server).\n * When enabled, `token` and `onTokenChange` are ignored.\n */\n persist?: boolean | string\n /** Initial token (e.g. from SSR cookie) */\n token?: string\n /** Called when token changes (login/logout) — use to persist in localStorage/cookie */\n onTokenChange?: (token: string | null) => void\n }\n}\n\n// Server client: requires both publishableKey (for CDN routing + rate limit +\n// monthly quota enforcement via the edge proxy) and secretKey (sk01_ opaque\n// bearer token, the authentication credential).\n// The proxy keys its tenant lookup off `X-Publishable-Key`, so omitting\n// publishableKey would silently bypass rate limiting and plan-based quota\n// enforcement.\nexport interface ClientServerConfig extends ClientConfig {\n secretKey: string\n}\n\nexport interface ClientMetadata {\n userAgent?: string\n timestamp: number\n}\n\nexport interface ClientState {\n metadata: ClientMetadata\n}\n\nexport interface PaginationMeta {\n page: number\n limit: number\n totalDocs: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n pagingCounter: number\n prevPage: number | null\n nextPage: number | null\n}\n\n// ============================================================================\n// Payload CMS Native Response Types\n// ============================================================================\n\n/**\n * Payload CMS Find (List) Response\n * GET /api/{collection}\n */\nexport interface PayloadFindResponse<T = unknown> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\n/**\n * Payload CMS Create/Update Response\n * POST /api/{collection}\n * PATCH /api/{collection}/{id}\n */\nexport interface PayloadMutationResponse<T = unknown> {\n message: string\n doc: T\n errors?: unknown[]\n}\n\n// ============================================================================\n// Query Options\n// ============================================================================\n\nexport type Sort = string | string[]\nexport type Where = Record<string, unknown>\n\n/**\n * Do NOT replace with `Pick<FindOptions>` from `payload` or import Payload\n * types here. Payload's generic query types depend on `PayloadTypes` module\n * augmentation; external SDK consumers who only use `createClient` should not\n * install Payload just to type REST query objects. Excluded vs native:\n * Local-API-only fields, `locale`/`fallbackLocale`.\n */\nexport interface ApiQueryOptions {\n page?: number\n limit?: number\n sort?: Sort\n /**\n * Filter documents. Id-based relation filters (`where: { product: { equals: id } }`) are the\n * most reliable pattern. Dotted-path relation filters (`where: { 'product.slug': { equals } }`)\n * are Payload-native but may silently return empty when access control restricts the related\n * document or when the relation is polymorphic. String shorthand (`where: { slug: 'x' }`)\n * silently matches nothing — always use `{ slug: { equals: 'x' } }`.\n */\n where?: Where\n /**\n * Controls how deeply relationship fields are populated. This is the primary control for\n * populating relationships like `category`, `images`, `brand`. The configured Payload default\n * applies when unset.\n */\n depth?: number\n select?: Record<string, boolean>\n /**\n * Controls which fields are returned for already-populated relationships, keyed by collection\n * slug. Does NOT control which relationships to populate — that is `depth`.\n *\n * @example\n * // depth: 2 populates category; populate trims which fields come back\n * populate: { categories: { title: true, slug: true } }\n */\n populate?: Record<string, boolean | Record<string, boolean>>\n /**\n * Controls Payload `type: 'join'` virtual reverse-relation fields only (pagination, sort,\n * filter, count per join field, or `false` to disable all join-field population).\n *\n * Does NOT populate normal relationship fields like `category`, `images`, or `brand`.\n * For normal relationship population use `depth` (and optionally `populate` for field\n * selection).\n *\n * Pass `joins: false` to disable all join-field population — useful for lightweight list\n * queries where join fields are not needed.\n *\n * @example\n * // `article-authors` has a `type: 'join'` field `articles` (reverse-relation)\n * joins: { articles: { limit: 10, sort: '-publishedAt' } }\n *\n * // depth: 2 populates product.category — joins has no effect on this\n * depth: 2\n *\n * // Disable all join-field population\n * joins: false\n */\n joins?:\n | Record<\n string,\n | {\n limit?: number\n page?: number\n sort?: string\n where?: Where\n count?: boolean\n }\n | false\n >\n | false\n /** Set to `false` to skip the count query — returns docs without totalDocs/totalPages */\n pagination?: boolean\n /** Include draft versions (access control still applies on the server) */\n draft?: boolean\n /** Include soft-deleted documents (requires `trash` enabled on the collection) */\n trash?: boolean\n}\n\n// ============================================================================\n// Debug & Retry Configuration\n// ============================================================================\n\nexport interface DebugConfig {\n logRequests?: boolean\n logResponses?: boolean\n logErrors?: boolean\n}\n\nexport interface RetryConfig {\n maxRetries?: number\n retryableStatuses?: number[]\n retryDelay?: (attempt: number) => number\n}\n\n// ============================================================================\n// Lightweight root entry contracts\n// ============================================================================\n\ninterface RootQueryLookup<T extends string> {\n find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>>\n count(options?: ApiQueryOptions): Promise<{ totalDocs: number }>\n}\n\nexport type RootReadOnlyQueryBuilder<T extends PublicCollection> =\n RootQueryLookup<T>\n\nexport interface RootServerQueryBuilder<\n T extends ServerCollection,\n> extends RootQueryLookup<T> {\n create(\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>>\n update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>>\n updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n remove(id: string): Promise<CollectionType<T>>\n removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n}\n\nexport interface RootCollectionClient {\n from<T extends PublicCollection>(collection: T): RootReadOnlyQueryBuilder<T>\n}\n\nexport interface RootServerCollectionClient {\n from<T extends ServerCollection>(collection: T): RootServerQueryBuilder<T>\n}\n\nexport interface RootClient {\n commerce: CommerceClient\n community: CommunityClient\n /** Set on {@link createClient} return values; optional for structural mocks. */\n events?: EventsClient\n customer: CustomerNamespace\n collections: RootCollectionClient\n lastRequestId: string | null\n getState(): ClientState\n getConfig(): ClientConfig\n}\n\nexport interface RootServerClient {\n commerce: ServerCommerceClient\n tenant: TenantIntrospectionClient\n /** Set on {@link createServerClient} return values; optional for structural mocks. */\n events?: EventsClient\n community: CommunityClient & {\n moderation: {\n banCustomer: (p: BanCustomerParams) => Promise<CommunityBan>\n unbanCustomer: (p: UnbanCustomerParams) => Promise<{ success: true }>\n }\n }\n collections: RootServerCollectionClient\n lastRequestId: string | null\n getState(): ClientState\n getConfig(): Omit<ClientServerConfig, 'secretKey'>\n}\n\nexport type RootClientWithEvents = RootClient & { events: EventsClient }\n\nexport type RootServerClientWithEvents = RootServerClient & { events: EventsClient }\n\n// ============================================================================\n// Type Utilities\n// ============================================================================\n\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]\n}\n\nexport type ExtractArrayType<T> = T extends (infer U)[] ? U : never\n","import {\n createAuthError,\n createConflictError,\n createNetworkError,\n createNotFoundError,\n createPermissionError,\n createValidationError,\n createUsageLimitError,\n createTimeoutError,\n TimeoutError,\n NetworkError,\n SDKError,\n} from '../errors'\nimport type { DebugConfig, RetryConfig } from '../../client/types'\nimport { resolveApiUrl } from '../../client/types'\nconst DEFAULT_TIMEOUT = 30000\nconst STOREFRONT_BROWSER_TIMEOUT = 15_000\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504]\nconst NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422]\nconst SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']\nconst DEFAULT_MAX_RETRIES = 3\nconst STOREFRONT_BROWSER_MAX_RETRIES = 1\n\nexport interface FetchOptions extends RequestInit {\n apiUrl?: string\n publishableKey?: string\n secretKey?: string\n customerToken?: string\n timeout?: number\n debug?: boolean | DebugConfig\n retry?: RetryConfig\n /** Called on 401 when customerToken is set and reason=token_expired. Return a new token to retry, or null to fail. */\n onUnauthorized?: () => Promise<string | null>\n}\n\nfunction debugLog(\n debug: boolean | DebugConfig | undefined,\n type: 'request' | 'response' | 'error',\n message: string,\n data?: unknown,\n) {\n if (!debug) return\n\n const shouldLog =\n debug === true ||\n (type === 'request' && (debug as DebugConfig).logRequests) ||\n (type === 'response' && (debug as DebugConfig).logResponses) ||\n (type === 'error' && (debug as DebugConfig).logErrors)\n\n if (shouldLog) {\n console.group(`[SDK ${type.toUpperCase()}] ${message}`)\n if (data) console.log(data)\n console.groupEnd()\n }\n}\n\nfunction redactSensitiveHeader(value: string): string {\n const prefix = value.toLowerCase().startsWith('bearer ') ? 'Bearer ' : ''\n return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : '****'\n}\n\nfunction redactSensitiveHeaders(headers: Headers): Record<string, string> {\n const redacted = Object.fromEntries(headers.entries())\n if (redacted.authorization) {\n redacted.authorization = redactSensitiveHeader(redacted.authorization)\n }\n if (redacted['x-preview-token']) {\n redacted['x-preview-token'] = redactSensitiveHeader(\n redacted['x-preview-token'],\n )\n }\n return redacted\n}\n\nfunction getErrorSuggestion(status: number): string | undefined {\n if (status === 400)\n return 'The request data failed validation. Check field values and types.'\n if (status === 401) return 'Please check your authentication credentials.'\n if (status === 403)\n return 'Access denied. Check your credentials or permissions.'\n if (status === 404) return 'The requested resource was not found.'\n if (status === 422) return 'The request data failed validation.'\n if (status >= 500) return 'A server error occurred. Please try again later.'\n return undefined\n}\n\nfunction isUsageLimitExceededResponse(response: Response): boolean {\n if (response.status !== 429) return false\n\n const limit = parseInt(response.headers.get('X-Usage-Limit') || '', 10)\n const current = parseInt(response.headers.get('X-Usage-Current') || '', 10)\n if (!Number.isFinite(limit) || !Number.isFinite(current)) return false\n\n return response.headers.get('X-Usage-Exceeded') === 'true' || current > limit\n}\n\n/**\n * Parse error details from HTTP response body.\n * Supports Payload native format:\n * - ValidationError: { errors: [{ message, data: { errors: [{ path, message }] } }] }\n * - Simple: { errors: [{ message, field? }] }\n * Also supports custom endpoint format ({ error: string, reason?: string, message?: string }).\n */\nasync function parseErrorBody(response: Response): Promise<{\n errorMessage: string\n userMessage: string\n reason?: string\n body?: Record<string, unknown>\n errors?: Array<{ message?: string; field?: string }>\n}> {\n const fallback = {\n errorMessage: `HTTP ${response.status}: ${response.statusText}`,\n userMessage: `Request failed (status: ${response.status})`,\n }\n\n try {\n const body = await response.json()\n const reason: string | undefined =\n typeof body.reason === 'string'\n ? body.reason\n : typeof body.code === 'string'\n ? body.code\n : undefined\n\n // Payload native: { errors: [{ message, field?, data? }] }\n if (body.errors && Array.isArray(body.errors)) {\n // Extract nested ValidationError field details\n // Payload ValidationError format: errors[].data.errors[].{path, message}\n const fieldErrors: Array<{ message?: string; field?: string }> = []\n for (const e of body.errors) {\n if (\n e.data?.errors &&\n Array.isArray(e.data.errors) &&\n e.data.errors.length > 0\n ) {\n for (const fe of e.data.errors) {\n fieldErrors.push({\n field: fe.path || fe.field,\n message: fe.message,\n })\n }\n } else if (e.field || e.message) {\n fieldErrors.push({ field: e.field, message: e.message })\n }\n }\n\n const details = (fieldErrors.length > 0 ? fieldErrors : body.errors)\n .map((e: { message?: string; field?: string }) =>\n e.field ? `${e.field}: ${e.message}` : e.message,\n )\n .filter(Boolean)\n .join('; ')\n if (details) {\n return {\n errorMessage: `HTTP ${response.status}: ${details}`,\n userMessage: details,\n reason,\n body,\n errors: fieldErrors.length > 0 ? fieldErrors : body.errors,\n }\n }\n }\n\n // Custom endpoint: { error: string, reason?: string, details?: { fieldErrors? } }\n if (typeof body.error === 'string') {\n return {\n errorMessage: `HTTP ${response.status}: ${body.error}`,\n userMessage: body.error,\n reason,\n body,\n }\n }\n\n // Fallback: { message: string }\n if (body.message) {\n return {\n errorMessage: `HTTP ${response.status}: ${body.message}`,\n userMessage: body.message,\n reason,\n body,\n }\n }\n\n return { ...fallback, reason, body }\n } catch {\n return fallback\n }\n}\n\nfunction getParsedErrorSuggestion(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n): string | undefined {\n if (status === 403 && parsed.reason === 'origin_not_allowed') {\n return 'Add the request origin to the tenant Browser API origins, then retry the browser request.'\n }\n\n return getErrorSuggestion(status)\n}\n\nasync function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// Attach requestId to any SDKError instance (readonly bypass is intentional — internal transport layer only)\nexport function attachRequestId<T extends SDKError>(\n err: T,\n id: string | undefined,\n): T {\n if (id) (err as Record<string, unknown>).requestId = id\n return err\n}\n\nfunction createHttpStatusError(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n details: Record<string, unknown>,\n requestId: string | undefined,\n): SDKError {\n const errorDetails = {\n ...details,\n ...(parsed.errors && { errors: parsed.errors }),\n ...(parsed.body && { body: parsed.body }),\n }\n const suggestion = getParsedErrorSuggestion(status, parsed)\n\n if (status === 400 || status === 422) {\n return attachRequestId(\n createValidationError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n status,\n ),\n requestId,\n )\n }\n\n if (status === 401) {\n return attachRequestId(\n createAuthError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 403) {\n return attachRequestId(\n createPermissionError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 404) {\n return attachRequestId(\n createNotFoundError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 409) {\n return attachRequestId(\n createConflictError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n return attachRequestId(\n createNetworkError(\n parsed.errorMessage,\n status,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n}\n\nexport async function httpFetch(\n url: string,\n options?: FetchOptions,\n): Promise<Response> {\n const {\n apiUrl,\n publishableKey,\n secretKey,\n customerToken,\n timeout: timeoutOption = DEFAULT_TIMEOUT,\n debug,\n retry,\n onUnauthorized,\n ...requestInit\n } = options || {}\n\n const baseUrl = resolveApiUrl(apiUrl)\n const method = (requestInit.method || 'GET').toUpperCase()\n const isPublishableKeyBrowserGet =\n typeof window !== 'undefined' &&\n !secretKey &&\n !customerToken &&\n Boolean(publishableKey) &&\n SAFE_METHODS.includes(method)\n\n const timeout =\n timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_TIMEOUT\n : timeoutOption\n\n const retryConfig = {\n maxRetries:\n retry?.maxRetries ??\n (isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_MAX_RETRIES\n : DEFAULT_MAX_RETRIES),\n retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,\n retryDelay:\n retry?.retryDelay ??\n ((attempt: number) => Math.min(1000 * 2 ** attempt, 10000)),\n }\n\n // Server auth: secretKey is now the raw opaque bearer token (sk01_...).\n // Customer auth: customerToken is a JWT.\n let authToken: string | undefined\n if (secretKey) {\n authToken = secretKey\n } else if (customerToken) {\n authToken = customerToken\n }\n\n let lastError: Error | undefined\n let hasRetried401 = false\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n const headers = new Headers(requestInit.headers)\n\n if (publishableKey) {\n headers.set('X-Publishable-Key', publishableKey)\n }\n\n if (authToken) {\n headers.set('Authorization', `Bearer ${authToken}`)\n }\n\n if (\n !headers.has('Content-Type') &&\n requestInit.body &&\n !(requestInit.body instanceof FormData)\n ) {\n headers.set('Content-Type', 'application/json')\n }\n\n // Redact sensitive headers for debug logging\n const redactedHeaders = redactSensitiveHeaders(headers)\n\n debugLog(debug, 'request', url, {\n method: requestInit.method || 'GET',\n headers: redactedHeaders,\n attempt: attempt + 1,\n })\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const response = await fetch(`${baseUrl}${url}`, {\n ...requestInit,\n headers,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n const requestId = response.headers.get('x-request-id') ?? undefined\n\n debugLog(debug, 'response', url, {\n status: response.status,\n statusText: response.statusText,\n headers: redactSensitiveHeaders(response.headers),\n })\n\n if (!response.ok) {\n // Usage limit 429 — never retry. Older servers identify this when\n // current usage is above the limit; newer servers also send\n // X-Usage-Exceeded to avoid confusing other 429s with quota exhaustion.\n if (isUsageLimitExceededResponse(response)) {\n const limit = parseInt(\n response.headers.get('X-Usage-Limit') || '0',\n 10,\n )\n const current = parseInt(\n response.headers.get('X-Usage-Current') || '0',\n 10,\n )\n const remaining = parseInt(\n response.headers.get('X-Usage-Remaining') || '0',\n 10,\n )\n\n throw attachRequestId(\n createUsageLimitError(\n `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,\n { limit, current, remaining },\n {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n },\n 'Monthly API call limit exceeded. Please upgrade your plan.',\n 'Upgrade your tenant plan to increase the monthly API call limit.',\n ),\n requestId,\n )\n }\n\n // Parse body once — captures reason field for 401 branching and error details\n const parsed = await parseErrorBody(response)\n\n // Auto-refresh customer token on 401 — only when reason=token_expired\n if (\n response.status === 401 &&\n onUnauthorized &&\n customerToken &&\n !hasRetried401 &&\n parsed.reason === 'token_expired'\n ) {\n hasRetried401 = true\n try {\n const newToken = await onUnauthorized()\n if (newToken) {\n authToken = newToken\n continue\n }\n } catch {\n // Refresh failed, fall through to throw\n }\n }\n\n const details = {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n }\n\n // Never retry non-retryable statuses regardless of user config\n if (NON_RETRYABLE_STATUSES.includes(response.status)) {\n throw createHttpStatusError(\n response.status,\n parsed,\n details,\n requestId,\n )\n }\n\n // Retryable errors\n const error = attachRequestId(\n createNetworkError(\n parsed.errorMessage,\n response.status,\n details,\n parsed.userMessage,\n getErrorSuggestion(response.status),\n ),\n requestId,\n )\n\n const method = (requestInit.method || 'GET').toUpperCase()\n if (\n attempt < retryConfig.maxRetries &&\n SAFE_METHODS.includes(method) &&\n retryConfig.retryableStatuses.includes(response.status)\n ) {\n lastError = error\n const retryDelay = retryConfig.retryDelay(attempt)\n debugLog(debug, 'error', `Retrying in ${retryDelay}ms...`, error)\n await delay(retryDelay)\n continue\n }\n\n throw error\n }\n\n return response\n } catch (error) {\n debugLog(debug, 'error', url, error)\n\n const method = (requestInit.method || 'GET').toUpperCase()\n const isSafe = SAFE_METHODS.includes(method)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError = createTimeoutError(\n `Request timed out after ${timeout}ms.`,\n { url, timeout, attempt: attempt + 1 },\n 'The request timed out.',\n 'Please check your network connection or try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = timeoutError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw timeoutError\n }\n\n if (error instanceof TypeError) {\n const networkError = createNetworkError(\n 'Network connection failed.',\n undefined,\n { url, originalError: error.message, attempt: attempt + 1 },\n 'Network connection failed.',\n 'Please check your internet connection and try again.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = networkError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw networkError\n }\n\n if (error instanceof NetworkError || error instanceof TimeoutError) {\n if (\n isSafe &&\n attempt < retryConfig.maxRetries &&\n error.status &&\n !NON_RETRYABLE_STATUSES.includes(error.status) &&\n retryConfig.retryableStatuses.includes(error.status)\n ) {\n lastError = error\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw error\n }\n\n // Re-throw any other SDKError subclass (e.g. UsageLimitError) without wrapping\n if (error instanceof SDKError) {\n throw error\n }\n\n const unknownError = createNetworkError(\n error instanceof Error\n ? error.message\n : 'An unknown network error occurred.',\n undefined,\n { url, originalError: error, attempt: attempt + 1 },\n 'An unknown error occurred.',\n 'Please try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = unknownError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw unknownError\n }\n }\n\n throw lastError ?? new NetworkError('Request failed after retries')\n}\n","export function productDetailQuery(\n params: { slug: string } | { id: string },\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n return `/api/products/detail?${search}`\n}\n\nexport function productDetailCatalogQuery(\n params: { slug: string } | { id: string },\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n return `/api/products/detail/catalog?${search}`\n}\n\nexport function listingGroupsQuery(params: { productIds: string[] }): string {\n return `/api/products/listing-groups?ids=${params.productIds.map(encodeURIComponent).join(',')}`\n}\n\nexport function listingGroupsCatalogQuery(params: {\n productIds: string[]\n}): string {\n return `/api/products/listing-groups/catalog?ids=${params.productIds.map(encodeURIComponent).join(',')}`\n}\n\ntype ListingGroupsQueryUrlOptions = {\n page?: number\n limit?: number\n sort?: string | string[]\n where?: Record<string, unknown>\n}\n\nfunction appendListingGroupsQuerySearchParams(\n search: URLSearchParams,\n options?: ListingGroupsQueryUrlOptions,\n): void {\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n if (options?.sort != null) {\n const sort = options.sort\n search.set(\n 'sort',\n Array.isArray(sort) ? sort.join(',') : sort,\n )\n }\n if (options?.where != null) {\n search.set('whereJson', JSON.stringify(options.where))\n }\n}\n\n/** GET cacheable PLP listing-groups query (full variant stock fields). */\nexport function listingGroupsQueryUrl(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n const query = search.toString()\n return `/api/products/listing-groups/query${query ? `?${query}` : ''}`\n}\n\n/** GET cacheable PLP listing-groups query (catalog / CDN-friendly). */\nexport function listingGroupsQueryCatalogUrl(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n const query = search.toString()\n return `/api/products/listing-groups/query/catalog${query ? `?${query}` : ''}`\n}\n\nexport function stockSnapshotQuery(params: { variantIds: string[] }): string {\n return `/api/products/stock?variantIds=${params.variantIds.map(encodeURIComponent).join(',')}`\n}\n","/**\n * Resolves a Payload CMS relation field value.\n * When depth is 0, relation fields return just the ID (string or number).\n * When depth > 0, they return the full document object (T).\n * This utility normalizes both cases to T | null.\n *\n * @param ref - The relation field value (T, string, number, null, or undefined)\n * @returns The resolved document object, or null if not populated\n */\nexport const resolveRelation = <T>(\n ref: T | string | number | null | undefined,\n): T | null => {\n if (\n typeof ref === 'string' ||\n typeof ref === 'number' ||\n ref === null ||\n ref === undefined\n )\n return null\n return ref\n}\n","import { resolveRelation } from '../../utils/types'\n\nexport interface MetadataImage {\n url: string\n width?: number\n height?: number\n alt?: string\n}\n\nexport interface Metadata {\n title?: string\n description?: string\n robots?: {\n index?: boolean\n follow?: boolean\n }\n alternates?: {\n canonical?: string\n }\n openGraph?: {\n title?: string\n description?: string\n siteName?: string\n images?: MetadataImage[]\n }\n twitter?: {\n card?: 'summary' | 'summary_large_image'\n title?: string\n description?: string\n images?: string[]\n }\n}\n\nexport interface ImageLike {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n sizes?: Record<\n string,\n | { url?: string | null; width?: number | null; height?: number | null }\n | undefined\n >\n}\n\nexport interface SeoInput {\n title?: string | null\n description?: string | null\n noIndex?: boolean | null\n canonical?: string | null\n openGraph?: {\n title?: string | null\n description?: string | null\n image?: ImageLike | string | null\n } | null\n}\n\nexport interface GenerateMetadataOptions {\n siteName?: string\n}\n\nexport function extractSeo(doc: Record<string, unknown>): SeoInput {\n const seo = (doc.seo ?? {}) as Record<string, unknown>\n const og = (seo.openGraph ?? {}) as Record<string, unknown>\n\n return {\n title: (seo.title as string) ?? (doc.title as string) ?? null,\n description: (seo.description as string) ?? null,\n noIndex: (seo.noIndex as boolean) ?? null,\n canonical: (seo.canonical as string) ?? null,\n openGraph: {\n title: (og.title as string) ?? null,\n description: (og.description as string) ?? null,\n image: (og.image as ImageLike | string | null) ?? null,\n },\n }\n}\n\nexport function generateMetadata(\n input: SeoInput,\n options?: GenerateMetadataOptions,\n): Metadata {\n const title = input.title ?? undefined\n const description = input.description ?? undefined\n\n const ogTitle = input.openGraph?.title ?? title\n const ogDescription = input.openGraph?.description ?? description\n const image = resolveMetaImage(input.openGraph?.image)\n\n return {\n title,\n description,\n ...(input.noIndex && { robots: { index: false, follow: false } }),\n ...(input.canonical && { alternates: { canonical: input.canonical } }),\n openGraph: {\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(options?.siteName && { siteName: options.siteName }),\n ...(image && { images: [image] }),\n },\n twitter: {\n card: image ? 'summary_large_image' : 'summary',\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(image && { images: [image.url] }),\n },\n }\n}\n\nfunction resolveMetaImage(\n ref: ImageLike | string | null | undefined,\n): MetadataImage | null {\n const image = resolveRelation<ImageLike>(ref)\n if (!image) return null\n\n // Prefer sizes['1536'] (closest to OG 1200px standard), fallback to original url\n const sized = image.sizes?.['1536']\n const url = sized?.url || image.url\n if (!url) return null\n\n const width = sized?.url ? sized.width : image.width\n const height = sized?.url ? sized.height : image.height\n\n return {\n url,\n ...(width && { width }),\n ...(height && { height }),\n ...(image.alt && { alt: image.alt }),\n }\n}\n","import type {\n ApiQueryOptions,\n PublicCollection,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { generateMetadata, extractSeo } from '../metadata'\nimport type { GenerateMetadataOptions, Metadata } from '../metadata'\nimport type { CollectionClient } from './collection-client'\nimport type { CollectionType } from './types'\n\ntype ReadOnlyCollectionApi = Pick<\n CollectionClient,\n 'requestFind' | 'requestFindById' | 'requestCount'\n>\n\n/**\n * Read-only subset of CollectionQueryBuilder.\n * Client.from() returns this type to prevent write operations at compile time.\n */\nexport type ReadOnlyQueryBuilder<T extends PublicCollection> =\n ReadOnlyCollectionQueryBuilder<T>\n\nexport class ReadOnlyCollectionQueryBuilder<T extends PublicCollection> {\n constructor(\n private api: ReadOnlyCollectionApi,\n private collection: T,\n ) {}\n\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n}\n\nexport class CollectionQueryBuilder<T extends string> {\n constructor(\n private api: CollectionClient,\n private collection: T,\n ) {}\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n * @returns Payload CMS find response with docs array and pagination\n */\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n * @returns Document object directly (no wrapper)\n */\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Create a new document\n * POST /api/{collection}\n * @returns Payload CMS mutation response with doc and message\n */\n async create(\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}`\n if (options?.file) {\n return this.api.requestCreateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n )\n }\n return this.api.requestCreate<CollectionType<T>>(endpoint, data)\n }\n\n /**\n * Update a document by ID\n * PATCH /api/{collection}/{id}\n * @returns Payload CMS mutation response with doc and message\n */\n async update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}/${String(id)}`\n if (options?.file) {\n return this.api.requestUpdateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n )\n }\n return this.api.requestUpdate<CollectionType<T>>(endpoint, data)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n * @returns Count response with totalDocs\n */\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n /**\n * Find first matching document and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) and limit: 1 automatically.\n * @returns Metadata or null if no document matches\n */\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Find document by ID and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) automatically.\n * @returns Metadata (throws on 404)\n */\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n * @returns Payload CMS find response with updated docs\n */\n async updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestUpdateMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where, data },\n )\n }\n\n /**\n * Delete a document by ID\n * DELETE /api/{collection}/{id}\n * @returns Deleted document object directly (no wrapper)\n */\n async remove(id: string): Promise<CollectionType<T>> {\n return this.api.requestDelete<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n )\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n * @returns Payload CMS find response with deleted docs\n */\n async removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestDeleteMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where },\n )\n }\n}\n\nexport class ServerCollectionQueryBuilder<\n T extends ServerCollection,\n> extends CollectionQueryBuilder<T> {}\n","import { HttpClient } from './http-client'\nimport type {\n ApiQueryOptions,\n PublicCollection,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n CollectionQueryBuilder,\n ReadOnlyCollectionQueryBuilder,\n ServerCollectionQueryBuilder,\n type ReadOnlyQueryBuilder,\n} from './query-builder'\n\nfunction buildPayloadFormData(\n data: unknown,\n file: File | Blob,\n filename?: string,\n): FormData {\n const formData = new FormData()\n formData.append('file', file, filename)\n if (data != null) {\n formData.append('_payload', JSON.stringify(data))\n }\n return formData\n}\n\nexport class CollectionClient<\n TCollection extends string = PublicCollection,\n> extends HttpClient {\n from<T extends TCollection>(collection: T): CollectionQueryBuilder<T> {\n return new CollectionQueryBuilder(this, collection)\n }\n\n // ============================================================================\n // Payload-native methods\n // ============================================================================\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n */\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a custom endpoint\n * POST /api/...custom-endpoint\n */\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a cacheable GET custom endpoint.\n */\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n */\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Create document\n * POST /api/{collection}\n */\n async requestCreate<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document\n * PATCH /api/{collection}/{id}\n */\n async requestUpdate<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n */\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n */\n async requestUpdateMany<T = unknown>(\n endpoint: string,\n data: { where?: unknown; data: unknown },\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: JSON.stringify(data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Delete document\n * DELETE /api/{collection}/{id}\n */\n async requestDelete<T = unknown>(endpoint: string): Promise<T> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n */\n async requestDeleteMany<T = unknown>(\n endpoint: string,\n data: { where?: unknown },\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'DELETE',\n body: JSON.stringify(data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Create document with file upload\n * POST /api/{collection} (multipart/form-data)\n */\n async requestCreateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document with file upload\n * PATCH /api/{collection}/{id} (multipart/form-data)\n */\n async requestUpdateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n}\n\nexport class ServerCollectionClient extends CollectionClient<ServerCollection> {\n override from<T extends ServerCollection>(\n collection: T,\n ): ServerCollectionQueryBuilder<T> {\n return new ServerCollectionQueryBuilder(this, collection)\n }\n}\n\nexport class ReadOnlyCollectionClient extends HttpClient {\n from<T extends PublicCollection>(collection: T): ReadOnlyQueryBuilder<T> {\n return new ReadOnlyCollectionQueryBuilder(this, collection)\n }\n\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n}\n","import {\n createApiError,\n createValidationError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from '../internal/errors'\nimport { attachRequestId } from '../internal/utils/http'\n\n/**\n * Shared JSON response parser for BaseApi and CartApi.\n * Parses response JSON body and throws typed errors based on the `reason` field.\n * Only called for responses that passed httpFetch (i.e. response.ok = true);\n * handles application-level errors embedded in 2xx bodies.\n */\nexport async function parseApiResponse<T>(\n response: Response,\n endpoint: string,\n): Promise<T> {\n let data: Record<string, unknown>\n try {\n data = await response.json()\n } catch {\n throw createApiError(\n `Invalid JSON response from ${endpoint}`,\n response.status,\n undefined,\n 'Server returned an invalid response.',\n 'Check if the API endpoint is available.',\n )\n }\n\n if (data.error) {\n const errorMessage =\n typeof data.error === 'string' ? data.error : 'Unknown API error'\n const reason = typeof data.reason === 'string' ? data.reason : undefined\n const requestId = response.headers.get('x-request-id') ?? undefined\n const retryAfterRaw = response.headers.get('Retry-After')\n const retryAfter = retryAfterRaw ? parseInt(retryAfterRaw, 10) || undefined : undefined\n\n if (reason === 'validation_failed') {\n throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId)\n }\n if (\n reason === 'token_expired' ||\n reason === 'token_invalid' ||\n reason === 'preview_token_invalid' ||\n reason === 'preview_token_required' ||\n reason === 'key_invalid' ||\n reason === 'key_revoked'\n ) {\n throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'forbidden') {\n throw attachRequestId(createPermissionError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'rate_limit_exceeded') {\n throw attachRequestId(createRateLimitError(errorMessage, retryAfter, data, errorMessage), requestId)\n }\n if (reason === 'not_found') {\n throw attachRequestId(createNotFoundError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'conflict') {\n throw attachRequestId(createConflictError(errorMessage, data, errorMessage), requestId)\n }\n throw attachRequestId(\n createApiError(errorMessage, response.status, data, errorMessage, 'An error occurred while processing the request.'),\n requestId,\n )\n }\n\n return data as T\n}\n","import { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { SDKError } from '../internal/errors'\nimport { parseApiResponse } from '../api/parse-response'\nimport type { CollectionType } from '../collection/types'\n\nexport interface CommunityClientOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\n/** Public read shape for `posts` (tenant-scoped author profiles). */\nexport type CommunityPost = CollectionType<'posts'>\n\n/** Public read shape for `comments`. */\nexport type CommunityComment = CollectionType<'comments'>\n\n/** @deprecated Use {@link CommunityComment}. */\nexport type Comment = CommunityComment\n\n/** Public read shape for `post-categories`. */\nexport type CommunityPostCategory = CollectionType<'post-categories'>\n\n/** Public read shape for `post-tags`. */\nexport type CommunityPostTag = CollectionType<'post-tags'>\n\nexport type CommunityPostListSort =\n | 'createdAt'\n | '-createdAt'\n | 'lastActivityAt'\n | '-lastActivityAt'\n | 'viewCount'\n | '-viewCount'\n | 'commentCount'\n | '-commentCount'\n\nexport type CommunityCommentListSort = 'createdAt' | '-createdAt'\n\nexport interface Reaction {\n id: string\n post?: string\n comment?: string\n type?: string\n createdAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionSummary {\n counts: Record<string, number>\n total: number\n userReactions: string[]\n}\n\nexport interface Bookmark {\n id: string\n post?: string\n createdAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionType {\n id: string\n title: string\n slug: string\n emoji?: string\n [key: string]: unknown\n}\n\nexport interface PaginatedResponse<T> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\nconst DEFAULT_POST_LIST_SORT: CommunityPostListSort = '-lastActivityAt'\nconst DEFAULT_COMMENT_LIST_SORT: CommunityCommentListSort = '-createdAt'\n\nexport class CommunityClient {\n private readonly publishableKey: string\n private readonly secretKey?: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: CommunityClientOptions) {\n this.publishableKey = requirePublishableKeyForSecret(\n 'CommunityClient',\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n private buildQuery(params?: Record<string, string | number | undefined>): string {\n if (!params) return ''\n const entries = Object.entries(params)\n .filter((e): e is [string, string | number] => e[1] !== undefined)\n .map(([k, v]) => [k, String(v)])\n return entries.length ? `?${new URLSearchParams(entries).toString()}` : ''\n }\n\n private buildPostsListQuery(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params?.sort ?? DEFAULT_POST_LIST_SORT\n urlParams.set('sort', sort)\n if (params?.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params?.page !== undefined) urlParams.set('page', String(params.page))\n if (params?.categoryId !== undefined) {\n urlParams.set('where[categories][in]', params.categoryId)\n }\n if (params?.tagId !== undefined) {\n urlParams.set('where[tags][in]', params.tagId)\n }\n return `/api/posts?${urlParams.toString()}`\n }\n\n private buildCommentsListQuery(params: {\n postId?: string\n parentId?: string\n rootComment?: string\n topLevelOnly?: boolean\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT\n urlParams.set('sort', sort)\n if (params.postId !== undefined) {\n urlParams.set('where[post][equals]', params.postId)\n }\n if (params.parentId !== undefined) {\n urlParams.set('where[parent][equals]', params.parentId)\n }\n if (params.rootComment !== undefined) {\n urlParams.set('where[rootComment][equals]', params.rootComment)\n }\n if (params.topLevelOnly) {\n urlParams.set('where[parent][exists]', 'false')\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n return `/api/comments?${urlParams.toString()}`\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n body?: unknown,\n ): Promise<T> {\n const token =\n typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n customerToken: token ?? undefined,\n ...(token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n createPost(params: {\n title?: string | null\n content?: unknown\n categories?: string[]\n thumbnail?: string\n }): Promise<CommunityPost> {\n return this.execute<CommunityPost>('/api/posts', 'POST', params)\n }\n\n /**\n * Public post feed. Server applies the same visibility contract as\n * `communityPostRead` (published + visible + moderation-safe).\n */\n listPosts(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n this.buildPostsListQuery(params),\n 'GET',\n )\n }\n\n listPostCategories(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostCategory>> {\n return this.execute<PaginatedResponse<CommunityPostCategory>>(\n `/api/post-categories${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n listPostTags(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostTag>> {\n return this.execute<PaginatedResponse<CommunityPostTag>>(\n `/api/post-tags${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getMyPosts(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getTrending(params?: {\n page?: number\n limit?: number\n period?: string\n metric?: 'reactions' | 'comments' | 'views' | 'activity'\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/trending${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n incrementView(params: { postId: string }): Promise<{ viewCount: number }> {\n return this.execute<{ viewCount: number }>(\n `/api/posts/${params.postId}/view`,\n 'POST',\n )\n }\n\n reportPost(params: {\n postId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { postId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/report`,\n 'POST',\n body,\n )\n }\n\n // Comments\n\n createComment(params: {\n postId: string\n body: string\n parentId?: string\n }): Promise<CommunityComment> {\n const { postId, parentId, body: commentBody } = params\n const body: Record<string, unknown> = { post: postId, body: commentBody }\n if (parentId !== undefined) {\n body.parent = parentId\n }\n return this.execute<CommunityComment>('/api/comments', 'POST', body)\n }\n\n /**\n * List comments for a post.\n *\n * - Default: all visible comments on the post (any depth).\n * - `topLevelOnly: true`: only root comments (`parent` unset).\n * - `rootComment`: comments belonging to a thread rooted at that comment.\n */\n listComments(params: {\n postId: string\n page?: number\n limit?: number\n rootComment?: string\n topLevelOnly?: boolean\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { postId, page, limit, rootComment, topLevelOnly, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n postId,\n page,\n limit,\n rootComment,\n topLevelOnly,\n sort,\n }),\n 'GET',\n )\n }\n\n /** Direct replies to a comment (`where[parent][equals]`). */\n listReplies(params: {\n commentId: string\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { commentId, page, limit, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n parentId: commentId,\n page,\n limit,\n sort,\n }),\n 'GET',\n )\n }\n\n updateComment(params: {\n commentId: string\n body: string\n }): Promise<CommunityComment> {\n const { commentId, body } = params\n return this.execute<CommunityComment>(\n `/api/comments/${commentId}`,\n 'PATCH',\n { body },\n )\n }\n\n deleteComment(params: {\n commentId: string\n }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/comments/${params.commentId}`,\n 'DELETE',\n )\n }\n\n reportComment(params: {\n commentId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { commentId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/report`,\n 'POST',\n body,\n )\n }\n\n // Reactions\n\n addReaction(params: {\n postId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<Reaction> {\n const { postId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.execute<Reaction>('/api/reactions', 'POST', {\n post: postId,\n type: reactionType,\n })\n }\n\n removeReaction(params: {\n postId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { postId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n addCommentReaction(params: {\n commentId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<Reaction> {\n const { commentId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addCommentReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.execute<Reaction>('/api/reactions', 'POST', {\n comment: commentId,\n type: reactionType,\n })\n }\n\n removeCommentReaction(params: {\n commentId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { commentId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n getReactionSummary(params: {\n postId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/posts/${params.postId}/reactions`,\n 'GET',\n )\n }\n\n getCommentReactionSummary(params: {\n commentId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/comments/${params.commentId}/reactions`,\n 'GET',\n )\n }\n\n getReactionTypes(): Promise<PaginatedResponse<ReactionType>> {\n return this.execute<PaginatedResponse<ReactionType>>(\n '/api/reaction-types?limit=100',\n 'GET',\n )\n }\n\n // Bookmarks\n\n addBookmark(params: { postId: string }): Promise<Bookmark> {\n return this.execute<Bookmark>('/api/bookmarks', 'POST', {\n post: params.postId,\n })\n }\n\n removeBookmark(params: {\n postId: string\n }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/posts/${params.postId}/bookmark`,\n 'DELETE',\n )\n }\n\n getMyBookmarks(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<Bookmark>> {\n return this.execute<PaginatedResponse<Bookmark>>(\n `/api/bookmarks/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n // Profiles\n\n listProfileLists(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CollectionType<'customer-profile-lists'>>> {\n return this.execute<PaginatedResponse<CollectionType<'customer-profile-lists'>>>(\n `/api/customer-profile-lists${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n async getProfileList(\n params: { slug: string } | { id: string },\n ): Promise<CollectionType<'customer-profile-lists'> | null> {\n const query =\n 'slug' in params\n ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1`\n : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`\n const res = await this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(`/api/customer-profile-lists${query}`, 'GET')\n return res.docs[0] ?? null\n }\n\n updatePublicProfile(body: {\n displayName?: string | null\n handle?: string | null\n avatar?: string | null\n bio?: string | null\n bioRichText?: CollectionType<'customer-profiles'>['bioRichText']\n }): Promise<CollectionType<'customer-profiles'>> {\n return this.execute<CollectionType<'customer-profiles'>>(\n '/api/customers/me/profile',\n 'PATCH',\n body,\n )\n }\n}\n","import { ApiError, SDKError } from '../internal/errors'\nimport { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport { resolveApiUrl, type PayloadFindResponse } from '../client/types'\nimport type { Order } from '../../payload-types'\nimport type {\n CustomerAuthResponse,\n CustomerRefreshResponse,\n CustomerRegisterData,\n CustomerRegisterResponse,\n CustomerLoginData,\n CustomerProfile,\n CustomerAuthOptions,\n UpdateProfileData,\n} from './types'\n\nconst DEFAULT_TIMEOUT = 15000\n\nfunction safeGetItem(key: string): string | null {\n try {\n return localStorage.getItem(key)\n } catch {\n return null\n }\n}\n\n/**\n * Customer authentication client.\n *\n * Manages customer registration, login, logout, and token lifecycle.\n * All requests include X-Publishable-Key for tenant resolution.\n */\nexport class CustomerAuth {\n private publishableKey: string\n private baseUrl: string\n private token: string | null\n private onTokenChange?: (token: string | null) => void\n private refreshPromise: Promise<CustomerRefreshResponse> | null = null\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.publishableKey = publishableKey\n this.baseUrl = resolveApiUrl(apiUrl)\n\n const persist = options?.persist ?? true\n if (persist) {\n const key = typeof persist === 'string' ? persist : 'customer-token'\n const isBrowser = typeof window !== 'undefined'\n this.token = isBrowser ? safeGetItem(key) : null\n this.onTokenChange = isBrowser\n ? (token) => {\n try {\n if (token) localStorage.setItem(key, token)\n else localStorage.removeItem(key)\n } catch {\n // Safari private mode, iframe sandbox, etc.\n }\n }\n : undefined\n } else {\n this.token = options?.token ?? null\n this.onTokenChange = options?.onTokenChange\n }\n }\n\n /**\n * Register a new customer account\n */\n async register(\n data: CustomerRegisterData,\n ): Promise<CustomerRegisterResponse> {\n return this.requestJson('/api/customers/register', {\n method: 'POST',\n body: JSON.stringify(data),\n })\n }\n\n /**\n * Login with email and password. Stores the token internally.\n */\n async login(data: CustomerLoginData): Promise<CustomerAuthResponse> {\n const result: CustomerAuthResponse = await this.requestJson(\n '/api/customers/login',\n {\n method: 'POST',\n body: JSON.stringify(data),\n },\n )\n\n this.setToken(result.token)\n return result\n }\n\n /**\n * Refresh the current token. Requires a valid (non-expired) token.\n */\n async refreshToken(): Promise<CustomerRefreshResponse> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n if (this.refreshPromise) return this.refreshPromise\n\n this.refreshPromise = this._doRefreshToken()\n try {\n return await this.refreshPromise\n } finally {\n this.refreshPromise = null\n }\n }\n\n private async _doRefreshToken(): Promise<CustomerRefreshResponse> {\n const result: CustomerRefreshResponse = await this.requestJson(\n '/api/customers/refresh',\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.token}` },\n },\n )\n\n this.setToken(result.token)\n return result\n }\n\n /**\n * Clear the stored token\n */\n logout(): void {\n this.setToken(null)\n }\n\n /**\n * Get the current authenticated customer's profile\n */\n async me(): Promise<CustomerProfile | null> {\n if (!this.token) return null\n\n try {\n const data = await this.requestJson<{ customer: CustomerProfile }>(\n '/api/customers/me',\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.token}` },\n },\n )\n return data.customer ?? null\n } catch (error) {\n if (error instanceof SDKError && error.status === 401) {\n this.setToken(null)\n return null\n }\n throw error\n }\n }\n\n /**\n * Request a password reset email\n */\n async forgotPassword(email: string): Promise<void> {\n await this.requestJson('/api/customers/forgot-password', {\n method: 'POST',\n body: JSON.stringify({ email }),\n })\n }\n\n /**\n * Reset password using a token from the reset email\n */\n async resetPassword(token: string, password: string): Promise<void> {\n await this.requestJson('/api/customers/reset-password', {\n method: 'POST',\n body: JSON.stringify({ token, password }),\n })\n }\n\n /**\n * Update the authenticated customer's profile (name, phone, marketingConsent)\n */\n async updateProfile(data: UpdateProfileData): Promise<CustomerProfile> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n const result = await this.requestJson<{ customer: CustomerProfile }>(\n '/api/customers/me',\n {\n method: 'PATCH',\n headers: { Authorization: `Bearer ${this.token}` },\n body: JSON.stringify(data),\n },\n )\n return result.customer\n }\n\n /**\n * Change the password of the currently authenticated customer\n */\n async changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<void> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n await this.requestJson('/api/customers/change-password', {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.token}` },\n body: JSON.stringify({ currentPassword, newPassword }),\n })\n }\n\n /**\n * Get the authenticated customer's orders with pagination and optional status filter\n */\n async getMyOrders(options?: {\n page?: number\n limit?: number\n status?: string\n }): Promise<PayloadFindResponse<Order>> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n const params = new URLSearchParams()\n if (options?.page) params.set('page', String(options.page))\n if (options?.limit) params.set('limit', String(options.limit))\n if (options?.status) params.set('status', options.status)\n\n const qs = params.toString()\n return this.requestJson(`/api/customers/me/orders${qs ? `?${qs}` : ''}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.token}` },\n })\n }\n\n /**\n * Get the current token (or null if not authenticated)\n */\n getToken(): string | null {\n return this.token\n }\n\n /**\n * Set the token manually (e.g. from SSR)\n */\n setToken(token: string | null): void {\n this.token = token\n this.onTokenChange?.(token)\n }\n\n /**\n * Check if the customer is currently authenticated\n */\n isAuthenticated(): boolean {\n return this.token !== null\n }\n\n /**\n * Internal: make a request with timeout and error handling.\n * Auth endpoints don't retry — failures are final.\n */\n private async requestJson<T = unknown>(\n path: string,\n init: RequestInit,\n ): Promise<T> {\n const headers = new Headers(init.headers)\n headers.set('X-Publishable-Key', this.publishableKey)\n if (!headers.has('Content-Type') && init.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await httpFetch(path, {\n ...init,\n apiUrl: this.baseUrl,\n publishableKey: this.publishableKey,\n headers,\n timeout: DEFAULT_TIMEOUT,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<T>(response, path)\n }\n}\n","import { CustomerAuth } from './customer-auth'\nimport type { CustomerAuthOptions } from './types'\n\n/**\n * Customer namespace. Currently exposes .auth; reserved for future customer-\n * scoped capabilities (addresses, preferences, etc.).\n */\nexport class CustomerNamespace {\n readonly auth: CustomerAuth\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.auth = new CustomerAuth(publishableKey, options, apiUrl)\n }\n}\n","import type { Cart, CartItem } from '../../payload-types'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { createConfigError, SDKError } from '../internal/errors'\nimport { parseApiResponse } from './parse-response'\n\nexport interface CartApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type AddItemParams = {\n cartId: string\n product: string\n variant: string\n option: string\n quantity: number\n}\n\nexport type UpdateItemParams = {\n cartItemId: string\n quantity: number\n}\n\nexport type RemoveItemParams = {\n cartItemId: string\n}\n\nexport type ApplyDiscountParams = {\n cartId: string\n discountCode: string\n}\n\nexport type RemoveDiscountParams = {\n cartId: string\n}\n\nexport type ClearCartParams = {\n cartId: string\n}\n\nexport class CartApi {\n private readonly publishableKey: string\n private readonly secretKey?: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: CartApiOptions) {\n if (!options.secretKey && !options.customerToken) {\n throw createConfigError(\n 'Either secretKey or customerToken is required for CartApi.',\n )\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n 'CartApi',\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST',\n body?: unknown,\n ): Promise<T> {\n const token =\n typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n customerToken: token ?? undefined,\n ...(token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n getCart(cartId: string): Promise<Cart> {\n return this.execute<Cart>(`/api/carts/${cartId}`, 'GET')\n }\n\n addItem(params: AddItemParams): Promise<CartItem> {\n return this.execute<CartItem>('/api/carts/add-item', 'POST', params)\n }\n\n updateItem(params: UpdateItemParams): Promise<CartItem> {\n return this.execute<CartItem>('/api/carts/update-item', 'POST', params)\n }\n\n removeItem(params: RemoveItemParams): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n '/api/carts/remove-item',\n 'POST',\n params,\n )\n }\n\n applyDiscount(params: ApplyDiscountParams): Promise<Cart> {\n return this.execute<Cart>('/api/carts/apply-discount', 'POST', params)\n }\n\n removeDiscount(params: RemoveDiscountParams): Promise<Cart> {\n return this.execute<Cart>('/api/carts/remove-discount', 'POST', params)\n }\n\n clearCart(params: ClearCartParams): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n '/api/carts/clear',\n 'POST',\n params,\n )\n }\n}\n","import { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { createConfigError, SDKError } from '../internal/errors'\nimport { parseApiResponse } from './parse-response'\n\nexport interface ServerApiOptions {\n publishableKey?: string\n secretKey: string\n apiUrl?: string\n onRequestId?: (id: string | null) => void\n}\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n headers?: Record<string, string>\n}\n\nexport abstract class BaseApi {\n protected readonly publishableKey: string\n protected readonly secretKey: string\n protected readonly apiUrl?: string\n protected readonly onRequestId?: (id: string | null) => void\n\n constructor(apiName: string, options: ServerApiOptions) {\n if (!options.secretKey) {\n throw createConfigError(`secretKey is required for ${apiName}.`)\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n apiName,\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.onRequestId = options.onRequestId\n }\n\n protected async request<T>(\n endpoint: string,\n body: unknown,\n options?: RequestOptions,\n ): Promise<T> {\n const method = options?.method ?? 'POST'\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n ...(body !== undefined && { body: JSON.stringify(body) }),\n ...(options?.headers && { headers: options.headers }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\nimport { SDKError } from '../internal/errors'\nimport {\n listingGroupsCatalogQuery,\n listingGroupsQuery,\n productDetailCatalogQuery,\n productDetailQuery,\n stockSnapshotQuery,\n} from '../internal/utils/query-string'\nimport type {\n ProductListingGroup,\n ProductVariantShape,\n} from '../../utils/ecommerce'\nimport type { PublicProduct } from '../collection/types'\nimport type { ProductUpsertInput } from './product-upsert-contract'\n\nexport type ProductApiOptions = ServerApiOptions\n\nexport type StockCheckParams = {\n items: Array<{\n variantId: string\n quantity: number\n }>\n}\n\nexport type StockCheckResult = {\n variantId: string\n status: 'available' | 'not_published' | 'archived' | 'not_found'\n available: boolean\n availableStock: number\n isUnlimited: boolean\n requestedQuantity: number\n error?: string\n}\n\nexport type StockCheckResponse = {\n results: StockCheckResult[]\n allAvailable: boolean\n}\n\nexport type ListingGroupsParams = {\n productIds: string[]\n}\n\nexport type ProductListingGroupVariant = Pick<\n ProductVariantShape,\n | 'id'\n | 'optionValues'\n | 'price'\n | 'compareAtPrice'\n | 'stock'\n | 'isUnlimited'\n | 'isActive'\n | 'thumbnail'\n | 'images'\n | '_order'\n>\n\nexport type ProductListingGroupSummary =\n ProductListingGroup<ProductListingGroupVariant>\n\ntype ProductListingGroupsProductVariants = NonNullable<\n PublicProduct['variants']\n>\ntype ProductListingGroupsProductPrimaryMediaItemId =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ProductListingGroupsProduct = Omit<PublicProduct, 'variants'> & {\n id: string\n slug: string\n title: string\n primaryMediaItemId?: ProductListingGroupsProductPrimaryMediaItemId\n variants?:\n | (Omit<ProductListingGroupsProductVariants, 'docs'> & {\n docs: ProductListingGroupVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsItem = {\n product: ProductListingGroupsProduct\n groups: ProductListingGroupSummary[]\n}\n\nexport type ProductListingGroupsResponse = {\n /**\n * Matching products in the same order as the requested productIds, excluding\n * ids that were not found, not published, or not accessible for the current\n * tenant/key.\n */\n docs: ProductListingGroupsItem[]\n /** Requested productIds that could not be returned. */\n missing: string[]\n}\n\nexport type ProductDetailParams = { slug: string } | { id: string }\nexport type ProductDetailPreviewParams = { id: string }\nexport type ProductDetailPreviewOptions = {\n previewToken: string\n}\n\nexport interface ProductDetailVariantOptionValue {\n optionId: string | number\n optionSlug: string\n valueId: string | number\n valueSlug: string\n value?: string | null\n}\n\nexport type ProductDetailMedia =\n | string\n | number\n | {\n id?: string | number | null\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n }\n\nexport type ProductOptionValueColorSwatch = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductOptionValueMediaSwatch<TMedia = ProductDetailMedia> = {\n type: 'media'\n mediaItemId: TMedia\n color?: null\n}\n\nexport type ProductOptionValueSwatch<TMedia = ProductDetailMedia> =\n | ProductOptionValueColorSwatch\n | ProductOptionValueMediaSwatch<TMedia>\n | null\n\nexport type ProductUpsertSwatchInput =\n | ProductOptionValueColorSwatch\n | ProductOptionValueMediaSwatch<string>\n\nexport type ProductDetailMediaValue =\n | string\n | number\n | ProductDetailMedia\n | null\n\nexport type ProductDetailSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDetailDisplayMediaSource =\n | 'listing_primary'\n | 'product_primary'\n | 'product_pool'\n | 'none'\n\n/** Selection + display sources returned by `resolveProductSelection()` media. */\nexport type ProductDetailMediaPointerSource =\n | ProductDetailSelectionMediaSource\n | ProductDetailDisplayMediaSource\n\nexport interface ProductDetailVariant {\n id: string | number\n optionKey: string\n title?: string | null\n displayName: string\n sku?: string | null\n price: number\n compareAtPrice?: number | null\n stock: number\n reservedStock: number\n isUnlimited: boolean\n isActive: boolean\n thumbnail?: ProductDetailMedia | null\n images?: ProductDetailMedia[]\n media?: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source: ProductDetailSelectionMediaSource\n }\n optionValues: ProductDetailVariantOptionValue[]\n}\n\nexport interface ProductDetailOptionValue {\n id: string | number\n value: string\n slug: string\n swatch?: ProductOptionValueSwatch<ProductDetailMedia>\n}\n\nexport interface ProductDetailOption {\n id: string | number\n title: string\n slug: string\n values: ProductDetailOptionValue[]\n}\n\nexport interface ProductDetailBrand {\n id: string | number\n name: string\n slug?: string | null\n logo?: unknown | null\n}\n\nexport interface ProductDetailCategory {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailTag {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailImage {\n id: string | number\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n}\n\nexport interface ProductDetailVideo {\n id: string | number\n url?: string | null\n}\n\nexport interface ProductDetailListing {\n minPrice?: number | null\n maxPrice?: number | null\n minCompareAtPrice?: number | null\n maxCompareAtPrice?: number | null\n isPriceRange?: boolean | null\n primaryImage?: ProductDetailMedia | null\n availableForSale?: boolean | null\n selectionHintVariant?: string | number | null\n}\n\nexport type ProductDetailCatalogVariant = Omit<\n ProductDetailVariant,\n 'stock' | 'reservedStock'\n>\n\nexport type ProductDetailCatalogListing = Omit<\n ProductDetailListing,\n 'availableForSale'\n> & {\n liveStockRequired: true\n}\n\nexport interface ProductDetailCatalog {\n product: Omit<ProductDetail['product'], 'totalInventory'>\n variants: ProductDetailCatalogVariant[]\n options: ProductDetail['options']\n brand: ProductDetail['brand']\n categories: ProductDetail['categories']\n tags: ProductDetail['tags']\n images: ProductDetail['images']\n videos: ProductDetail['videos']\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n listing: ProductDetailCatalogListing\n}\n\nexport type StockSnapshotItemStatus =\n | 'available'\n | 'not_published'\n | 'archived'\n | 'not_found'\n\nexport interface StockSnapshotItem {\n variantId: string\n status: StockSnapshotItemStatus\n availableStock: number\n availableForSale: boolean\n isUnlimited: boolean\n}\n\nexport interface StockSnapshotResponse {\n snapshots: StockSnapshotItem[]\n}\n\nexport type StockSnapshotParams = {\n variantIds: string[]\n}\n\nexport interface ProductDetail {\n product: {\n id: string | number\n slug: string\n title: string\n subtitle?: string | null\n description?: string | null\n content?: unknown\n publishedAt?: string | null\n status: string\n totalInventory: number | null\n totalVariants: number\n hasUnlimitedVariant: boolean\n hasOnlyDefaultVariant: boolean\n }\n variants: ProductDetailVariant[]\n options: ProductDetailOption[]\n brand: ProductDetailBrand | null\n categories: ProductDetailCategory[]\n tags: ProductDetailTag[]\n images: ProductDetailImage[]\n videos: ProductDetailVideo[]\n /** Canonical product primary pointer (pool member). */\n primaryMediaItemId?: ProductDetailMediaValue\n listing: ProductDetailListing\n}\n\nexport type ProductDetailUnavailableReason =\n | 'not_found'\n | 'not_published'\n | 'feature_disabled'\n\nexport type ProductDetailResult =\n | { found: true; product: ProductDetail }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nexport type ProductDetailCatalogResult =\n | { found: true; product: ProductDetailCatalog }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nconst PRODUCT_DETAIL_UNAVAILABLE_REASONS = new Set<string>([\n 'not_found',\n 'not_published',\n 'feature_disabled',\n])\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction readProductDetailUnavailableReason(\n value: unknown,\n): ProductDetailUnavailableReason | undefined {\n if (!isRecord(value)) return undefined\n\n const directReason = value.reason ?? value.code\n if (\n typeof directReason === 'string' &&\n PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)\n ) {\n return directReason as ProductDetailUnavailableReason\n }\n\n return readProductDetailUnavailableReason(value.body)\n}\n\nexport function productDetailResultFromError(\n error: unknown,\n): ProductDetailResult | undefined {\n if (!(error instanceof SDKError) || error.status !== 404) return undefined\n\n const reason = readProductDetailUnavailableReason(error.details)\n if (!reason) return undefined\n\n return { found: false, reason }\n}\n\nexport type ProductUpsertOptionSwatchInput = {\n type?: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: string | null\n}\n\nexport type ProductUpsertOptionValueInput = {\n id?: string\n value: string\n slug?: string\n swatch?: ProductUpsertSwatchInput | null\n metadata?: unknown\n}\n\nexport type ProductUpsertOptionValuePayload = ProductUpsertOptionValueInput\n\nfunction rejectLegacyOptionValueSwatchColor(\n value: ProductUpsertOptionValueInput,\n): void {\n if (\n Object.prototype.hasOwnProperty.call(\n value as Record<string, unknown>,\n 'swatchColor',\n )\n ) {\n throw new TypeError(\n 'Product upsert option values no longer accept legacy flat \"swatchColor\"; use nested \"swatch\" instead.',\n )\n }\n}\n\nfunction normalizeProductUpsertOptionValue(\n value: ProductUpsertOptionValueInput,\n): ProductUpsertOptionValuePayload {\n rejectLegacyOptionValueSwatchColor(value)\n return value\n}\n\nfunction normalizeProductUpsertParams(\n params: ProductUpsertParams,\n): ProductUpsertInput {\n const options = params.options ?? []\n const variants = params.variants ?? []\n if (!options.length) {\n return { ...params, options, variants } as ProductUpsertInput\n }\n return {\n ...params,\n options: options.map((option) => ({\n ...option,\n values: option.values.map((value) =>\n normalizeProductUpsertOptionValue(value),\n ),\n })),\n variants,\n } as ProductUpsertInput\n}\n\nexport type ProductUpsertOptionInput = {\n id?: string\n title: string\n slug?: string\n values: ProductUpsertOptionValueInput[]\n}\n\nexport type ProductUpsertVariantOptionValue =\n | string\n | {\n valueSlug?: string\n valueId?: string\n value?: string\n }\n\nexport type ProductUpsertVariantInput = {\n id?: string\n optionValues?: Record<string, ProductUpsertVariantOptionValue> | string[]\n sku?: string | null\n title?: string | null\n price: number\n compareAtPrice?: number | null\n stock?: number\n isUnlimited?: boolean\n weight?: number | null\n requiresShipping?: boolean\n barcode?: string | null\n externalId?: string | null\n isActive?: boolean\n images?: string[]\n metadata?: unknown\n}\n\nexport type ProductUpsertParams = {\n product: Record<string, unknown> & { id?: string; title?: string }\n options?: ProductUpsertOptionInput[]\n variants?: ProductUpsertVariantInput[]\n}\n\n/** Console `POST /api/products/upsert` field allowlist error reasons. */\nexport const PRODUCT_UPSERT_UNKNOWN_FIELD_REASON = 'unknown_field' as const\nexport const PRODUCT_UPSERT_READONLY_FIELD_REASON =\n 'product_field_readonly' as const\nexport const PRODUCT_GRAPH_CONFLICT_REASON = 'graph_conflict' as const\nexport const PRODUCT_GRAPH_REVISION_REQUIRED_REASON =\n 'graph_revision_required' as const\n\nexport type ProductUpsertFieldValidationErrorReason =\n | typeof PRODUCT_UPSERT_UNKNOWN_FIELD_REASON\n | typeof PRODUCT_UPSERT_READONLY_FIELD_REASON\n\n/** 400 response body when upsert rejects unknown or server-managed product fields. */\nexport type ProductUpsertFieldValidationErrorBody = {\n error: string\n reason: ProductUpsertFieldValidationErrorReason\n field: string\n requestId?: string\n}\n\nexport function isProductUpsertFieldValidationErrorBody(\n value: unknown,\n): value is ProductUpsertFieldValidationErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n const reason = body.reason\n return (\n typeof body.error === 'string' &&\n typeof body.field === 'string' &&\n (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON ||\n reason === PRODUCT_UPSERT_READONLY_FIELD_REASON)\n )\n}\n\nexport type ProductUpsertGraphConflictErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_CONFLICT_REASON\n currentGraphRevision: string\n currentGraphUpdatedAt: string\n requestId?: string\n}\n\nexport function isProductUpsertGraphConflictErrorBody(\n value: unknown,\n): value is ProductUpsertGraphConflictErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_CONFLICT_REASON &&\n typeof body.currentGraphRevision === 'string' &&\n typeof body.currentGraphUpdatedAt === 'string'\n )\n}\n\nexport type ProductUpsertGraphRevisionRequiredErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n requestId?: string\n}\n\nexport function isProductUpsertGraphRevisionRequiredErrorBody(\n value: unknown,\n): value is ProductUpsertGraphRevisionRequiredErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n )\n}\n\nexport type ProductUpsertResponse =\n | { ok: true; product: PublicProduct; listingProjectionStale: boolean }\n | {\n ok: false\n failedEntity: 'product' | 'option' | 'option-value' | 'variant'\n failedIndex?: number\n message: string\n }\n\nexport class ProductApi extends BaseApi {\n constructor(options: ProductApiOptions) {\n super('ProductApi', options)\n }\n\n /**\n * Check point-in-time stock availability for one or more product variants.\n * Results reflect available stock at the moment of the call and are not guaranteed\n * to remain available by the time an order is placed.\n */\n stockCheck(params: StockCheckParams): Promise<StockCheckResponse> {\n return this.request<StockCheckResponse>('/api/products/stock-check', params)\n }\n\n stockSnapshot(params: StockSnapshotParams): Promise<StockSnapshotResponse> {\n return this.request<StockSnapshotResponse>(\n stockSnapshotQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n listingGroups(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.request<ProductListingGroupsResponse>(\n listingGroupsQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n listingGroupsCatalog(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.request<ProductListingGroupsResponse>(\n listingGroupsCatalogQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n /**\n * Fetch full product detail by slug or id.\n * Returns a discriminated result so storefronts can distinguish missing,\n * unpublished, and feature-disabled products.\n *\n * Only product-detail 404 responses carrying one of those allowlisted reasons\n * are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus\n * permission/auth errors such as tenant mismatch, continue to throw typed SDK\n * errors instead of being collapsed into a storefront absence result.\n */\n async detail(params: ProductDetailParams): Promise<ProductDetailResult> {\n try {\n const product = await this.request<ProductDetail>(\n productDetailQuery(params),\n undefined,\n { method: 'GET' },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n }\n\n async detailCatalog(\n params: ProductDetailParams,\n ): Promise<ProductDetailCatalogResult> {\n try {\n const product = await this.request<ProductDetailCatalog>(\n productDetailCatalogQuery(params),\n undefined,\n { method: 'GET' },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n }\n\n /**\n * Atomically create or update a product together with its options,\n * option-values, and variants in a single transaction. Mirrors Shopify's\n * `productSet` shape and is the canonical write path for the MCP\n * `product-upsert` tool.\n */\n upsert(params: ProductUpsertParams): Promise<ProductUpsertResponse> {\n return this.request<ProductUpsertResponse>(\n '/api/products/upsert',\n normalizeProductUpsertParams(params),\n )\n }\n}\n","import type {\n Order,\n Transaction,\n Fulfillment,\n Return,\n} from '../../payload-types'\nimport { BaseApi, type RequestOptions, type ServerApiOptions } from './base-api'\n\nexport type OrderApiOptions = ServerApiOptions\n\n/** Header-only; never sent in the JSON body. */\nexport type WithIdempotencyKey<T> = T & {\n /**\n * Client-generated key for safe retries. Sent as `X-Idempotency-Key` when the\n * server endpoint supports HTTP idempotency.\n */\n idempotencyKey?: string\n}\n\nexport function idempotencyRequestOptions(\n idempotencyKey?: string,\n): RequestOptions | undefined {\n return idempotencyKey\n ? { headers: { 'X-Idempotency-Key': idempotencyKey } }\n : undefined\n}\n\nexport function splitIdempotencyKey<T extends { idempotencyKey?: string }>(\n params: T,\n): { body: Omit<T, 'idempotencyKey'>; idempotencyKey?: string } {\n const { idempotencyKey, ...body } = params\n return { body, idempotencyKey }\n}\n\nexport type CustomerSnapshot = {\n name?: string\n email: string\n phone?: string\n}\n\nexport type ReturnReason =\n | 'change_of_mind'\n | 'defective'\n | 'wrong_delivery'\n | 'damaged'\n | 'other'\n\nexport type ReturnItem = {\n orderItem: string\n quantity: number\n}\n\ntype OrderCreateEntityID = string | number\n\nexport type CreateOrderItem = {\n product: OrderCreateEntityID\n variant: OrderCreateEntityID\n option: OrderCreateEntityID\n quantity: number\n /**\n * Compatibility input: the create-order endpoint accepts this, but the server\n * derives authoritative line pricing from the product variant.\n */\n unitPrice?: number\n /**\n * Compatibility input: the create-order endpoint accepts this, but the server\n * derives authoritative line totals from the product variant.\n */\n totalPrice?: number\n}\n\nexport type CreateOrderParams = WithIdempotencyKey<{\n orderNumber: string\n customer?: string\n customerSnapshot: CustomerSnapshot\n shippingAddress: Order['shippingAddress']\n orderItems: CreateOrderItem[]\n totalAmount: number\n shippingAmount?: number\n pgPaymentId?: string\n discountCode?: string\n}>\n\nexport type UpdateOrderParams = {\n orderNumber: string\n status: Order['status']\n}\n\nexport type TransactionStatus = 'pending' | 'paid' | 'failed' | 'canceled'\n\nexport type UpdateTransactionParams = {\n pgPaymentId: string\n status: TransactionStatus\n paymentMethod?: string\n receiptUrl?: string\n paymentKey?: string\n amount?: number\n}\n\nexport type ConfirmPaymentParams = WithIdempotencyKey<{\n orderNumber?: string\n pgPaymentId: string\n pgProvider: string\n pgOrderId?: string\n amount: number\n currency?: string\n paymentMethod?: string\n receiptUrl?: string\n approvedAt?: string\n providerStatus?: string\n /** Provider event id; also used as idempotency key when `idempotencyKey` is omitted. */\n providerEventId?: string\n confirmationSource?:\n | 'provider_webhook'\n | 'provider_lookup'\n | 'provider_api_confirm'\n | 'manual_server'\n metadata?: Record<string, unknown>\n}>\n\nexport type ConfirmPaymentResponse = {\n orderId: string\n transactionId: string\n status: 'paid'\n alreadyConfirmed?: boolean\n}\n\nexport type CancelReasonCode =\n | 'customer'\n | 'inventory'\n | 'fraud'\n | 'declined'\n | 'staff'\n | 'other'\n\nexport type CancelOrderStatus =\n | 'pending'\n | 'paid'\n | 'failed'\n | 'canceled'\n | 'refunded'\n | 'preparing'\n | 'shipped'\n | 'delivered'\n | 'confirmed'\n | 'return_requested'\n | 'return_processing'\n | 'returned'\n\nexport type CancelOrderReconciliationStatus = Exclude<\n CancelOrderStatus,\n 'pending' | 'failed' | 'canceled'\n>\n\ntype CancelOrderResponseBase = {\n orderId: string\n}\n\ntype CancelOrderUnpaidCommittedResponseFields = {\n refundedAmount: 0\n providerRefunded: false\n}\n\ntype CancelOrderPaidCommittedResponseFields = {\n transactionId: string\n refundedAmount: 0\n providerRefunded: false\n refundPending: true\n}\n\ntype CancelOrderLegacyProviderRefundResponseFields = {\n transactionId: string\n refundedAmount: number\n refundSeq: number\n providerRefunded: true\n}\n\ntype CancelOrderAlreadyCanceledResponseFields = {\n refundedAmount: number\n providerRefunded: false\n}\n\ntype CancelOrderAlreadyCanceledRefundPendingResponseFields = {\n transactionId: string\n refundedAmount: number\n providerRefunded: false\n refundPending: true\n}\n\nexport type CancelOrderPaidCommittedResponse = CancelOrderResponseBase &\n CancelOrderPaidCommittedResponseFields & {\n status: 'canceled'\n cancelCommitted: true\n }\n\nexport type CancelOrderUnpaidCommittedResponse = CancelOrderResponseBase &\n CancelOrderUnpaidCommittedResponseFields & {\n status: 'canceled'\n cancelCommitted: true\n }\n\nexport type CancelOrderCommittedResponse =\n | CancelOrderPaidCommittedResponse\n | CancelOrderUnpaidCommittedResponse\n\nexport type CancelOrderAlreadyCanceledResponse = CancelOrderResponseBase &\n CancelOrderAlreadyCanceledResponseFields & {\n status: 'canceled'\n cancelCommitted: false\n alreadyCanceled: true\n }\n\nexport type CancelOrderAlreadyCanceledRefundPendingResponse =\n CancelOrderResponseBase &\n CancelOrderAlreadyCanceledRefundPendingResponseFields & {\n status: 'canceled'\n cancelCommitted: false\n alreadyCanceled: true\n }\n\n/** @deprecated Inline PG cancel reconciliation; retained for legacy API consumers. */\nexport type CancelOrderReconciliationResponse = CancelOrderResponseBase &\n CancelOrderLegacyProviderRefundResponseFields & {\n status: CancelOrderReconciliationStatus\n cancelCommitted: false\n reconciliationRequired: true\n }\n\nexport type CancelOrderResponse =\n | CancelOrderCommittedResponse\n | CancelOrderAlreadyCanceledResponse\n | CancelOrderAlreadyCanceledRefundPendingResponse\n | CancelOrderReconciliationResponse\n\nexport type CancelOrderParams = {\n orderNumber: string\n reasonCode?: CancelReasonCode\n reasonDetail?: string\n idempotencyKey?: string\n}\n\nexport type ResolveCancelRefundOutcome = 'succeeded' | 'failed'\n\nexport type ResolveCancelRefundSucceededParams = {\n orderNumber: string\n idempotencyKey: string\n outcome: 'succeeded'\n refundedAmount: number\n pgProvider: string\n pgRefundId: string\n}\n\nexport type ResolveCancelRefundFailedParams = {\n orderNumber: string\n idempotencyKey: string\n outcome: 'failed'\n refundedAmount: 0\n pgProvider: string\n pgRefundId?: string\n}\n\nexport type ResolveCancelRefundParams =\n | ResolveCancelRefundSucceededParams\n | ResolveCancelRefundFailedParams\n\nexport type ResolveCancelRefundSucceededResponse = {\n orderId: string\n transactionId: string\n refundTransactionId: string\n refundedAmount: number\n refundStatus: 'succeeded'\n transactionStatus: 'refunded'\n}\n\nexport type ResolveCancelRefundFailedResponse = {\n orderId: string\n transactionId: string\n refundTransactionId: string\n refundedAmount: 0\n refundStatus: 'failed'\n transactionStatus: 'paid'\n}\n\nexport type ResolveCancelRefundResponse =\n | ResolveCancelRefundSucceededResponse\n | ResolveCancelRefundFailedResponse\n\nexport type RestockAction = 'return_to_stock' | 'discard'\n\nexport type ReturnWithRefundItem = {\n orderItem: string | number\n quantity: number\n restockAction?: RestockAction\n restockingFee?: number\n}\n\nexport type ReturnWithRefundParams = WithIdempotencyKey<{\n orderNumber: string\n reason?: ReturnReason\n reasonDetail?: string\n returnItems: ReturnWithRefundItem[]\n refundAmount: number\n returnShippingFee?: number\n pgPaymentId: string\n paymentKey?: string\n refundReceiptUrl?: string\n}>\n\nexport type CheckoutParams = WithIdempotencyKey<{\n cartId: string\n orderNumber: string\n customerSnapshot: CustomerSnapshot\n pgPaymentId?: string\n discountCode?: string\n}>\n\nexport type CreateFulfillmentParams = WithIdempotencyKey<{\n orderNumber: string\n carrier?: string\n trackingNumber?: string\n items: Array<{\n orderItem: string\n quantity: number\n }>\n}>\n\nexport type UpdateFulfillmentParams = {\n fulfillmentId: string\n status: 'packed' | 'shipped' | 'delivered' | 'failed'\n carrier?: string\n trackingNumber?: string\n}\n\nexport type BulkImportFulfillmentsParams = {\n items: Array<{\n orderNumber: string\n carrier?: string\n trackingNumber?: string\n }>\n}\n\nexport type BulkImportFulfillmentsResponse = {\n succeeded: Array<{ orderNumber: string; fulfillmentId: string }>\n failed: Array<{ orderNumber: string; error: string }>\n}\n\nexport type CreateReturnParams = WithIdempotencyKey<{\n orderNumber: string\n reason?: ReturnReason\n reasonDetail?: string\n returnItems: ReturnItem[]\n refundAmount: number\n}>\n\nexport type UpdateReturnParams = {\n returnId: string\n status: 'processing' | 'approved' | 'rejected' | 'completed'\n}\n\nexport class OrderApi extends BaseApi {\n constructor(options: OrderApiOptions) {\n super('OrderApi', options)\n }\n\n createOrder(params: CreateOrderParams): Promise<Order> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Order>(\n '/api/orders/create',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n updateOrder(params: UpdateOrderParams): Promise<Order> {\n return this.request<Order>('/api/orders/update', params)\n }\n\n updateTransaction(params: UpdateTransactionParams): Promise<Transaction> {\n return this.request<Transaction>('/api/transactions/update', params)\n }\n\n confirmPayment(\n params: ConfirmPaymentParams,\n ): Promise<ConfirmPaymentResponse> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n const headerKey = idempotencyKey ?? params.providerEventId\n return this.request<ConfirmPaymentResponse>(\n '/api/orders/confirm-payment',\n body,\n idempotencyRequestOptions(headerKey),\n )\n }\n\n cancelOrder(params: CancelOrderParams): Promise<CancelOrderResponse> {\n const { idempotencyKey } = params\n const body = {\n orderNumber: params.orderNumber,\n reasonCode: params.reasonCode,\n reasonDetail: params.reasonDetail,\n }\n return this.request<CancelOrderResponse>(\n '/api/orders/cancel',\n body,\n idempotencyKey\n ? { headers: { 'X-Idempotency-Key': idempotencyKey } }\n : undefined,\n )\n }\n\n resolveCancelRefund(\n params: ResolveCancelRefundParams,\n ): Promise<ResolveCancelRefundResponse> {\n return this.request<ResolveCancelRefundResponse>(\n '/api/orders/resolve-cancel-refund',\n {\n orderNumber: params.orderNumber,\n idempotencyKey: params.idempotencyKey,\n outcome: params.outcome,\n refundedAmount: params.refundedAmount,\n pgProvider: params.pgProvider,\n ...(params.pgRefundId ? { pgRefundId: params.pgRefundId } : {}),\n },\n idempotencyRequestOptions(params.idempotencyKey),\n )\n }\n\n checkout(params: CheckoutParams): Promise<Order> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Order>(\n '/api/orders/checkout',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n createFulfillment(params: CreateFulfillmentParams): Promise<Fulfillment> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Fulfillment>(\n '/api/orders/create-fulfillment',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n updateFulfillment(params: UpdateFulfillmentParams): Promise<Fulfillment> {\n return this.request<Fulfillment>('/api/orders/update-fulfillment', params)\n }\n\n bulkImportFulfillments(\n params: BulkImportFulfillmentsParams,\n ): Promise<BulkImportFulfillmentsResponse> {\n return this.request<BulkImportFulfillmentsResponse>(\n '/api/fulfillments/bulk-import',\n params,\n )\n }\n\n returnWithRefund(\n params: ReturnWithRefundParams,\n ): Promise<{ return: Return; transaction: Transaction | null }> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<{ return: Return; transaction: Transaction | null }>(\n '/api/returns/return-refund',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n createReturn(params: CreateReturnParams): Promise<Return> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Return>(\n '/api/returns/create',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n updateReturn(params: UpdateReturnParams): Promise<Return> {\n return this.request<Return>('/api/returns/update', params)\n }\n}\n","import { CartApi } from '../api/cart-api'\nimport { productDetailResultFromError } from '../api/product-api'\nimport { httpFetch } from '../internal/utils'\nimport {\n listingGroupsCatalogQuery,\n listingGroupsQuery,\n productDetailCatalogQuery,\n productDetailQuery,\n stockSnapshotQuery,\n} from '../internal/utils/query-string'\nimport { SDKError } from '../internal/errors'\nimport { parseApiResponse } from '../api/parse-response'\nimport type { CustomerAuth } from '../customer/customer-auth'\nimport type {\n AddItemParams,\n UpdateItemParams,\n RemoveItemParams,\n ApplyDiscountParams,\n RemoveDiscountParams,\n ClearCartParams,\n} from '../api/cart-api'\nimport type {\n StockCheckParams,\n StockCheckResponse,\n StockSnapshotParams,\n StockSnapshotResponse,\n ListingGroupsParams,\n ProductListingGroupsResponse,\n ProductDetailParams,\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailCatalogResult,\n ProductDetailResult,\n} from '../api/product-api'\nimport type { ValidateDiscountParams, ValidateDiscountResult } from '../api/discount-api'\nimport type { CalculateShippingParams, CalculateShippingResult } from '../api/shipping-api'\nimport {\n idempotencyRequestOptions,\n splitIdempotencyKey,\n type CheckoutParams,\n} from '../api/order-api'\nimport type { RequestOptions } from '../api/base-api'\nimport type { Cart, CartItem, Order } from '../../payload-types'\nimport type { PayloadFindResponse } from '../client/types'\n\nexport interface CommerceClientOptions {\n publishableKey: string\n apiUrl?: string\n customerToken: () => string | null\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n customerAuth: CustomerAuth\n}\n\nexport class CommerceClient {\n readonly product: {\n stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>\n stockSnapshot: (params: StockSnapshotParams) => Promise<StockSnapshotResponse>\n listingGroups: (params: ListingGroupsParams) => Promise<ProductListingGroupsResponse>\n listingGroupsCatalog: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsResponse>\n detail: (params: ProductDetailParams) => Promise<ProductDetailResult>\n detailCatalog: (params: ProductDetailParams) => Promise<ProductDetailCatalogResult>\n }\n\n readonly cart: {\n get: (cartId: string) => Promise<Cart>\n addItem: (params: AddItemParams) => Promise<CartItem>\n updateItem: (params: UpdateItemParams) => Promise<CartItem>\n removeItem: (params: RemoveItemParams) => Promise<{ success: boolean }>\n applyDiscount: (params: ApplyDiscountParams) => Promise<Cart>\n removeDiscount: (params: RemoveDiscountParams) => Promise<Cart>\n clear: (params: ClearCartParams) => Promise<{ success: boolean }>\n }\n\n readonly orders: {\n checkout: (params: CheckoutParams) => Promise<Order>\n listMine: (options?: {\n page?: number\n limit?: number\n status?: string\n }) => Promise<PayloadFindResponse<Order>>\n }\n\n readonly discounts: {\n validate: (params: ValidateDiscountParams) => Promise<ValidateDiscountResult>\n }\n\n readonly shipping: {\n calculate: (params: CalculateShippingParams) => Promise<CalculateShippingResult>\n }\n\n constructor(options: CommerceClientOptions) {\n const cartApi = new CartApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n\n const execute = async <T>(\n endpoint: string,\n body: unknown,\n requestOptions?: RequestOptions,\n ): Promise<T> => {\n const token = options.customerToken()\n try {\n const response = await httpFetch(endpoint, {\n method: 'POST',\n apiUrl: options.apiUrl,\n publishableKey: options.publishableKey,\n customerToken: token ?? undefined,\n ...(token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized }),\n body: JSON.stringify(body),\n ...(requestOptions?.headers && { headers: requestOptions.headers }),\n })\n options.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n options.onRequestId?.(id)\n throw err\n }\n }\n\n const executeGet = async <T>(endpoint: string): Promise<T> => {\n const token = options.customerToken()\n try {\n const response = await httpFetch(endpoint, {\n method: 'GET',\n apiUrl: options.apiUrl,\n publishableKey: options.publishableKey,\n customerToken: token ?? undefined,\n ...(token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized }),\n })\n options.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n options.onRequestId?.(id)\n throw err\n }\n }\n\n this.product = {\n stockCheck: (params) => execute<StockCheckResponse>('/api/products/stock-check', params),\n stockSnapshot: (params) =>\n executeGet<StockSnapshotResponse>(stockSnapshotQuery(params)),\n listingGroups: (params) =>\n executeGet<ProductListingGroupsResponse>(listingGroupsQuery(params)),\n listingGroupsCatalog: (params) =>\n executeGet<ProductListingGroupsResponse>(listingGroupsCatalogQuery(params)),\n detail: async (params) => {\n try {\n const product = await executeGet<ProductDetail>(productDetailQuery(params))\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n },\n detailCatalog: async (params) => {\n try {\n const product = await executeGet<ProductDetailCatalog>(\n productDetailCatalogQuery(params),\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n },\n }\n\n this.cart = {\n get: cartApi.getCart.bind(cartApi),\n addItem: cartApi.addItem.bind(cartApi),\n updateItem: cartApi.updateItem.bind(cartApi),\n removeItem: cartApi.removeItem.bind(cartApi),\n applyDiscount: cartApi.applyDiscount.bind(cartApi),\n removeDiscount: cartApi.removeDiscount.bind(cartApi),\n clear: cartApi.clearCart.bind(cartApi),\n }\n\n this.orders = {\n checkout: (params) => {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return execute<Order>(\n '/api/orders/checkout',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n },\n listMine: (params) => options.customerAuth.getMyOrders(params),\n }\n\n this.discounts = {\n validate: (params) => execute<ValidateDiscountResult>('/api/discounts/validate', params),\n }\n\n this.shipping = {\n calculate: (params) => execute<CalculateShippingResult>('/api/shipping-policies/calculate', params),\n }\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\n\nexport interface EventsClientOptions {\n publishableKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type EventsDateParam = string | Date\n\nexport interface EventsRangeParams {\n start: EventsDateParam\n end: EventsDateParam\n limit?: number\n page?: number\n calendar?: string | string[]\n calendarSlug?: string | string[]\n category?: string | string[]\n categorySlug?: string | string[]\n tag?: string | string[]\n tagSlug?: string | string[]\n}\n\nexport interface EventsTaxonomyItem {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n color?: string | null\n}\n\nexport interface EventsCalendarItem extends EventsTaxonomyItem {\n timezone?: string | null\n visibility?: string | null\n}\n\nexport interface EventsLocation {\n type?: string | null\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n onlineNote?: string | null\n}\n\nexport interface EventsOccurrenceLocation {\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n note?: string | null\n}\n\nexport interface EventsExternalSource {\n provider?: string | null\n url?: string | null\n}\n\nexport interface EventsRangeEvent {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n visibility?: string | null\n sourceType?: string | null\n registrationPolicy?: string | null\n externalRegistrationUrl?: string | null\n externalSource: EventsExternalSource | null\n location: EventsLocation | null\n calendars: EventsCalendarItem[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n}\n\nexport interface EventsRangeOccurrence {\n id: string | number\n instanceKey?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n status?: string | null\n capacity?: number\n registrationCount?: number\n waitlistCount?: number\n locationOverride: EventsOccurrenceLocation | null\n event: EventsRangeEvent\n}\n\nexport interface EventsRangeResponse {\n range: {\n start: string\n end: string\n }\n docs: EventsRangeOccurrence[]\n calendars: EventsCalendarItem[]\n events: EventsRangeEvent[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventRegistrationAttendeeInput {\n name?: string\n email?: string\n phone?: string\n}\n\nexport interface EventRegistrationAnswerInput {\n question: string\n answer?: string\n}\n\nexport interface EventRegistrationRegisterParams {\n event: string\n occurrence: string\n quantity?: number\n attendee?: EventRegistrationAttendeeInput\n answers?: EventRegistrationAnswerInput[]\n}\n\nexport interface EventRegistrationPublic {\n id?: string | number\n event?: unknown\n occurrence?: unknown\n registrationStatus?: string | null\n attendanceStatus?: string | null\n quantity?: number | null\n guestTokenExpiresAt?: string | null\n}\n\nexport interface EventGuestRegistration extends EventRegistrationPublic {\n attendee: {\n name: string | null\n email: string | null\n phone: string | null\n } | null\n attendeeEmail: string | null\n answers: Array<{ question: string; answer?: string }>\n}\n\nexport interface EventRegistrationRegisterResponse {\n registration: EventRegistrationPublic\n guestToken: string\n guestTokenExpiresAt: string\n}\n\nexport interface EventGuestRegistrationResponse {\n registration: EventGuestRegistration\n}\n\nexport interface EventGuestCancelParams {\n reason?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\nexport class EventsClient {\n private readonly publishableKey: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: EventsClientOptions) {\n const secretKey = (options as { secretKey?: string }).secretKey\n this.publishableKey = requirePublishableKeyForSecret(\n 'EventsClient',\n options.publishableKey,\n secretKey,\n )\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n getRange(params: EventsRangeParams): Promise<EventsRangeResponse> {\n return this.execute<EventsRangeResponse>(\n buildRangeEndpoint(params),\n 'GET',\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n register(\n params: EventRegistrationRegisterParams,\n ): Promise<EventRegistrationRegisterResponse> {\n return this.execute<EventRegistrationRegisterResponse>(\n '/api/event-registrations/register',\n 'POST',\n buildRegistrationRequestBody(params),\n { useCustomerAuth: true },\n )\n }\n\n getGuestRegistration(token: string): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n '/api/event-registrations/guest/lookup',\n 'POST',\n { token },\n { useCustomerAuth: false },\n )\n }\n\n cancelGuestRegistration(\n token: string,\n params: EventGuestCancelParams = {},\n ): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n '/api/event-registrations/guest/cancel',\n 'POST',\n buildGuestCancelRequestBody(token, params),\n { useCustomerAuth: false },\n )\n }\n\n private async execute<T>(\n endpoint: string,\n method: HttpMethod,\n body?: unknown,\n options: { useCustomerAuth?: boolean } = {},\n ): Promise<T> {\n const useCustomerAuth = options.useCustomerAuth === true\n const token = useCustomerAuth\n ? typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n : undefined\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n ...(useCustomerAuth && token ? { customerToken: token } : {}),\n ...(useCustomerAuth &&\n token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\nfunction buildRegistrationRequestBody(\n params: EventRegistrationRegisterParams,\n): EventRegistrationRegisterParams {\n return {\n event: params.event,\n occurrence: params.occurrence,\n ...(params.quantity !== undefined && { quantity: params.quantity }),\n ...(params.attendee !== undefined && { attendee: params.attendee }),\n ...(params.answers !== undefined && { answers: params.answers }),\n }\n}\n\nfunction buildGuestCancelRequestBody(\n token: string,\n params: EventGuestCancelParams,\n): { token: string; reason?: string } {\n return {\n token,\n ...(params.reason !== undefined && { reason: params.reason }),\n }\n}\n\nfunction buildRangeEndpoint(params: EventsRangeParams): string {\n const urlParams = new URLSearchParams()\n urlParams.set('start', formatDateParam(params.start))\n urlParams.set('end', formatDateParam(params.end))\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n appendValues(urlParams, 'calendar', params.calendar)\n appendValues(urlParams, 'calendarSlug', params.calendarSlug)\n appendValues(urlParams, 'category', params.category)\n appendValues(urlParams, 'categorySlug', params.categorySlug)\n appendValues(urlParams, 'tag', params.tag)\n appendValues(urlParams, 'tagSlug', params.tagSlug)\n return `/api/event-occurrences/range?${urlParams.toString()}`\n}\n\nfunction formatDateParam(value: EventsDateParam): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nfunction appendValues(\n params: URLSearchParams,\n key: string,\n value: string | string[] | undefined,\n): void {\n if (value === undefined) return\n const values = Array.isArray(value) ? value : [value]\n for (const entry of values) {\n if (entry) params.append(key, entry)\n }\n}\n","import { ReadOnlyCollectionClient } from '../collection/collection-client'\nimport { CommunityClient } from '../community/community-client'\nimport { CustomerNamespace } from '../customer/customer-namespace'\nimport { CommerceClient } from '../commerce/commerce-client'\nimport { EventsClient } from '../events/events-client'\nimport { createConfigError } from '../internal/errors'\nimport {\n type ClientConfig,\n type ClientState,\n type ClientMetadata,\n} from './types'\n\nexport default class Client {\n commerce: CommerceClient\n community: CommunityClient\n events: EventsClient\n customer: CustomerNamespace\n collections: ReadOnlyCollectionClient\n lastRequestId: string | null = null\n\n protected state: ClientState\n protected config: ClientConfig\n\n constructor(options: ClientConfig) {\n const publishableKey = options.publishableKey\n if (!publishableKey) {\n throw createConfigError('publishableKey is required.')\n }\n\n this.config = { ...options, publishableKey }\n\n const metadata: ClientMetadata = {\n timestamp: Date.now(),\n userAgent:\n typeof window !== 'undefined' ? window.navigator?.userAgent : 'Node.js',\n }\n\n this.state = { metadata }\n\n this.customer = new CustomerNamespace(\n this.config.publishableKey,\n options.customer,\n this.config.apiUrl,\n )\n\n const onUnauthorized = async (): Promise<string | null> => {\n try {\n const result = await this.customer.auth.refreshToken()\n return result.token ?? null\n } catch {\n return null\n }\n }\n\n const onRequestId = (id: string | null) => {\n this.lastRequestId = id\n }\n\n this.commerce = new CommerceClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n customerAuth: this.customer.auth,\n })\n\n this.community = new CommunityClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.events = new EventsClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.collections = new ReadOnlyCollectionClient(\n this.config.publishableKey,\n undefined,\n () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n this.config.apiUrl,\n )\n }\n\n getState(): ClientState {\n return { ...this.state }\n }\n\n getConfig(): ClientConfig {\n return { ...this.config }\n }\n}\n\n/**\n * Create an SDK client. Works in both browser and server environments.\n * Read-only collection queries + customer auth (cart, login, profile).\n * Use the server subpath when you need full CRUD with server credentials.\n */\nexport function createClient(options: ClientConfig): Client {\n return new Client(options)\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\n\nexport type DiscountApiOptions = ServerApiOptions\n\nexport type ValidateDiscountParams = {\n code: string\n orderAmount: number\n}\n\nexport type ValidateDiscountResult = {\n valid: boolean\n code: string\n type?: 'percentage' | 'fixed_amount' | 'free_shipping' | 'tiered'\n discountAmount: number\n freeShipping?: boolean\n reason?: string\n}\n\nexport class DiscountApi extends BaseApi {\n constructor(options: DiscountApiOptions) {\n super('DiscountApi', options)\n }\n\n validate(params: ValidateDiscountParams): Promise<ValidateDiscountResult> {\n return this.request<ValidateDiscountResult>('/api/discounts/validate', params)\n }\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\n\nexport type ShippingApiOptions = ServerApiOptions\n\nexport type CalculateShippingParams = {\n shippingPolicyId?: string\n orderAmount: number\n postalCode?: string\n}\n\nexport type CalculateShippingResult = {\n shippingAmount: number\n baseShippingAmount: number\n extraShippingAmount: number\n freeShipping: boolean\n freeShippingMinAmount: number | null\n isJeju: boolean\n isRemoteIsland: boolean\n}\n\nexport class ShippingApi extends BaseApi {\n constructor(options: ShippingApiOptions) {\n super('ShippingApi', options)\n }\n\n calculate(params: CalculateShippingParams): Promise<CalculateShippingResult> {\n return this.request<CalculateShippingResult>('/api/shipping-policies/calculate', params)\n }\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailVariant,\n} from '../api/product-api'\nimport type { StockSnapshotResponse } from '../api/product-api'\n\nexport type ProductDetailStockMergeStatus = 'complete' | 'partial'\n\nexport interface MergedProductDetailResult {\n stockMergeStatus: ProductDetailStockMergeStatus\n product: ProductDetail\n}\n\nexport function mergeProductDetailWithStock(\n catalog: ProductDetailCatalog,\n snapshot: StockSnapshotResponse,\n): MergedProductDetailResult {\n const snapshotByVariantId = new Map(\n snapshot.snapshots.map((item) => [item.variantId, item]),\n )\n\n let missingSnapshotCount = 0\n const variants: ProductDetailVariant[] = catalog.variants.map((variant) => {\n const snap = snapshotByVariantId.get(String(variant.id))\n if (!snap) {\n missingSnapshotCount += 1\n return { ...variant, stock: 0, reservedStock: 0 }\n }\n\n return {\n ...variant,\n stock: snap.isUnlimited ? 0 : snap.availableStock,\n reservedStock: 0,\n }\n })\n\n const trackedVariants = variants.filter((variant) => !variant.isUnlimited)\n const totalInventory =\n trackedVariants.length === 0\n ? null\n : trackedVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0)),\n 0,\n )\n\n const { liveStockRequired: _liveStockRequired, ...listingBase } = catalog.listing\n const availableForSale = snapshot.snapshots.some(\n (item) => item.status === 'available' && item.availableForSale,\n )\n\n return {\n stockMergeStatus: missingSnapshotCount === 0 ? 'complete' : 'partial',\n product: {\n ...catalog,\n product: { ...catalog.product, totalInventory },\n variants,\n listing: { ...listingBase, availableForSale },\n },\n }\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Semantic event type for v1 commerce notification webhooks. */\nexport const COMMERCE_NOTIFICATION_EVENT_TYPE = 'commerce.notification' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange = WebhookOrderChange | WebhookCommerceNotificationChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n typeof obj.operation === 'string' &&\n obj.operation.length > 0 &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nexport const COMMERCE_NOTIFICATION_OPERATION = 'notification' as const\n\nexport const COMMERCE_NOTIFICATION_EVENTS = [\n 'orderPaid',\n 'orderCanceled',\n 'fulfillmentShipped',\n 'orderDelivered',\n 'returnRequested',\n 'returnCompleted',\n] as const\n\nexport type CommerceNotificationEventName =\n (typeof COMMERCE_NOTIFICATION_EVENTS)[number]\n\nexport type CommerceNotificationSourceCollection =\n | 'orders'\n | 'fulfillments'\n | 'returns'\n\nexport type CommerceNotificationSource = {\n collection: CommerceNotificationSourceCollection\n id: string | number\n}\n\nexport type CommerceNotificationData = {\n source?: CommerceNotificationSource\n orderId?: string | number\n orderNumber?: string\n status?: string\n totalAmount?: number\n currency?: string\n fulfillmentId?: string | number\n fulfillmentStatus?: string\n shippedAt?: string\n returnId?: string | number\n returnStatus?: string\n refundAmount?: number\n completedAt?: string\n}\n\nexport type CommerceNotification = {\n event: CommerceNotificationEventName\n intentId: string\n dedupeKey: string\n orderId?: string\n fulfillmentId?: string\n returnId?: string\n}\n\nexport type WebhookCommerceNotificationChange = {\n type: 'notification'\n source: 'commerce-notifications'\n event: CommerceNotificationEventName\n sourceCollection: CommerceNotificationSourceCollection\n sourceId: string | number\n}\n\n/** Webhook event emitted for v1 commerce notification deliveries. */\nexport type CommerceNotificationWebhookEvent = WebhookEvent<\n CommerceNotificationSourceCollection,\n CommerceNotificationData\n> & {\n operation: typeof COMMERCE_NOTIFICATION_OPERATION\n eventType: typeof COMMERCE_NOTIFICATION_EVENT_TYPE\n change?: WebhookCommerceNotificationChange\n notification: CommerceNotification\n}\n\nexport type CommerceEmailChannel = 'webhook' | 'provider'\n\nexport type CommerceEmailEventConfig = {\n enabled: boolean\n channel: CommerceEmailChannel\n template?: string\n}\n\nexport type CommerceEmailConfig = {\n version: 1\n commerceNotifications: Partial<\n Record<CommerceNotificationEventName, CommerceEmailEventConfig>\n >\n}\n\nexport type CommerceEmailHandlerContext = {\n event: CommerceNotificationWebhookEvent\n idempotencyKey: string\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport type CommerceEmailEventHandlers = Partial<\n Record<\n CommerceNotificationEventName,\n (context: CommerceEmailHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\nfunction isCommerceNotificationEventName(\n value: unknown,\n): value is CommerceNotificationEventName {\n return (\n typeof value === 'string' &&\n (COMMERCE_NOTIFICATION_EVENTS as readonly string[]).includes(value)\n )\n}\n\nfunction isCommerceNotificationSourceCollection(\n value: unknown,\n): value is CommerceNotificationSourceCollection {\n return value === 'orders' || value === 'fulfillments' || value === 'returns'\n}\n\nfunction isCommerceNotificationData(\n value: unknown,\n): value is CommerceNotificationData {\n if (!isRecord(value)) return false\n if (\n value.source !== undefined &&\n (!isRecord(value.source) ||\n !isCommerceNotificationSourceCollection(value.source.collection) ||\n !isStringOrNumber(value.source.id))\n ) {\n return false\n }\n\n return (\n (value.orderId === undefined || isStringOrNumber(value.orderId)) &&\n (value.orderNumber === undefined || typeof value.orderNumber === 'string') &&\n (value.status === undefined || typeof value.status === 'string') &&\n (value.totalAmount === undefined || typeof value.totalAmount === 'number') &&\n (value.currency === undefined || typeof value.currency === 'string') &&\n (value.fulfillmentId === undefined ||\n isStringOrNumber(value.fulfillmentId)) &&\n (value.fulfillmentStatus === undefined ||\n typeof value.fulfillmentStatus === 'string') &&\n (value.shippedAt === undefined || typeof value.shippedAt === 'string') &&\n (value.returnId === undefined || isStringOrNumber(value.returnId)) &&\n (value.returnStatus === undefined ||\n typeof value.returnStatus === 'string') &&\n (value.refundAmount === undefined ||\n typeof value.refundAmount === 'number') &&\n (value.completedAt === undefined || typeof value.completedAt === 'string')\n )\n}\n\nfunction isCommerceNotification(\n value: unknown,\n): value is CommerceNotification {\n if (!isRecord(value)) return false\n return (\n isCommerceNotificationEventName(value.event) &&\n typeof value.intentId === 'string' &&\n value.intentId.length > 0 &&\n typeof value.dedupeKey === 'string' &&\n value.dedupeKey.length > 0 &&\n (value.orderId === undefined || typeof value.orderId === 'string') &&\n (value.fulfillmentId === undefined ||\n typeof value.fulfillmentId === 'string') &&\n (value.returnId === undefined || typeof value.returnId === 'string')\n )\n}\n\nfunction isWebhookCommerceNotificationChange(\n value: unknown,\n): value is WebhookCommerceNotificationChange {\n if (!isRecord(value)) return false\n return (\n value.type === 'notification' &&\n value.source === 'commerce-notifications' &&\n isCommerceNotificationEventName(value.event) &&\n isCommerceNotificationSourceCollection(value.sourceCollection) &&\n isStringOrNumber(value.sourceId)\n )\n}\n\nfunction matchesOptionalId(\n actual: string | number | undefined,\n expected: string | number | undefined,\n): boolean {\n return actual === undefined || expected === undefined || actual === expected\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * Returns true for semantic commerce notification webhooks.\n *\n * Use `notification.intentId` and `notification.dedupeKey` for semantic\n * idempotency. `deliveryId`, when present, identifies a delivery attempt for\n * observability and is not the semantic notification identity.\n */\nexport function isCommerceNotificationWebhookEvent(\n event: unknown,\n): event is CommerceNotificationWebhookEvent {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== COMMERCE_NOTIFICATION_OPERATION ||\n event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE ||\n !isCommerceNotificationData(event.data) ||\n !isCommerceNotification((event as { notification?: unknown }).notification)\n ) {\n return false\n }\n\n const notification = (event as unknown as CommerceNotificationWebhookEvent)\n .notification\n const data = event.data\n const change = event.change\n const sourceCollection = data.source?.collection ?? event.collection\n const sourceId = data.source?.id\n\n if (!isCommerceNotificationSourceCollection(sourceCollection)) return false\n if (data.source !== undefined && event.collection !== data.source.collection) {\n return false\n }\n\n if (change !== undefined) {\n if (!isWebhookCommerceNotificationChange(change)) return false\n if (change.sourceCollection !== sourceCollection) return false\n if (change.event !== notification.event) return false\n if (!matchesOptionalId(change.sourceId, sourceId)) return false\n }\n const changeSourceId = isWebhookCommerceNotificationChange(change)\n ? change.sourceId\n : undefined\n\n if (\n notification.event === 'orderPaid' ||\n notification.event === 'orderCanceled' ||\n notification.event === 'orderDelivered'\n ) {\n return (\n sourceCollection === 'orders' &&\n typeof notification.orderId === 'string' &&\n notification.orderId.length > 0 &&\n matchesOptionalId(data.orderId, sourceId) &&\n matchesOptionalId(notification.orderId, sourceId) &&\n matchesOptionalId(data.orderId, notification.orderId) &&\n matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId)\n )\n }\n\n if (notification.event === 'fulfillmentShipped') {\n return (\n sourceCollection === 'fulfillments' &&\n matchesOptionalId(data.fulfillmentId, sourceId) &&\n typeof notification.fulfillmentId === 'string' &&\n notification.fulfillmentId.length > 0 &&\n matchesOptionalId(notification.fulfillmentId, sourceId) &&\n matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) &&\n matchesOptionalId(changeSourceId, notification.fulfillmentId)\n )\n }\n\n if (\n notification.event === 'returnRequested' ||\n notification.event === 'returnCompleted'\n ) {\n return (\n sourceCollection === 'returns' &&\n matchesOptionalId(data.returnId, sourceId) &&\n typeof notification.returnId === 'string' &&\n notification.returnId.length > 0 &&\n matchesOptionalId(notification.returnId, sourceId) &&\n matchesOptionalId(data.returnId, notification.returnId) &&\n matchesOptionalId(changeSourceId, notification.returnId)\n )\n }\n\n return false\n}\n\nexport function getCommerceNotificationIdempotencyKey(\n event: Pick<CommerceNotificationWebhookEvent, 'notification'>,\n): string {\n return `${event.notification.intentId}:${event.notification.dedupeKey}`\n}\n\nexport function defineCommerceEmailConfig<TConfig extends CommerceEmailConfig>(\n config: TConfig,\n): TConfig {\n return config\n}\n\nexport function createCommerceEmailWebhookHandler(\n handlers: CommerceEmailEventHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (!isCommerceNotificationWebhookEvent(event)) {\n await handlers.unhandled?.(event)\n return\n }\n\n const handler = handlers[event.notification.event]\n if (!handler) {\n await handlers.unhandled?.(event)\n return\n }\n\n await handler({\n event,\n idempotencyKey: getCommerceNotificationIdempotencyKey(event),\n })\n }\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n | typeof COMMERCE_NOTIFICATION_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n // Validate and convert hex signature to Uint8Array\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n // crypto.subtle.verify performs constant-time comparison internally\n return crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n encoder.encode(`${timestamp}.${deliveryId}.${payload}`),\n )\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const toleranceSeconds = options.toleranceSeconds ?? 300\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(\n rawBody,\n options.secret,\n signature,\n timestamp,\n deliveryId,\n ))\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n","import type { Config } from '../../payload-types'\n\n/**\n * Collection type derived from Payload Config.\n * This ensures type safety and automatic synchronization with payload-types.ts\n */\nexport type Collection = keyof Config['collections']\n\n/**\n * Internal collections that should not be exposed via SDK.\n * Includes Payload system collections and admin-only collections.\n */\nexport const INTERNAL_COLLECTIONS = [\n 'users',\n 'payload-kv',\n 'payload-locked-documents',\n 'payload-preferences',\n 'payload-migrations',\n 'payload-folders',\n 'field-configs',\n 'system-media',\n 'track-assets',\n 'audiences',\n 'email-logs',\n 'api-usage',\n 'tenant-analytics-daily',\n 'tenant-web-analytics-config',\n 'analytics-event-schemas',\n 'subscriptions',\n 'billing-history',\n 'inventory-reservations',\n 'commerce-notification-intents',\n 'product-collection-items',\n 'order-status-logs',\n 'api-keys',\n 'personal-access-tokens',\n 'tenant-entitlements',\n 'tenant-purge-jobs',\n 'direct-upload-sessions',\n 'webhook-events',\n 'webhook-deliveries',\n 'audit-logs',\n 'plans',\n 'webhooks',\n 'event-registrations',\n] as const\n\nexport type InternalCollection = (typeof INTERNAL_COLLECTIONS)[number]\n\n/**\n * Array of all public collection names for runtime use (e.g., Zod enum validation).\n * This is the single source of truth for which collections are publicly accessible via SDK.\n */\nexport const COLLECTIONS = [\n 'tenants',\n 'tenant-metadata',\n 'tenant-logos',\n 'products',\n 'product-variants',\n 'product-options',\n 'product-option-values',\n 'product-categories',\n 'product-tags',\n 'product-collections',\n 'brands',\n 'brand-logos',\n 'orders',\n 'order-items',\n 'returns',\n 'return-items',\n 'fulfillments',\n 'fulfillment-items',\n 'transactions',\n 'customers',\n 'customer-profiles',\n 'customer-addresses',\n 'carts',\n 'cart-items',\n 'discounts',\n 'shipping-policies',\n 'shipping-zones',\n 'documents',\n 'document-categories',\n 'document-types',\n 'articles',\n 'article-authors',\n 'article-categories',\n 'article-tags',\n 'playlists',\n 'playlist-categories',\n 'playlist-tags',\n 'tracks',\n 'track-categories',\n 'track-tags',\n 'galleries',\n 'gallery-categories',\n 'gallery-tags',\n 'gallery-items',\n 'links',\n 'link-categories',\n 'link-tags',\n 'canvases',\n 'canvas-node-types',\n 'canvas-edge-types',\n 'canvas-categories',\n 'canvas-tags',\n 'canvas-nodes',\n 'canvas-edges',\n 'videos',\n 'video-categories',\n 'video-tags',\n 'live-streams',\n 'images',\n 'forms',\n 'form-submissions',\n // Community\n 'posts',\n 'comments',\n 'reactions',\n 'reaction-types',\n 'bookmarks',\n 'post-categories',\n 'post-tags',\n 'customer-profile-lists',\n // Events\n 'event-calendars',\n 'events',\n 'event-categories',\n 'event-occurrences',\n 'event-tags',\n] as const\n\n/**\n * Server-auth collection names for runtime use. These collections are safe for\n * secret-key/PAT SDK and MCP server tools, but must not appear in browser or\n * publishable-key collection discovery.\n */\nexport const SERVER_ONLY_COLLECTIONS = [\n 'customer-groups',\n 'reports',\n 'community-bans',\n] as const\n\n/**\n * Public collections available for SDK access.\n * Derived from the COLLECTIONS array (single source of truth).\n */\nexport type PublicCollection = (typeof COLLECTIONS)[number]\n\nexport type ServerOnlyCollection = (typeof SERVER_ONLY_COLLECTIONS)[number]\n\nexport const SERVER_COLLECTIONS = [\n ...COLLECTIONS,\n ...SERVER_ONLY_COLLECTIONS,\n] as const\n\nexport type ServerCollection = (typeof SERVER_COLLECTIONS)[number]\n\n/**\n * Compile-time classification checks: every Config collection must be public,\n * server-only, or internal, and each collection must appear in exactly one\n * classification bucket.\n */\ntype _Uncategorized = Exclude<\n Collection,\n PublicCollection | ServerOnlyCollection | InternalCollection\n>\nexport const _assertAllCategorized: [_Uncategorized] extends [never]\n ? true\n : _Uncategorized = true\n\ntype _Overcategorized =\n | Extract<PublicCollection, ServerOnlyCollection | InternalCollection>\n | Extract<ServerOnlyCollection, InternalCollection>\nexport const _assertNoDuplicateCategorization: [_Overcategorized] extends [\n never,\n]\n ? true\n : _Overcategorized = true\n","/**\n * Fetch-based SSE connection manager for real-time collection change events.\n * Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).\n */\n\nexport interface RealtimeEvent {\n collection: string\n operation: string\n id: string | null\n timestamp: string\n}\n\nexport type RealtimeListener = (event: RealtimeEvent) => void\n\nconst INITIAL_RECONNECT_DELAY = 1_000\nconst MAX_RECONNECT_DELAY = 30_000\nconst RECONNECT_BACKOFF_FACTOR = 2\nconst MAX_NO_TOKEN_RETRIES = 5\n\nexport class RealtimeConnection {\n private abortController: AbortController | null = null\n private reconnectAttempt = 0\n private noTokenAttempts = 0\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private listeners = new Set<RealtimeListener>()\n private _connected = false\n\n constructor(\n private baseUrl: string,\n private publishableKey: string,\n private getToken: () => string | null,\n private collections?: string[],\n ) {}\n\n get connected(): boolean {\n return this._connected\n }\n\n addListener(fn: RealtimeListener): () => void {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n connect(): void {\n if (this.abortController) return // Already connecting/connected\n\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }\n\n disconnect(): void {\n this._connected = false\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n this.reconnectAttempt = 0\n this.noTokenAttempts = 0\n }\n\n private async startStream(signal: AbortSignal): Promise<void> {\n const token = this.getToken()\n if (!token) {\n this.noTokenAttempts++\n if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {\n // Stop reconnecting — no token available after multiple attempts\n this._connected = false\n this.abortController = null\n return\n }\n this.scheduleReconnect()\n return\n }\n this.noTokenAttempts = 0\n\n const params = this.collections?.length\n ? `?collections=${this.collections.join(',')}`\n : ''\n const url = `${this.baseUrl}/api/events/stream${params}`\n\n try {\n const response = await fetch(url, {\n headers: {\n 'X-Publishable-Key': this.publishableKey,\n Authorization: `Bearer ${token}`,\n },\n signal,\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n // Token expired — try reconnecting (will get fresh token)\n this.scheduleReconnect()\n return\n }\n throw new Error(`SSE connection failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body')\n }\n\n this._connected = true\n this.reconnectAttempt = 0\n\n await this.readStream(response.body, signal)\n } catch {\n if (signal.aborted) return // Intentional disconnect\n this._connected = false\n this.scheduleReconnect()\n }\n }\n\n private async readStream(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent = ''\n let currentData = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done || signal.aborted) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? '' // Keep incomplete last line in buffer\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7)\n } else if (line.startsWith('data: ')) {\n currentData += (currentData ? '\\n' : '') + line.slice(6)\n } else if (line === '') {\n // Empty line = end of event\n if (currentEvent === 'collection:change' && currentData) {\n try {\n const event: RealtimeEvent = JSON.parse(currentData)\n for (const listener of this.listeners) {\n try {\n listener(event)\n } catch {\n // Listener error — ignore\n }\n }\n } catch {\n // Malformed JSON — ignore\n }\n }\n currentEvent = ''\n currentData = ''\n }\n // Ignore comment lines (: heartbeat)\n }\n }\n } catch {\n // Stream read error\n } finally {\n reader.releaseLock()\n this._connected = false\n if (!signal.aborted) {\n this.scheduleReconnect()\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return\n\n const delay = Math.min(\n INITIAL_RECONNECT_DELAY *\n Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),\n MAX_RECONNECT_DELAY,\n )\n this.reconnectAttempt++\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }, delay)\n }\n}\n","export type NormalizedOptionSwatch<TMedia = unknown> = {\n type: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: string | number | null\n /** Inlined swatch media when the API populated mediaItemId before pool indexing. */\n inlineMedia?: TMedia | null\n}\n\nexport function selectedSwatchMediaItemId(\n swatch: NormalizedOptionSwatch | null | undefined,\n): string | null {\n if (!swatch || swatch.type !== 'media') return null\n const id = swatch.mediaItemId\n if (id == null || id === '') return null\n return String(id)\n}\n\nexport type ProductSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDisplayMediaSource =\n | 'listing_primary'\n | 'product_primary'\n | 'product_pool'\n | 'none'\n\n/** @deprecated Use {@link ProductSelectionMediaSource} or {@link ProductDisplayMediaSource}. */\nexport type ProductMediaResolutionSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n\nexport type ProductSelectionVariant<TMedia> = {\n id?: string | number | null\n images?: Array<TMedia | string | number | null | undefined> | null\n}\n\nexport type ProductSelectionOptionValue = {\n id?: string | number | null\n swatch?: NormalizedOptionSwatch<unknown> | null\n}\n\nexport type ProductSelectionMediaPointer =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ResolveProductSelectionMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n selectedVariant?: ProductSelectionVariant<TMedia> | null\n matchingVariants?: Array<\n ProductSelectionVariant<TMedia> | null | undefined\n > | null\n selectedOptionValues?: Array<\n ProductSelectionOptionValue | null | undefined\n > | null\n}\n\nexport type ResolveProductSelectionMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductSelectionMediaSource\n}\n\nexport type ResolveProductDisplayMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n listingPrimaryImage?: ProductSelectionMediaPointer\n}\n\nexport type ResolveProductDisplayMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductDisplayMediaSource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction getMediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction toPointerId(\n value: ProductSelectionMediaPointer | undefined,\n): string | null {\n return getMediaId(value)\n}\n\nfunction mediaArray<TMedia>(value: TMedia[] | null | undefined): TMedia[] {\n if (!Array.isArray(value)) return []\n return value.filter((entry): entry is TMedia => entry != null)\n}\n\nfunction uniqueWithPrimaryFirst<TMedia>(\n primary: TMedia | null,\n items: TMedia[],\n): TMedia[] {\n const unique = new Map<string, TMedia>()\n\n for (const item of items) {\n const id = getMediaId(item)\n const key = id ?? `inline:${unique.size}`\n if (!unique.has(key)) unique.set(key, item)\n }\n\n if (primary) {\n const primaryId = getMediaId(primary)\n const prefixed = new Map<string, TMedia>()\n const primaryKey = primaryId ?? 'inline:primary'\n prefixed.set(primaryKey, primary)\n\n for (const [key, value] of unique.entries()) {\n if (!prefixed.has(key)) prefixed.set(key, value)\n }\n\n return Array.from(prefixed.values())\n }\n\n return Array.from(unique.values())\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n\n for (const item of pool) {\n const id = getMediaId(item)\n if (id) poolById.set(id, item)\n }\n\n return poolById\n}\n\nfunction resolveVariantImageItems<TMedia>(\n variant: ProductSelectionVariant<TMedia> | null | undefined,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n if (!variant || !Array.isArray(variant.images)) return []\n\n const resolved: TMedia[] = []\n\n for (const entry of variant.images) {\n if (entry == null) continue\n\n if (typeof entry === 'string' || typeof entry === 'number') {\n const pooled = poolById.get(String(entry))\n if (pooled) resolved.push(pooled)\n continue\n }\n\n const mediaId = getMediaId(entry)\n if (mediaId) {\n const pooled = poolById.get(mediaId)\n if (pooled) {\n resolved.push(pooled)\n }\n continue\n }\n }\n\n return resolved\n}\n\nfunction resolveOptionSwatchPrimary<TMedia>(\n selectedOptionValues:\n | Array<ProductSelectionOptionValue | null | undefined>\n | null\n | undefined,\n poolById: Map<string, TMedia>,\n): TMedia | null {\n if (!selectedOptionValues?.length) return null\n\n for (const optionValue of selectedOptionValues) {\n const swatch = optionValue?.swatch\n const swatchPointer = selectedSwatchMediaItemId(swatch)\n if (swatchPointer) {\n const pooled = poolById.get(swatchPointer)\n if (pooled) return pooled\n }\n\n const inline = swatch?.inlineMedia\n if (inline != null && typeof inline === 'object') {\n return inline as TMedia\n }\n }\n\n return null\n}\n\nexport function resolveProductSelectionMedia<TMedia>(\n input: ResolveProductSelectionMediaInput<TMedia>,\n): ResolveProductSelectionMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const selectedVariantImages = resolveVariantImageItems(\n input.selectedVariant,\n poolById,\n )\n\n if (selectedVariantImages.length > 0) {\n const primaryImage = selectedVariantImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, selectedVariantImages),\n source: 'variant_media_selected',\n }\n }\n\n if (\n input.selectedVariant == null &&\n (input.matchingVariants?.length ?? 0) > 0\n ) {\n const mergedMatchingImages: TMedia[] = []\n\n for (const matchingVariant of input.matchingVariants ?? []) {\n mergedMatchingImages.push(\n ...resolveVariantImageItems(matchingVariant, poolById),\n )\n }\n\n if (mergedMatchingImages.length > 0) {\n const primaryImage = mergedMatchingImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, mergedMatchingImages),\n source: 'variant_media_matching',\n }\n }\n }\n\n const optionSwatchPrimary = resolveOptionSwatchPrimary(\n input.selectedOptionValues,\n poolById,\n )\n\n if (optionSwatchPrimary) {\n return {\n primaryImage: optionSwatchPrimary,\n images: [optionSwatchPrimary],\n source: 'option_swatch',\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport function resolveProductDisplayMedia<TMedia>(\n input: ResolveProductDisplayMediaInput<TMedia>,\n): ResolveProductDisplayMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const listingPointer = toPointerId(input.listingPrimaryImage)\n if (listingPointer) {\n const listingPrimary = poolById.get(listingPointer)\n if (listingPrimary) {\n return {\n primaryImage: listingPrimary,\n images: uniqueWithPrimaryFirst(listingPrimary, pool),\n source: 'listing_primary',\n }\n }\n }\n\n const productPrimaryPointer = getMediaId(input.productPrimaryMediaItemId)\n if (productPrimaryPointer) {\n const productPrimary = poolById.get(productPrimaryPointer)\n if (productPrimary) {\n return {\n primaryImage: productPrimary,\n images: uniqueWithPrimaryFirst(productPrimary, pool),\n source: 'product_primary',\n }\n }\n }\n\n if (pool.length > 0) {\n const productPoolPrimary = pool[0] ?? null\n\n if (productPoolPrimary) {\n return {\n primaryImage: productPoolPrimary,\n images: uniqueWithPrimaryFirst(productPoolPrimary, pool),\n source: 'product_pool',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport type ListingPrimaryImageFallbackInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n productThumbnail?: TMedia | string | number | null\n listingPrimaryImage?: TMedia | string | number | null\n resolvedPrimary?: TMedia | null\n resolvedSource?: ProductMediaResolutionSource\n}\n\nexport function resolveListingPrimaryImagePointer<TMedia>(\n input: ListingPrimaryImageFallbackInput<TMedia>,\n): string | null {\n const pool = mediaArray(input.productMediaPool)\n const resolvedPointer = getMediaId(input.resolvedPrimary)\n if (\n resolvedPointer &&\n input.resolvedSource !== 'product_pool' &&\n input.resolvedSource !== 'none'\n ) {\n return resolvedPointer\n }\n\n const poolById = buildPoolById(pool)\n const listingPointer = getMediaId(input.listingPrimaryImage)\n if (listingPointer && poolById.has(listingPointer)) {\n return listingPointer\n }\n\n const primaryPointer = toPointerId(input.productPrimaryMediaItemId)\n if (primaryPointer && poolById.has(primaryPointer)) return primaryPointer\n\n const thumbnailPointer = getMediaId(input.productThumbnail)\n if (thumbnailPointer && poolById.has(thumbnailPointer)) {\n return thumbnailPointer\n }\n\n if (pool.length > 0) {\n const firstPoolId = getMediaId(pool[0])\n if (firstPoolId) return firstPoolId\n }\n\n return null\n}\n","import type {\n ProductDetail,\n ProductDetailMedia,\n ProductDetailOptionValue,\n ProductDetailVariant,\n ProductListingGroupsItem,\n ProductOptionValueSwatch,\n} from '../core/api/product-api'\nimport { type NormalizedOptionSwatch } from './product-media'\nimport {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n resolveListingPrimaryImagePointer,\n type ProductMediaResolutionSource,\n type ProductSelectionMediaSource,\n} from './product-selection-media'\n\nfunction normalizeMatrixSwatch(\n swatch: ProductDetailOptionValue['swatch'],\n): NormalizedOptionSwatch<ProductDetailMedia> | null {\n if (!swatch) return null\n const rawMedia = swatch.mediaItemId as MediaValue\n const inlineMedia =\n rawMedia != null &&\n typeof rawMedia === 'object' &&\n 'url' in rawMedia &&\n typeof (rawMedia as { url?: unknown }).url === 'string'\n ? (rawMedia as ProductDetailMedia)\n : null\n return {\n type: swatch.type ?? null,\n color: swatch.color ?? null,\n mediaItemId: extractEntityId(rawMedia),\n inlineMedia,\n }\n}\n\ntype EntityID = string\n\ntype RelationshipValue =\n | string\n | number\n | null\n | undefined\n | { id?: string | number | null }\n\nexport type MediaValue = ProductDetailMedia | null | undefined\n\nexport type { ProductOptionValueSwatch }\n\n/** Raw Payload / REST swatch before strict public normalization. */\nexport type ProductOptionValueSwatchInput = {\n type?: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: RelationshipValue\n}\n\nexport interface ProductOptionValueShape {\n id?: string | number | null\n option?: RelationshipValue\n value?: string | null\n slug?: string | null\n swatch?: ProductOptionValueSwatch | ProductOptionValueSwatchInput | null\n _order?: string | null\n '_product-option-values_values_order'?: string | null\n}\n\nexport interface ProductOptionShape {\n id?: string | number | null\n title?: string | null\n slug?: string | null\n _order?: string | null\n '_product-options_options_order'?: string | null\n values?: {\n docs?: unknown[]\n } | null\n}\n\nexport interface ProductVariantShape {\n id?: string | number | null\n optionValues?: unknown[] | null\n price?: number | null\n compareAtPrice?: number | null\n stock?: number | null\n reservedStock?: number | null\n isUnlimited?: boolean | null\n isActive?: boolean | null\n thumbnail?: MediaValue\n images?: MediaValue[] | null\n _order?: string | null\n}\n\nexport interface ProductListingProductShape {\n id?: EntityID\n thumbnail?: MediaValue\n primaryMediaItemId?: MediaValue\n images?: MediaValue[] | null\n listing?: {\n primaryImage?: MediaValue\n } | null\n}\n\nexport type ProductOptionMatrixValue = {\n id: string\n optionId: string\n optionSlug: string\n label: string\n slug: string | null\n swatch: ProductOptionValueSwatch\n order: string\n}\n\nexport type ProductOptionMatrixOption = {\n id: string\n title: string\n slug: string\n order: string\n values: ProductOptionMatrixValue[]\n}\n\nexport type ProductOptionMatrixVariant<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n id: string\n optionValueIds: string[]\n optionValueByOptionId: Map<string, string>\n optionValueByOptionSlug: Map<string, string>\n source: TVariant\n}\n\nexport type ProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n options: ProductOptionMatrixOption[]\n optionIds: string[]\n optionSlugs: string[]\n optionById: Map<string, ProductOptionMatrixOption>\n optionBySlug: Map<string, ProductOptionMatrixOption>\n valueById: Map<string, ProductOptionMatrixValue>\n valueToOptionId: Map<string, string>\n valueToOptionSlug: Map<string, string>\n variants: ProductOptionMatrixVariant<TVariant>[]\n}\n\nexport type ProductListingProjection = {\n selectionHintVariant: EntityID | null\n primaryImage: EntityID | null\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n availableForSale: boolean\n}\n\nexport type ProductListingGroup<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n optionId: EntityID\n optionTitle: string\n optionSlug: string\n optionValueId: EntityID\n optionValueLabel: string\n optionValueSlug: string | null\n optionValueSwatch: ProductOptionValueSwatch\n variantIds: EntityID[]\n variantCount: number\n variants: TVariant[]\n listing: ProductListingProjection\n}\n\nexport type ProductListingCardPriceRange = {\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n}\n\nexport type ProductListingSwatch = {\n optionId: EntityID\n optionValueId: EntityID\n label: string\n swatch: ProductOptionValueSwatch<ProductDetailMedia>\n href: string\n availableForSale: boolean\n}\n\nexport type ProductListingCardRepresentativeVariant =\n ProductListingGroupsItem['groups'][number]['variants'][number]\n\nexport type ProductListingCard = {\n id: EntityID\n href: string\n title: string\n representativeVariant?: ProductListingCardRepresentativeVariant | null\n primaryImage: ProductDetailMedia | null\n priceRange: ProductListingCardPriceRange\n availableForSale: boolean\n swatches: ProductListingSwatch[]\n}\n\nexport type ProductSelectionByOptionValue =\n | string\n | number\n | null\n | undefined\n | {\n valueId?: string | number | null\n valueSlug?: string | null\n }\n\nexport type ProductSelectionInput = {\n variantId?: string | number | null\n byOptionSlug?: Record<string, ProductSelectionByOptionValue>\n byOptionId?: Record<string, ProductSelectionByOptionValue>\n valueIds?: Iterable<unknown>\n search?: string | URLSearchParams | URL | null\n}\n\nexport type NormalizedProductSelection = {\n byOptionSlug: Record<string, string>\n byOptionId: Record<string, string>\n valueIds: string[]\n variantId: string | null\n}\n\nexport type CompatibilityProductSelectionParamEvent = {\n optionId: string\n optionSlug: string\n valueSlug: string\n searchParam: string\n}\n\nexport type LegacyProductSelectionParamEvent =\n CompatibilityProductSelectionParamEvent\n\nexport type ProductSelectionUrlEmit = 'slug-compat' | 'canonical-id'\n\nconst DEFAULT_PRODUCT_SELECTION_URL_EMIT: ProductSelectionUrlEmit =\n 'slug-compat'\n\nfunction resolveProductSelectionUrlEmit(\n emit?: ProductSelectionUrlEmit,\n): ProductSelectionUrlEmit {\n return emit ?? DEFAULT_PRODUCT_SELECTION_URL_EMIT\n}\n\nfunction appendSlugCompatSelectionParam(\n params: URLSearchParams,\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n optionId: string,\n valueId: string,\n): boolean {\n const option = matrix.optionById.get(optionId)\n const value = matrix.valueById.get(valueId)\n if (!option?.slug || !value?.slug) return false\n\n const slugMatches = option.values.filter(\n (candidate) => candidate.slug === value.slug,\n )\n if (slugMatches.length !== 1) return false\n\n params.append(`opt.${option.slug}`, value.slug)\n return true\n}\n\nfunction appendCanonicalSelectionParam(\n params: URLSearchParams,\n optionId: string,\n valueId: string,\n): void {\n params.append(`opt.${optionId}`, valueId)\n}\n\nexport type ProductSelectionCodecOptions = {\n emit?: ProductSelectionUrlEmit\n /**\n * When true, `resolveProductSelection()` fills unselected options to reach a\n * concrete variant. Does not change codec parse/stringify behavior.\n */\n fillDefaults?: boolean\n onCompatibilityOptionIdParam?: (\n event: CompatibilityProductSelectionParamEvent,\n ) => void\n onLegacyOptionIdParam?: (event: LegacyProductSelectionParamEvent) => void\n}\n\nexport type ProductSelectionResolutionContext = {\n detail?: Pick<ProductDetail, 'images' | 'listing' | 'primaryMediaItemId'>\n images?: ProductDetail['images']\n listing?: ProductDetail['listing']\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n}\n\nexport type ProductSelectionAvailableSwatch = {\n color?: string | null\n image?: MediaValue | null\n}\n\nexport type ProductSelectionAvailableValue = {\n valueId: string\n value: string\n label: string\n slug: string\n selected: boolean\n available: boolean\n exists: boolean\n availableForSale: boolean\n isUnlimited: boolean\n availableStock: number | null\n swatch: ProductOptionValueSwatch\n}\n\nexport type ProductSelectionResolution = {\n normalizedSelection: NormalizedProductSelection\n selectedVariant: ProductDetailVariant | null\n matchingVariants: ProductDetailVariant[]\n partialVariants: ProductDetailVariant[]\n availableValuesByOptionSlug: Record<string, ProductSelectionAvailableValue[]>\n availableValuesByOptionId: Record<string, ProductSelectionAvailableValue[]>\n allOptionsSelected: boolean\n price: {\n min: number | null\n max: number | null\n compareAtMin: number | null\n compareAtMax: number | null\n isRange: boolean\n }\n media: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source?: ProductMediaResolutionSource\n }\n stock: {\n availableForSale: boolean\n isUnlimited: boolean\n stock: number | null\n reservedStock: number | null\n availableStock: number | null\n }\n}\n\nexport class ProductSelectionCodecError extends Error {\n code = 'ambiguous_product_selection_query'\n\n constructor(message: string) {\n super(message)\n this.name = 'ProductSelectionCodecError'\n }\n}\n\nfunction getRelationID(value: RelationshipValue): string | undefined {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n const id = value.id\n if (typeof id === 'string') return id\n if (typeof id === 'number') return String(id)\n }\n return undefined\n}\n\nfunction compareOrder(\n left: string | null | undefined,\n right: string | null | undefined,\n): number {\n return (left ?? '').localeCompare(right ?? '')\n}\n\nfunction isProductOptionValueDoc(\n value: unknown,\n): value is ProductOptionValueShape {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n ('value' in value || 'slug' in value)\n )\n}\n\nfunction extractEntityId(value: MediaValue): EntityID | null {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n if (typeof value.id === 'string') return value.id\n if (typeof value.id === 'number') return String(value.id)\n }\n return null\n}\n\nfunction getFirstMediaId(\n values: MediaValue[] | null | undefined,\n): EntityID | null {\n if (!Array.isArray(values)) return null\n\n for (const value of values) {\n const id = extractEntityId(value)\n if (id != null) return id\n }\n\n return null\n}\n\nfunction getVariantPrimaryImage(\n variant: ProductVariantShape | null | undefined,\n): EntityID | null {\n if (!variant) return null\n return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images)\n}\n\nfunction resolveGenericListingPrimaryImage(\n product: ProductListingProductShape | null | undefined,\n resolvedPrimary: MediaValue | null,\n resolvedSource?: ProductSelectionMediaSource,\n): EntityID | null {\n return resolveListingPrimaryImagePointer({\n productMediaPool: product?.images ?? [],\n productPrimaryMediaItemId: getRelationID(\n product?.primaryMediaItemId ?? null,\n ),\n productThumbnail: product?.thumbnail ?? null,\n listingPrimaryImage: product?.listing?.primaryImage ?? null,\n resolvedPrimary,\n resolvedSource,\n })\n}\n\nfunction getFirstAvailableVariantPrimaryImage(\n variants: ProductVariantShape[],\n): EntityID | null {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n\n for (const variant of orderedVariants) {\n if (!isVariantAvailableForSale(variant)) continue\n const image = getVariantPrimaryImage(variant)\n if (image != null) return image\n }\n\n return null\n}\n\nfunction normalizeProductOptionValueSwatch(\n swatch:\n | ProductOptionValueSwatch\n | ProductOptionValueSwatchInput\n | null\n | undefined,\n): ProductOptionValueSwatch {\n if (swatch == null) return null\n if (typeof swatch !== 'object') return null\n\n const raw = swatch as ProductOptionValueSwatchInput\n const mediaItemId = extractEntityId(raw.mediaItemId as MediaValue)\n const color =\n typeof raw.color === 'string' ? raw.color.trim() : ''\n const hasColor = color.length > 0\n\n if (raw.type === 'media' || (mediaItemId && raw.type !== 'color')) {\n if (!mediaItemId || hasColor) return null\n return {\n type: 'media',\n mediaItemId: mediaItemId as ProductDetailMedia,\n color: null,\n }\n }\n\n if (raw.type === 'color' || hasColor) {\n if (mediaItemId || !hasColor) return null\n return { type: 'color', color, mediaItemId: null }\n }\n\n return null\n}\n\nfunction normalizeOptionValue(\n value: ProductOptionValueShape,\n fallbackOptionId: string,\n fallbackOptionSlug: string,\n): ProductOptionMatrixValue {\n return {\n id: String(value.id),\n optionId: getRelationID(value.option) ?? fallbackOptionId,\n optionSlug: fallbackOptionSlug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug ?? null,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: value._order ?? value['_product-option-values_values_order'] ?? '',\n }\n}\n\nfunction normalizeVariantOptionValues<TVariant extends ProductVariantShape>(\n variant: TVariant,\n optionById: Map<string, ProductOptionMatrixOption>,\n valueToOptionId: Map<string, string>,\n optionIds: string[],\n): ProductOptionMatrixVariant<TVariant> {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of Array.isArray(variant.optionValues)\n ? variant.optionValues\n : []) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId =\n valueToOptionId.get(valueId) ??\n (isProductOptionValueDoc(rawValue)\n ? getRelationID(rawValue.option)\n : undefined)\n if (!optionId || optionValueByOptionId.has(optionId)) continue\n\n optionValueByOptionId.set(optionId, valueId)\n const optionSlug = optionById.get(optionId)?.slug\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n}\n\nexport function buildProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>({\n options,\n variants = [],\n}: {\n options: ProductOptionShape[]\n variants?: TVariant[]\n}): ProductOptionMatrix<TVariant> {\n const normalizedOptions = options\n .map((option) => {\n const valuesById = new Map<string, ProductOptionMatrixValue>()\n const optionSlug = option.slug ?? String(option.id)\n\n for (const rawValue of option.values?.docs ?? []) {\n if (!isProductOptionValueDoc(rawValue)) continue\n\n const normalizedValue = normalizeOptionValue(\n rawValue,\n String(option.id),\n optionSlug,\n )\n valuesById.set(normalizedValue.id, normalizedValue)\n }\n\n return {\n id: String(option.id),\n title: option.title ?? String(option.id),\n slug: optionSlug,\n order: option._order ?? option['_product-options_options_order'] ?? '',\n values: Array.from(valuesById.values()).sort((left, right) =>\n compareOrder(left.order, right.order),\n ),\n }\n })\n .sort((left, right) => compareOrder(left.order, right.order))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = variants.map((variant) =>\n normalizeVariantOptionValues(\n variant,\n optionById,\n valueToOptionId,\n optionIds,\n ),\n )\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nfunction matrixOrder(index: number): string {\n return String(index).padStart(6, '0')\n}\n\nexport function buildProductOptionMatrixFromDetail(\n detail: ProductDetail,\n): ProductOptionMatrix<ProductDetailVariant> {\n const normalizedOptions = detail.options.map((option, optionIndex) => ({\n id: String(option.id),\n title: option.title || String(option.id),\n slug: option.slug,\n order: matrixOrder(optionIndex),\n values: option.values.map((value, valueIndex) => ({\n id: String(value.id),\n optionId: String(option.id),\n optionSlug: option.slug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: matrixOrder(valueIndex),\n })),\n }))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = detail.variants.map((variant) => {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of variant.optionValues) {\n const optionId = String(rawValue.optionId)\n const valueId = String(rawValue.valueId)\n const optionSlug = rawValue.optionSlug\n if (!optionById.has(optionId)) continue\n if (valueToOptionId.get(valueId) !== optionId) continue\n if (optionValueByOptionId.has(optionId)) continue\n optionValueByOptionId.set(optionId, valueId)\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n })\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nexport function getSelectedValueByOptionId<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): Map<string, string> {\n const selectedByOption = new Map<string, string>()\n\n for (const rawValue of selectedValueIds) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId || selectedByOption.has(optionId)) continue\n\n selectedByOption.set(optionId, valueId)\n }\n\n return selectedByOption\n}\n\nexport function normalizeSelectedValueIds<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): string[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n\n return matrix.optionIds\n .map((optionId) => selectedByOption.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n}\n\nexport function getAvailableOptionValues<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n optionId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixValue[] {\n const option = matrix.optionById.get(optionId)\n if (!option) return []\n\n if (matrix.variants.length === 0) {\n return option.values\n }\n\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.delete(optionId)\n\n const matchingVariants = matrix.variants.filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) === selectedValueId,\n ),\n )\n\n const availableValueIds = new Set(\n matchingVariants\n .filter((variant) => variant.source.isActive !== false)\n .map((variant) => variant.optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId)),\n )\n\n return option.values.filter((value) => availableValueIds.has(value.id))\n}\n\nexport function resolveVariantForSelection<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixVariant<TVariant> | undefined {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n if (selectedByOption.size !== matrix.optionIds.length) {\n return undefined\n }\n\n return matrix.variants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selectedByOption.get(optionId),\n ),\n )\n}\n\nfunction getVariantSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n variantId: string | number | null | undefined,\n): ProductOptionMatrixVariant<ProductDetailVariant> | undefined {\n if (variantId == null) return undefined\n const id = String(variantId)\n return matrix.variants.find((variant) => variant.id === id)\n}\n\nfunction hasExplicitSelection(selection: ProductSelectionInput): boolean {\n return Boolean(\n selection.variantId != null ||\n selection.search ||\n selection.valueIds ||\n Object.keys(selection.byOptionId ?? {}).length > 0 ||\n Object.keys(selection.byOptionSlug ?? {}).length > 0,\n )\n}\n\nfunction assignSelectedValue(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueId: string | number | null | undefined,\n): boolean {\n if (valueId == null) return false\n const normalizedValueId = String(valueId)\n if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return false\n selectedByOptionId.set(optionId, normalizedValueId)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionId(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionById.get(optionId)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionId}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(optionId, value.id)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionSlug(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionSlug: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionSlug}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(option.id, value.id)\n return true\n}\n\nfunction toSearchParams(\n search: string | URLSearchParams | URL | null | undefined,\n): URLSearchParams {\n if (!search) return new URLSearchParams()\n if (search instanceof URLSearchParams) return new URLSearchParams(search)\n if (search instanceof URL) return new URLSearchParams(search.searchParams)\n\n const trimmed = search.trim()\n if (!trimmed) return new URLSearchParams()\n\n try {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) {\n return new URL(trimmed).searchParams\n }\n } catch {\n return new URLSearchParams()\n }\n\n return new URLSearchParams(\n trimmed.startsWith('?') ? trimmed.slice(1) : trimmed,\n )\n}\n\nfunction slugLike(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction assertNoAmbiguousSelectionParams(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n params: URLSearchParams,\n) {\n const knownSelectionKeys = new Set<string>()\n const hasVariantParam = params.has('variant')\n const hasOptionParams = Array.from(params.keys()).some((key) =>\n key.startsWith('opt.'),\n )\n\n if (hasVariantParam && hasOptionParams) {\n throw new ProductSelectionCodecError(\n 'Product selection URL cannot mix variant=<variantId> with opt.<optionId>=<valueId> params.',\n )\n }\n\n for (const option of matrix.options) {\n knownSelectionKeys.add(slugLike(option.slug))\n knownSelectionKeys.add(slugLike(option.title))\n for (const value of option.values) {\n if (value.slug) knownSelectionKeys.add(slugLike(value.slug))\n }\n }\n\n for (const [key, value] of params.entries()) {\n if (key.startsWith('opt.')) {\n const optionToken = key.slice(4)\n if (\n !optionToken ||\n (!matrix.optionBySlug.has(optionToken) &&\n !matrix.optionById.has(optionToken))\n ) {\n throw new ProductSelectionCodecError(\n `Unknown product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n if (!value) {\n throw new ProductSelectionCodecError(\n `Product selection query parameter \"${key}\" requires a value ID or compatibility value slug.`,\n )\n }\n continue\n }\n\n if (key === 'variant') {\n if (!value) {\n throw new ProductSelectionCodecError(\n 'Product selection query parameter \"variant\" requires a variant ID.',\n )\n }\n if (!getVariantSelection(matrix, value)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${value}\".`,\n )\n }\n continue\n }\n\n const keyToken = slugLike(key)\n if (\n knownSelectionKeys.has(keyToken) ||\n (value === '' && knownSelectionKeys.has(keyToken))\n ) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n }\n}\n\nfunction emitCompatibilityOptionIdParam(\n options: ProductSelectionCodecOptions | undefined,\n event: CompatibilityProductSelectionParamEvent,\n) {\n try {\n if (options?.onCompatibilityOptionIdParam) {\n options.onCompatibilityOptionIdParam(event)\n return\n }\n options?.onLegacyOptionIdParam?.(event)\n } catch {\n // Compatibility telemetry must not change parser semantics.\n }\n}\n\nfunction assignSearchSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): string | null {\n if (!search) return null\n const params = toSearchParams(search)\n assertNoAmbiguousSelectionParams(matrix, params)\n\n const variantParam = params.get('variant')\n if (variantParam != null) {\n const variantSelection = getVariantSelection(matrix, variantParam)\n if (!variantSelection) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${variantParam}\".`,\n )\n }\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n return variantSelection.id\n }\n\n for (const [key, valueToken] of params.entries()) {\n if (!key.startsWith('opt.')) continue\n const optionToken = key.slice(4)\n\n const optionById = matrix.optionById.get(optionToken)\n if (optionById) {\n if (\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n )\n ) {\n continue\n }\n\n const before = selectedByOptionId.get(optionById.id)\n if (\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n ) &&\n selectedByOptionId.get(optionById.id) !== before\n ) {\n emitCompatibilityOptionIdParam(options, {\n optionId: optionById.id,\n optionSlug: optionById.slug,\n valueSlug: valueToken,\n searchParam: key,\n })\n continue\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n const optionBySlug = matrix.optionBySlug.get(optionToken)\n if (optionBySlug) {\n if (\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionBySlug.slug,\n valueToken,\n )\n ) {\n continue\n }\n\n if (matrix.valueById.has(valueToken)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionSlug>=<valueSlug> for compatibility URLs.`,\n )\n }\n }\n\n return null\n}\n\nexport function normalizeProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return normalizeProductSelectionFromMatrix(matrix, selection, options)\n}\n\nexport function normalizeProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>()\n const variantSelection = getVariantSelection(matrix, selection.variantId)\n const variantId = variantSelection?.id ?? null\n\n if (variantSelection) {\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n }\n\n for (const rawValueId of selection.valueIds ?? []) {\n const valueId = getRelationID(rawValueId as RelationshipValue)\n if (!valueId) continue\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId) continue\n selectedByOptionId.set(optionId, valueId)\n }\n\n const searchVariantId = assignSearchSelection(\n matrix,\n selectedByOptionId,\n selection.search,\n options,\n )\n\n for (const [rawOptionId, rawSelection] of Object.entries(\n selection.byOptionId ?? {},\n )) {\n const optionId = String(rawOptionId)\n if (!matrix.optionById.has(optionId)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueId,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValue(matrix, selectedByOptionId, optionId, rawSelection)\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueSlug,\n )\n }\n }\n\n for (const [rawOptionSlug, rawSelection] of Object.entries(\n selection.byOptionSlug ?? {},\n )) {\n const optionSlug = String(rawOptionSlug)\n if (!matrix.optionBySlug.has(optionSlug)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n const option = matrix.optionBySlug.get(optionSlug)\n if (option) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n option.id,\n rawSelection.valueId,\n )\n }\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n rawSelection.valueSlug,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n String(rawSelection),\n )\n }\n }\n\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId: searchVariantId ?? variantId,\n }\n}\n\nexport function parseProductSelection(\n detail: ProductDetail,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n return normalizeProductSelection(detail, { search }, options)\n}\n\nexport function stringifyProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): string {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const normalized = normalizeProductSelectionFromMatrix(\n matrix,\n selection,\n options,\n )\n const params = new URLSearchParams()\n\n if (hasExplicitSelection(selection)) {\n const matchingVariants = getMatchingVariantEntries(matrix, normalized)\n const exactVariant = getExactSelectedVariantEntry(\n matrix,\n normalized,\n matchingVariants,\n )\n if (exactVariant) {\n params.set('variant', exactVariant.id)\n return params.toString()\n }\n }\n\n const emit = resolveProductSelectionUrlEmit(options?.emit)\n\n for (const optionId of matrix.optionIds) {\n const valueId = normalized.byOptionId[optionId]\n if (!valueId) continue\n if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {\n continue\n }\n\n if (emit === 'slug-compat') {\n if (appendSlugCompatSelectionParam(params, matrix, optionId, valueId)) {\n continue\n }\n }\n\n appendCanonicalSelectionParam(params, optionId, valueId)\n }\n\n return params.toString()\n}\n\nexport function createProductSelectionCodec(\n detail: ProductDetail,\n options?: ProductSelectionCodecOptions,\n): {\n parse: (\n search: string | URLSearchParams | URL | null | undefined,\n ) => NormalizedProductSelection\n stringify: (selection?: ProductSelectionInput) => string\n} {\n return {\n parse: (search) => parseProductSelection(detail, search, options),\n stringify: (selection = {}) =>\n stringifyProductSelection(detail, selection, options),\n }\n}\n\nfunction selectedEntries(\n selection: NormalizedProductSelection,\n): Array<[string, string]> {\n return Object.entries(selection.byOptionId)\n}\n\nfunction getMatchingVariantEntries(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: NormalizedProductSelection,\n): ProductOptionMatrixVariant<ProductDetailVariant>[] {\n const entries = selectedEntries(selection)\n if (entries.length === 0) return matrix.variants\n\n return matrix.variants.filter((variant) =>\n entries.every(\n ([optionId, valueId]) =>\n variant.optionValueByOptionId.get(optionId) === valueId,\n ),\n )\n}\n\nfunction activeVariantEntries(\n variants: ProductOptionMatrixVariant<ProductDetailVariant>[],\n): ProductOptionMatrixVariant<ProductDetailVariant>[] {\n return variants.filter((variant) => variant.source.isActive !== false)\n}\n\nfunction getExactSelectedVariantEntry(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: NormalizedProductSelection,\n matchingVariants: ProductOptionMatrixVariant<ProductDetailVariant>[],\n): ProductOptionMatrixVariant<ProductDetailVariant> | null {\n if (matrix.optionIds.length === 0) {\n return (\n getVariantSelection(matrix, selection.variantId) ??\n (matchingVariants.length === 1 ? (matchingVariants[0] ?? null) : null)\n )\n }\n\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(selection.byOptionId[optionId]),\n )\n if (!allOptionsSelected) return null\n\n return (\n matchingVariants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selection.byOptionId[optionId],\n ),\n ) ?? null\n )\n}\n\nfunction normalizedSelectionFromByOptionId(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n variantId: string | null,\n): NormalizedProductSelection {\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId,\n }\n}\n\nfunction buildFilledNormalizedSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n normalizedSelection: NormalizedProductSelection,\n listing: Partial<ProductDetail['listing']>,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedSelection.byOptionId),\n )\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n if (variantId === normalizedSelection.variantId) {\n return normalizedSelection\n }\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n for (const option of matrix.options) {\n if (selectedByOptionId.has(option.id)) continue\n if (option.values.length === 1) {\n selectedByOptionId.set(option.id, option.values[0]!.id)\n }\n }\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n const partialNormalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n normalizedSelection.variantId,\n )\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n partialNormalized,\n )\n const orderedMatches = [...matchingVariantEntries].sort((left, right) =>\n compareVariantOrder(left.source, right.source),\n )\n\n const hintVariantId =\n listing.selectionHintVariant != null\n ? String(listing.selectionHintVariant)\n : null\n const hintedEntry =\n hintVariantId != null\n ? orderedMatches.find((entry) => entry.id === hintVariantId)\n : undefined\n const availableEntry = orderedMatches.find((entry) =>\n isVariantAvailableForSale(entry.source),\n )\n const chosenEntry = hintedEntry ?? availableEntry ?? orderedMatches[0]\n\n if (!chosenEntry) {\n return normalizedSelection\n }\n\n for (const optionId of matrix.optionIds) {\n if (selectedByOptionId.has(optionId)) continue\n const valueId = chosenEntry.optionValueByOptionId.get(optionId)\n if (valueId) selectedByOptionId.set(optionId, valueId)\n }\n\n const filledVariantId = matrix.optionIds.every((optionId) =>\n selectedByOptionId.has(optionId),\n )\n ? (resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) ??\n chosenEntry.id)\n : normalizedSelection.variantId\n\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n filledVariantId,\n )\n}\n\nfunction resolveVariantIdForCompleteSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n): string | null {\n if (!matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n return null\n }\n\n const normalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n null,\n )\n const matchingVariantEntries = getMatchingVariantEntries(matrix, normalized)\n return (\n getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)\n ?.id ?? null\n )\n}\n\nfunction buildSelectionPrice(\n variants: ProductDetailVariant[],\n): ProductSelectionResolution['price'] {\n const { min, max } = getMinMax(variants.map((variant) => variant.price))\n const { min: compareAtMin, max: compareAtMax } = getMinMax(\n variants.map((variant) => variant.compareAtPrice),\n )\n\n return {\n min,\n max,\n compareAtMin,\n compareAtMax,\n isRange: min !== null && max !== null ? min !== max : false,\n }\n}\n\nfunction isPresentMedia(value: MediaValue): value is ProductDetailMedia {\n return value != null\n}\n\nfunction mediaArray(\n values: MediaValue[] | null | undefined,\n): ProductDetailMedia[] {\n if (!Array.isArray(values)) return []\n return values.filter(isPresentMedia)\n}\n\nfunction buildSelectionMedia(\n detail: {\n images: ProductDetail['images']\n listing: Pick<ProductDetail['listing'], 'primaryImage'>\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n },\n selectedVariant: ProductDetailVariant | null,\n matchingVariants: ProductDetailVariant[],\n selectedValues: ProductOptionMatrixValue[],\n): ProductSelectionResolution['media'] {\n const productPool = mediaArray(detail.images)\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),\n selectedVariant: selectedVariant\n ? {\n id: selectedVariant.id,\n images: selectedVariant.images,\n }\n : null,\n matchingVariants: matchingVariants.map((variant) => ({\n id: variant.id,\n images: variant.images,\n })),\n selectedOptionValues: selectedValues.map((value) => ({\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n })),\n })\n if (resolvedMedia.source !== 'none') {\n return {\n primaryImage: resolvedMedia.primaryImage,\n images: resolvedMedia.images,\n source: resolvedMedia.source,\n }\n }\n\n const displayMedia = resolveProductDisplayMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),\n listingPrimaryImage: detail.listing.primaryImage ?? null,\n })\n if (displayMedia.source !== 'none') {\n return {\n primaryImage: displayMedia.primaryImage,\n images: displayMedia.images,\n source: displayMedia.source,\n }\n }\n\n return { primaryImage: null, images: [], source: 'none' }\n}\n\nfunction buildSelectionStock(\n selectedVariant: ProductDetailVariant | null,\n matchingVariants: ProductDetailVariant[],\n): ProductSelectionResolution['stock'] {\n if (selectedVariant) {\n const availableStock = selectedVariant.isUnlimited\n ? null\n : Math.max(0, selectedVariant.stock - selectedVariant.reservedStock)\n const isActive = selectedVariant.isActive !== false\n return {\n availableForSale:\n isActive && (selectedVariant.isUnlimited || (availableStock ?? 0) > 0),\n isUnlimited: selectedVariant.isUnlimited,\n stock: selectedVariant.stock,\n reservedStock: selectedVariant.reservedStock,\n availableStock,\n }\n }\n\n return {\n availableForSale: matchingVariants.some(isVariantAvailableForSale),\n isUnlimited: matchingVariants.some((variant) => variant.isUnlimited),\n stock: null,\n reservedStock: null,\n availableStock: null,\n }\n}\n\nfunction buildAvailableValueStock(\n variants: ProductDetailVariant[],\n): Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n> {\n const activeVariants = variants.filter(\n (variant) => variant.isActive !== false,\n )\n const isUnlimited = activeVariants.some((variant) => variant.isUnlimited)\n const availableStock = isUnlimited\n ? null\n : activeVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, variant.stock - variant.reservedStock),\n 0,\n )\n\n return {\n availableForSale: activeVariants.some(isVariantAvailableForSale),\n isUnlimited,\n availableStock,\n }\n}\n\nfunction buildProductSelectionAvailableValue(\n matrixValue: ProductOptionMatrixValue,\n _productImages: ProductDetailMedia[],\n selected: boolean,\n available: boolean,\n stock: Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n >,\n): ProductSelectionAvailableValue {\n return {\n valueId: matrixValue.id,\n value: matrixValue.label,\n label: matrixValue.label,\n slug: matrixValue.slug ?? '',\n selected,\n available,\n exists: available,\n ...stock,\n swatch: matrixValue.swatch ?? null,\n }\n}\n\nfunction getCandidateVariantsForValue(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n optionId: string,\n valueId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductDetailVariant[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.set(optionId, valueId)\n\n return matrix.variants\n .filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) ===\n selectedValueId,\n ),\n )\n .map((variant) => variant.source)\n}\n\nfunction getResolutionContext(context?: ProductSelectionResolutionContext): {\n images: ProductDetail['images']\n listing: Partial<ProductDetail['listing']>\n primaryMediaItemId: ProductDetail['primaryMediaItemId']\n} {\n return {\n images: context?.images ?? context?.detail?.images ?? [],\n listing: context?.listing ?? context?.detail?.listing ?? {},\n primaryMediaItemId:\n context?.primaryMediaItemId ??\n context?.detail?.primaryMediaItemId ??\n null,\n }\n}\n\nexport function resolveProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n context?: ProductSelectionResolutionContext,\n): ProductSelectionResolution {\n const { images, listing, primaryMediaItemId } = getResolutionContext(context)\n const effectiveSelection =\n hasExplicitSelection(selection) || listing.selectionHintVariant == null\n ? selection\n : { ...selection, variantId: listing.selectionHintVariant }\n let normalizedSelection = normalizeProductSelectionFromMatrix(\n matrix,\n effectiveSelection,\n options,\n )\n\n if (options?.fillDefaults) {\n normalizedSelection = buildFilledNormalizedSelection(\n matrix,\n normalizedSelection,\n listing,\n )\n }\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n normalizedSelection,\n )\n const activeMatchingVariantEntries = activeVariantEntries(\n matchingVariantEntries,\n )\n const selectedVariantEntry = getExactSelectedVariantEntry(\n matrix,\n normalizedSelection,\n matchingVariantEntries,\n )\n const selectedVariant = selectedVariantEntry?.source ?? null\n const matchingVariants = activeMatchingVariantEntries.map(\n (variant) => variant.source,\n )\n const selectedValues = matrix.optionIds\n .map((optionId) => normalizedSelection.byOptionId[optionId])\n .map((valueId) => (valueId ? matrix.valueById.get(valueId) : undefined))\n .filter((value): value is ProductOptionMatrixValue => value !== undefined)\n const availableValuesByOptionId = Object.fromEntries(\n matrix.options.map((option) => {\n const availableValueIds = new Set(\n getAvailableOptionValues(\n matrix,\n option.id,\n normalizedSelection.valueIds,\n ).map((value) => value.id),\n )\n return [\n option.id,\n option.values.map((value) =>\n buildProductSelectionAvailableValue(\n value,\n images,\n normalizedSelection.byOptionId[option.id] === value.id,\n availableValueIds.has(value.id),\n buildAvailableValueStock(\n getCandidateVariantsForValue(\n matrix,\n option.id,\n value.id,\n normalizedSelection.valueIds,\n ),\n ),\n ),\n ),\n ]\n }),\n )\n const availableValuesByOptionSlug = Object.fromEntries(\n matrix.options.map((option) => [\n option.slug,\n availableValuesByOptionId[option.id] ?? [],\n ]),\n )\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(normalizedSelection.byOptionId[optionId]),\n )\n const priceVariants = selectedVariant ? [selectedVariant] : matchingVariants\n\n return {\n normalizedSelection,\n selectedVariant,\n matchingVariants,\n partialVariants: selectedVariant ? [] : matchingVariants,\n availableValuesByOptionSlug,\n availableValuesByOptionId,\n allOptionsSelected,\n price: buildSelectionPrice(priceVariants),\n media: buildSelectionMedia(\n {\n images,\n listing: {\n primaryImage: listing.primaryImage ?? null,\n },\n primaryMediaItemId,\n },\n selectedVariant,\n matchingVariants,\n selectedValues,\n ),\n stock: buildSelectionStock(selectedVariant, matchingVariants),\n }\n}\n\nexport function resolveProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): ProductSelectionResolution {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return resolveProductSelectionFromMatrix(matrix, selection, options, {\n detail,\n })\n}\n\nexport function selectNext(\n detail: ProductDetail,\n current: ProductSelectionInput = {},\n optionSlug: string,\n valueSlug: string,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const listing = detail.listing ?? {}\n const normalizedCurrent = normalizeProductSelectionFromMatrix(\n matrix,\n current,\n options,\n )\n\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return normalizedCurrent\n\n const valueMatches = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (valueMatches.length !== 1) return normalizedCurrent\n const clickedValueId = valueMatches[0]!.id\n\n const keepClickedSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>()\n selectedByOptionId.set(option.id, clickedValueId)\n\n for (const otherOptionId of matrix.optionIds) {\n if (otherOptionId === option.id) continue\n const otherValueId = normalizedCurrent.byOptionId[otherOptionId]\n if (!otherValueId) continue\n\n const constraintIds = normalizeSelectedValueIds(\n matrix,\n Array.from(selectedByOptionId.values()),\n )\n const available = getAvailableOptionValues(\n matrix,\n otherOptionId,\n constraintIds,\n )\n if (available.some((candidate) => candidate.id === otherValueId)) {\n selectedByOptionId.set(otherOptionId, otherValueId)\n }\n }\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n listing,\n )\n }\n\n const keepPriorSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedCurrent.byOptionId),\n )\n selectedByOptionId.delete(option.id)\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n listing,\n )\n }\n\n const clickedResult = keepClickedSelection()\n const clickedVariantId = resolveVariantIdForCompleteSelection(\n matrix,\n new Map(Object.entries(clickedResult.byOptionId)),\n )\n\n const priorValueIds = Object.entries(normalizedCurrent.byOptionId)\n .filter(([otherOptionId]) => otherOptionId !== option.id)\n .map(([, valueId]) => valueId)\n\n const clickedAvailableWithPrior =\n priorValueIds.length === 0 ||\n getAvailableOptionValues(matrix, option.id, priorValueIds).some(\n (candidate) => candidate.id === clickedValueId,\n )\n\n if (clickedVariantId != null) {\n const priorClickedValue = normalizedCurrent.byOptionId[option.id]\n if (priorClickedValue != null && priorClickedValue !== clickedValueId) {\n return clickedResult\n }\n if (clickedAvailableWithPrior) {\n return clickedResult\n }\n }\n\n return keepPriorSelection()\n}\n\nexport type ProductDetailImageMedia = Extract<\n ProductDetailMedia,\n { id?: string | number | null; url?: string | null }\n>\n\nfunction isProductDetailImageMedia(\n value: ProductDetailMedia | null | undefined,\n): value is ProductDetailImageMedia {\n return typeof value === 'object' && value !== null\n}\n\nfunction mediaDedupeKey(value: ProductDetailImageMedia): string | null {\n if (value.id != null) return `id:${String(value.id)}`\n if (value.url) return `url:${value.url}`\n return null\n}\n\nexport function getProductSelectionImages(\n resolution: Pick<ProductSelectionResolution, 'media'>,\n): ProductDetailImageMedia[] {\n const seen = new Set<string>()\n const images: ProductDetailImageMedia[] = []\n const candidates = [\n resolution.media.primaryImage,\n ...resolution.media.images,\n ].filter(isProductDetailImageMedia)\n\n for (const candidate of candidates) {\n const key = mediaDedupeKey(candidate)\n if (key && seen.has(key)) continue\n if (key) seen.add(key)\n images.push(candidate)\n }\n\n return images\n}\n\nexport type ProductHrefProduct =\n | ProductDetail\n | {\n slug?: string | null\n product?: { slug?: string | null } | null\n }\n\nexport type ProductHrefGroup = {\n optionId?: string | number | null\n optionSlug?: string | null\n optionValueId?: string | number | null\n optionValueSlug?: string | null\n variantId?: string | number | null\n listing?: {\n selectionHintVariant?: string | number | null\n } | null\n}\n\nexport type ProductHrefOptions = {\n basePath?: string\n detail?: ProductDetail\n matrix?: ProductOptionMatrix<ProductDetailVariant>\n selection?: ProductSelectionInput\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nexport type ProductListingCardOptions = {\n basePath?: string\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nfunction getProductHrefSlug(product: ProductHrefProduct): string {\n if ('product' in product && product.product?.slug) {\n return product.product.slug\n }\n if ('slug' in product && product.slug) return product.slug\n throw new ProductSelectionCodecError(\n 'Product slug is required to build a product href.',\n )\n}\n\nfunction joinProductPath(\n basePath: string,\n slug: string,\n trailingSlash: boolean,\n) {\n const base = basePath.replace(/\\/+$/, '')\n const encodedSlug = encodeURIComponent(slug)\n return `${base}/${encodedSlug}${trailingSlash ? '/' : ''}`\n}\n\nfunction getProductHrefGroupSelection(\n group: ProductHrefGroup | null | undefined,\n matrix?: ProductOptionMatrix<ProductDetailVariant>,\n): ProductSelectionInput | null {\n if (!group) return null\n\n if (group.variantId != null) return { variantId: group.variantId }\n\n const optionId =\n group.optionId != null\n ? String(group.optionId)\n : group.optionSlug\n ? matrix?.optionBySlug.get(group.optionSlug)?.id\n : undefined\n if (!optionId) return null\n\n const option = matrix?.optionById.get(optionId)\n const optionValueId =\n group.optionValueId != null\n ? String(group.optionValueId)\n : group.optionValueSlug && option\n ? option.values.find((value) => value.slug === group.optionValueSlug)\n ?.id\n : undefined\n\n if (!optionValueId) return null\n return { byOptionId: { [optionId]: optionValueId } }\n}\n\nfunction getProductHrefCodecOptions(\n options: ProductHrefOptions,\n): ProductSelectionCodecOptions | undefined {\n return options.emit != null ? { emit: options.emit } : undefined\n}\n\nfunction appendGroupByOptionIdHrefParams(\n params: URLSearchParams,\n group: ProductHrefGroup | null | undefined,\n groupSelection: ProductSelectionInput,\n options: ProductHrefOptions,\n): boolean {\n const emit = resolveProductSelectionUrlEmit(options.emit)\n const byOptionId = groupSelection.byOptionId ?? {}\n const entries = Object.entries(byOptionId)\n if (entries.length === 0) return false\n\n for (const [optionId, valueId] of entries) {\n const optionSlug =\n group?.optionSlug ??\n options.matrix?.optionById.get(optionId)?.slug ??\n null\n const valueSlug =\n group?.optionValueSlug ??\n options.matrix?.valueById.get(String(valueId))?.slug ??\n null\n\n if (\n emit === 'slug-compat' &&\n optionSlug &&\n valueSlug &&\n entries.length === 1\n ) {\n params.set(`opt.${optionSlug}`, valueSlug)\n return true\n }\n\n if (\n emit === 'slug-compat' &&\n options.matrix &&\n appendSlugCompatSelectionParam(\n params,\n options.matrix,\n optionId,\n String(valueId),\n )\n ) {\n continue\n }\n appendCanonicalSelectionParam(params, optionId, String(valueId))\n }\n\n return params.size > 0\n}\n\nfunction getPreferCompleteVariantFromHintSelection(\n group: ProductHrefGroup | null | undefined,\n options: ProductHrefOptions,\n): ProductSelectionInput | null {\n if (!options.preferCompleteVariantFromHint) return null\n if (group?.optionValueId != null || group?.optionValueSlug) return null\n\n const hintVariantId = group?.listing?.selectionHintVariant\n if (hintVariantId == null) return null\n\n return { variantId: hintVariantId }\n}\n\nexport function buildProductHref(\n product: ProductHrefProduct,\n group?: ProductHrefGroup | null,\n options: ProductHrefOptions = {},\n): string {\n const path = joinProductPath(\n options.basePath ?? '/products',\n getProductHrefSlug(product),\n options.trailingSlash ?? false,\n )\n const params = new URLSearchParams()\n\n if (options.detail && options.selection) {\n const selection = stringifyProductSelection(\n options.detail,\n options.selection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n\n const preferVariantSelection = getPreferCompleteVariantFromHintSelection(\n group,\n options,\n )\n if (preferVariantSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n preferVariantSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (preferVariantSelection.variantId != null) {\n params.set('variant', String(preferVariantSelection.variantId))\n return `${path}?${params.toString()}`\n }\n }\n\n const groupSelection = getProductHrefGroupSelection(group, options.matrix)\n if (groupSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n groupSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (groupSelection.variantId != null) {\n params.set('variant', String(groupSelection.variantId))\n return `${path}?${params.toString()}`\n }\n if (\n appendGroupByOptionIdHrefParams(params, group, groupSelection, options)\n ) {\n return `${path}?${params.toString()}`\n }\n }\n\n if (group?.optionValueSlug) {\n const optionSlug =\n group.optionSlug ??\n (group.optionId != null\n ? options.matrix?.optionById.get(String(group.optionId))?.slug\n : undefined)\n if (optionSlug) {\n params.set(`opt.${optionSlug}`, group.optionValueSlug)\n }\n }\n\n return params.size > 0 ? `${path}?${params.toString()}` : path\n}\n\nfunction compareVariantOrder(a: ProductVariantShape, b: ProductVariantShape) {\n const aOrder = Number(a._order ?? Number.MAX_SAFE_INTEGER)\n const bOrder = Number(b._order ?? Number.MAX_SAFE_INTEGER)\n\n if (Number.isFinite(aOrder) && Number.isFinite(bOrder) && aOrder !== bOrder) {\n return aOrder - bOrder\n }\n\n const aId = String(getRelationID(a.id) ?? '')\n const bId = String(getRelationID(b.id) ?? '')\n return aId.localeCompare(bId)\n}\n\nfunction isVariantAvailableForSale(variant: ProductVariantShape) {\n if (variant.isActive === false) return false\n if (variant.isUnlimited) return true\n return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0\n}\n\nfunction sortVariantsForMediaSelection(\n variants: ProductVariantShape[],\n): ProductVariantShape[] {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const unavailableActiveVariants = activeVariants.filter(\n (variant) => !isVariantAvailableForSale(variant),\n )\n\n return [...availableVariants, ...unavailableActiveVariants]\n}\n\nfunction variantHasPoolMedia(\n variant: ProductVariantShape | null,\n productMediaPool: MediaValue[],\n): boolean {\n if (!variant?.images?.length) return false\n return variant.images.some((image) => {\n const imageId = getRelationID(image)\n return Boolean(\n imageId &&\n productMediaPool.some((poolItem) => getRelationID(poolItem) === imageId),\n )\n })\n}\n\nfunction getMinMax(values: Array<number | null | undefined>) {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number',\n )\n if (numbers.length === 0) {\n return { min: null, max: null }\n }\n\n return {\n min: Math.min(...numbers),\n max: Math.max(...numbers),\n }\n}\n\nexport function buildProductListingProjection(\n product: ProductListingProductShape | null | undefined,\n variants: ProductVariantShape[],\n): ProductListingProjection {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null\n\n const { min: minPrice, max: maxPrice } = getMinMax(\n activeVariants.map((variant) => variant.price),\n )\n const { min: minCompareAtPrice, max: maxCompareAtPrice } = getMinMax(\n activeVariants.map((variant) => variant.compareAtPrice),\n )\n\n const productMediaPool = product?.images ?? []\n const selectionHintHasPoolMedia = variantHasPoolMedia(\n selectionHintVariant,\n productMediaPool,\n )\n const mediaSelectionVariants = sortVariantsForMediaSelection(variants)\n const resolvedProductMedia = resolveProductSelectionMedia<MediaValue>({\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product?.primaryMediaItemId),\n selectedVariant:\n selectionHintVariant && selectionHintHasPoolMedia\n ? {\n id: selectionHintVariant.id,\n images: selectionHintVariant.images,\n }\n : null,\n matchingVariants: selectionHintHasPoolMedia ? [] : mediaSelectionVariants,\n })\n\n return {\n selectionHintVariant: getRelationID(selectionHintVariant?.id) ?? null,\n primaryImage: resolveGenericListingPrimaryImage(\n product,\n resolvedProductMedia.primaryImage,\n resolvedProductMedia.source,\n ),\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n minPrice !== null && maxPrice !== null ? minPrice !== maxPrice : false,\n availableForSale: availableVariants.length > 0,\n }\n}\n\nexport function buildProductListingCard(\n item: ProductListingGroupsItem,\n options: ProductListingCardOptions = {},\n): ProductListingCard {\n const product = item.product\n const groups = item.groups\n const variants = getProductListingCardVariants(item)\n const projectedListing = buildProductListingProjection(product, variants)\n const selectionHintVariant =\n getRelationID(product.listing?.selectionHintVariant) ??\n projectedListing.selectionHintVariant\n const representativeVariant = findListingCardRepresentativeVariant(\n variants,\n selectionHintVariant,\n )\n\n const productMediaPool = mediaArray(product.images)\n const representativeHasPoolMedia = Boolean(\n representativeVariant?.images?.some((image) =>\n productMediaPool.some(\n (poolItem) => getRelationID(poolItem) === getRelationID(image),\n ),\n ),\n )\n const resolvedPrimaryMedia = resolveProductSelectionMedia<ProductDetailMedia>(\n {\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),\n selectedVariant: representativeHasPoolMedia\n ? representativeVariant\n : null,\n matchingVariants: representativeHasPoolMedia ? [] : variants,\n },\n )\n const listingPrimaryPointer = resolveListingPrimaryImagePointer({\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),\n productThumbnail: product.thumbnail ?? null,\n listingPrimaryImage: product.listing?.primaryImage ?? null,\n resolvedPrimary: resolvedPrimaryMedia.primaryImage,\n resolvedSource: resolvedPrimaryMedia.source,\n })\n const listingPrimaryMedia = listingPrimaryPointer\n ? (productMediaPool.find(\n (item) => getRelationID(item) === listingPrimaryPointer,\n ) ??\n resolvedPrimaryMedia.primaryImage ??\n null)\n : null\n\n const priceRange = resolveListingCardPriceRange(\n product,\n projectedListing,\n groups,\n )\n\n const availableForSale =\n product.listing?.availableForSale != null\n ? product.listing.availableForSale\n : groups.length > 0\n ? groups.some((group) => group.listing.availableForSale)\n : projectedListing.availableForSale\n\n const swatches: ProductListingSwatch[] =\n groups.length > 1\n ? groups.map((group) => buildListingSwatch(product, group, options))\n : []\n\n return {\n id: String(product.id),\n href: buildProductHref(\n { slug: product.slug },\n { listing: { selectionHintVariant } },\n options,\n ),\n title: product.title,\n representativeVariant,\n primaryImage: listingPrimaryMedia,\n priceRange,\n availableForSale,\n swatches,\n }\n}\n\nfunction getProductListingCardVariants(\n item: ProductListingGroupsItem,\n): ProductListingCardRepresentativeVariant[] {\n const productVariants = item.product.variants?.docs\n if (Array.isArray(productVariants) && productVariants.length > 0) {\n return productVariants\n }\n\n const variants: ProductListingCardRepresentativeVariant[] = []\n const seen = new Set<string>()\n\n for (const group of item.groups) {\n for (const variant of group.variants) {\n const id = getRelationID(variant.id)\n if (id && seen.has(id)) continue\n if (id) seen.add(id)\n variants.push(variant)\n }\n }\n\n return variants\n}\n\nfunction findListingCardRepresentativeVariant(\n variants: ProductListingCardRepresentativeVariant[],\n representativeVariantId: EntityID | null,\n): ProductListingCardRepresentativeVariant | null {\n if (representativeVariantId == null) return null\n return (\n variants.find(\n (variant) => getRelationID(variant.id) === representativeVariantId,\n ) ?? null\n )\n}\n\n/** Shopify `priceRangeV2` naming for persisted listing projection fields. */\nexport function toShopifyPriceRangeV2(listing: {\n minPrice?: number | null\n maxPrice?: number | null\n}): {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n} {\n return {\n minVariantPrice: { amount: listing.minPrice ?? null },\n maxVariantPrice: { amount: listing.maxPrice ?? null },\n }\n}\n\nfunction hasCompleteListingPriceProjection(\n listing: ProductListingGroupsItem['product']['listing'] | null | undefined,\n): listing is NonNullable<ProductListingGroupsItem['product']['listing']> & {\n minPrice: number\n maxPrice: number\n} {\n return listing?.minPrice != null && listing?.maxPrice != null\n}\n\nfunction listingDefinesCompareAtProjection(\n listing: NonNullable<ProductListingGroupsItem['product']['listing']>,\n): boolean {\n return 'minCompareAtPrice' in listing || 'maxCompareAtPrice' in listing\n}\n\nfunction resolveListingCardPriceRange(\n product: ProductListingGroupsItem['product'],\n projectedListing: ReturnType<typeof buildProductListingProjection>,\n groups: ProductListingGroupsItem['groups'],\n): ProductListingCardPriceRange {\n const listing = product.listing\n if (hasCompleteListingPriceProjection(listing)) {\n const groupRange =\n groups.length > 0 ? aggregateListingPriceRange(groups) : null\n const definesCompareAt = listingDefinesCompareAtProjection(listing)\n\n return {\n minPrice: listing.minPrice,\n maxPrice: listing.maxPrice,\n minCompareAtPrice: definesCompareAt\n ? (listing.minCompareAtPrice ?? null)\n : (groupRange?.minCompareAtPrice ??\n projectedListing.minCompareAtPrice),\n maxCompareAtPrice: definesCompareAt\n ? (listing.maxCompareAtPrice ?? null)\n : (groupRange?.maxCompareAtPrice ??\n projectedListing.maxCompareAtPrice),\n isPriceRange:\n listing.isPriceRange ??\n (listing.minPrice !== listing.maxPrice),\n }\n }\n\n if (groups.length > 0) {\n return aggregateListingPriceRange(groups)\n }\n\n return {\n minPrice: projectedListing.minPrice,\n maxPrice: projectedListing.maxPrice,\n minCompareAtPrice: projectedListing.minCompareAtPrice,\n maxCompareAtPrice: projectedListing.maxCompareAtPrice,\n isPriceRange: projectedListing.isPriceRange,\n }\n}\n\nfunction aggregateListingPriceRange(\n groups: ProductListingGroupsItem['groups'],\n): ProductListingCardPriceRange {\n const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice))\n const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice))\n const minCompareAtPrice = minOfNullable(\n groups.map((g) => g.listing.minCompareAtPrice),\n )\n const maxCompareAtPrice = maxOfNullable(\n groups.map((g) => g.listing.maxCompareAtPrice),\n )\n const isPriceRange =\n minPrice !== null && maxPrice !== null && minPrice !== maxPrice\n return {\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange,\n }\n}\n\nfunction buildListingSwatch(\n product: ProductListingGroupsItem['product'],\n group: ProductListingGroupsItem['groups'][number],\n options: ProductListingCardOptions,\n): ProductListingSwatch {\n return {\n optionId: group.optionId,\n optionValueId: group.optionValueId,\n label: group.optionValueLabel,\n swatch: group.optionValueSwatch ?? null,\n href: buildProductHref(\n { slug: product.slug },\n {\n optionId: group.optionId,\n optionSlug: group.optionSlug,\n optionValueId: group.optionValueId,\n optionValueSlug: group.optionValueSlug,\n listing: group.listing,\n },\n options,\n ),\n availableForSale: group.listing.availableForSale,\n }\n}\n\nfunction minOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.min(...numbers)\n}\n\nfunction maxOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.max(...numbers)\n}\n\n/**\n * Builds product-first listing groups for one primary option.\n *\n * The returned groups are intended for product cards with nested swatches or\n * option-value sections. They do not make a product-paginated API response into\n * an expanded-card paginator; one product can still emit several groups.\n */\nexport function buildProductListingGroupsByOption<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(args: {\n product: ProductListingProductShape | null | undefined\n options: ProductOptionShape[]\n variants: TVariant[]\n primaryOptionId?: string | null\n}): ProductListingGroup<TVariant>[] {\n const primaryOptionId = args.primaryOptionId ?? undefined\n if (!primaryOptionId) return []\n\n const matrix = buildProductOptionMatrix({\n options: args.options,\n variants: args.variants,\n })\n const primaryOption = matrix.optionById.get(primaryOptionId)\n if (!primaryOption) return []\n\n return primaryOption.values.flatMap((value) => {\n const variants = matrix.variants\n .filter(\n (variant) =>\n variant.optionValueByOptionId.get(primaryOption.id) === value.id,\n )\n .map((variant) => variant.source)\n\n if (variants.length === 0) {\n return []\n }\n\n const listingBase = buildProductListingProjection(undefined, variants)\n const orderedVariants = sortVariantsForMediaSelection(variants)\n const productMediaPool = (args.product?.images ?? []).filter(\n (image): image is ProductDetailMedia =>\n image != null && typeof image === 'object',\n )\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool,\n productPrimaryMediaItemId: extractEntityId(\n args.product?.primaryMediaItemId ?? null,\n ),\n selectedVariant: null,\n matchingVariants: orderedVariants,\n selectedOptionValues: [\n {\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n },\n ],\n })\n const groupPrimaryImage =\n extractEntityId(resolvedMedia.primaryImage) ??\n getFirstAvailableVariantPrimaryImage(variants) ??\n extractEntityId(args.product?.thumbnail) ??\n getFirstMediaId(args.product?.images)\n\n return [\n {\n optionId: primaryOption.id,\n optionTitle: primaryOption.title,\n optionSlug: primaryOption.slug,\n optionValueId: value.id,\n optionValueLabel: value.label,\n optionValueSlug: value.slug,\n optionValueSwatch: value.swatch ?? null,\n variantIds: variants.map((variant) => String(variant.id)),\n variantCount: variants.length,\n variants,\n listing: {\n ...listingBase,\n primaryImage: groupPrimaryImage,\n },\n },\n ]\n })\n}\n","import {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n type ProductDisplayMediaSource,\n type ProductSelectionMediaSource,\n type ResolveProductSelectionMediaInput,\n type ResolveProductSelectionMediaResult,\n} from './product-selection-media'\n\nexport type { NormalizedOptionSwatch } from './product-selection-media'\nexport { selectedSwatchMediaItemId } from './product-selection-media'\n\n/** @deprecated Use `ProductSelectionMediaSource` or `ProductDisplayMediaSource`. */\nexport type MediaPointerSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n | 'variant_featured'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput`. */\nexport type ResolveProductMediaInput<TMedia> =\n ResolveProductSelectionMediaInput<TMedia> & {\n variantFeaturedMediaItemId?: string | number | null\n selectedOptionValueMediaItemIds?: Array<string | number | null | undefined>\n legacy?: {\n variantThumbnail?: TMedia | null\n variantImages?: TMedia[] | null\n optionValueThumbnails?: Array<TMedia | null | undefined>\n optionValueImages?: Array<TMedia[] | null | undefined>\n productThumbnail?: TMedia | null\n productImages?: TMedia[] | null\n }\n }\n\n/** @deprecated Use `ResolveProductSelectionMediaResult`. */\nexport type ResolveProductMediaResult<TMedia> = Omit<\n ResolveProductSelectionMediaResult<TMedia>,\n 'source'\n> & {\n source: MediaPointerSource\n}\n\nfunction mediaPointerOptionValues(\n values: Array<string | number | null | undefined> | undefined,\n) {\n return (values ?? [])\n .filter((value): value is string | number => value != null && value !== '')\n .map((value) => ({\n swatch: {\n type: 'media' as const,\n mediaItemId: value,\n },\n }))\n}\n\n/**\n * @deprecated One-release shim for ADR 0016. Prefer\n * `resolveProductSelectionMedia()`. Legacy direct-media fallbacks are ignored;\n * callers fall through to product display media (`resolveProductDisplayMedia`)\n * or `none`.\n */\nexport function resolveProductMedia<TMedia>(\n input: ResolveProductMediaInput<TMedia>,\n): ResolveProductMediaResult<TMedia> {\n const resolved = resolveProductSelectionMedia({\n ...input,\n selectedVariant:\n input.selectedVariant ??\n (input.variantFeaturedMediaItemId\n ? { images: [input.variantFeaturedMediaItemId] }\n : null),\n selectedOptionValues:\n input.selectedOptionValues ??\n mediaPointerOptionValues(input.selectedOptionValueMediaItemIds),\n })\n\n if (resolved.source !== 'none') {\n return {\n ...resolved,\n source:\n resolved.source === 'variant_media_selected'\n ? 'variant_featured'\n : resolved.source,\n }\n }\n\n const display = resolveProductDisplayMedia({\n productMediaPool: input.productMediaPool,\n productPrimaryMediaItemId: input.productPrimaryMediaItemId,\n })\n\n return {\n primaryImage: display.primaryImage,\n images: display.images,\n source: display.source,\n }\n}\n","import {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n type ProductDisplayMediaSource,\n type ProductSelectionMediaPointer,\n type ProductSelectionMediaSource,\n type ResolveProductSelectionMediaInput,\n} from './product-selection-media'\n\n/** @deprecated ADR 0016 replaces media sets with variant `images[]` subsets. */\nexport type ProductMediaSetMatchType =\n | 'default'\n | 'option-values'\n | 'exact-variant'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput` and variant `images[]`. */\nexport type ProductMediaSetInput = {\n label?: string | null\n matchType: ProductMediaSetMatchType\n optionValueIds?: Array<string | number | null | undefined> | null\n variantIds?: Array<string | number | null | undefined> | null\n items: Array<string | number | null | undefined>\n primaryMediaItemId?: string | number | null\n}\n\ntype LegacyProductGallerySource =\n | 'exact_variant_set'\n | 'option_value_set'\n | 'default_set'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput`. */\nexport type ResolveProductGalleryInput<TMedia> =\n ResolveProductSelectionMediaInput<TMedia> & {\n pool?: TMedia[] | null\n mediaSets?: ProductMediaSetInput[] | null\n selectedVariantId?: string | number | null\n selectedOptionValueIds?: Array<string | number | null | undefined> | null\n listingPrimaryImage?: ProductSelectionMediaPointer\n }\n\n/** @deprecated Use selection or display media source types. */\nexport type ProductGallerySource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n | LegacyProductGallerySource\n\n/** @deprecated Use `ResolveProductSelectionMediaResult`. */\nexport type ResolveProductGalleryResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductGallerySource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction mediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction relationshipIds(\n values: Array<string | number | null | undefined> | null | undefined,\n): string[] {\n if (!Array.isArray(values)) return []\n return values\n .map((value) => mediaId(value))\n .filter((value): value is string => Boolean(value))\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n for (const item of pool) {\n const id = mediaId(item)\n if (id) poolById.set(id, item)\n }\n return poolById\n}\n\nfunction mediaSetItemsInPool<TMedia>(\n mediaSet: ProductMediaSetInput,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n const seen = new Set<string>()\n const items: TMedia[] = []\n const primaryId = mediaId(mediaSet.primaryMediaItemId)\n\n if (primaryId) {\n const primary = poolById.get(primaryId)\n if (primary) {\n seen.add(primaryId)\n items.push(primary)\n }\n }\n\n for (const itemId of relationshipIds(mediaSet.items)) {\n if (seen.has(itemId)) continue\n const item = poolById.get(itemId)\n if (!item) continue\n seen.add(itemId)\n items.push(item)\n }\n\n return items\n}\n\nfunction resolveLegacyMediaSet<TMedia>(\n input: ResolveProductGalleryInput<TMedia>,\n): ResolveProductGalleryResult<TMedia> | null {\n if (!Array.isArray(input.mediaSets)) return null\n\n const pool = input.productMediaPool ?? input.pool ?? []\n const poolById = buildPoolById(pool)\n\n const selectedVariantId = mediaId(input.selectedVariantId)\n if (selectedVariantId) {\n const exactSet = input.mediaSets.find(\n (set) =>\n set.matchType === 'exact-variant' &&\n relationshipIds(set.variantIds).includes(selectedVariantId),\n )\n if (exactSet) {\n const images = mediaSetItemsInPool(exactSet, poolById)\n if (images.length > 0) {\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'exact_variant_set',\n }\n }\n }\n }\n\n const selectedOptionValueIds = new Set(\n relationshipIds(input.selectedOptionValueIds),\n )\n const optionSetMatches = input.mediaSets\n .filter((set) => set.matchType === 'option-values')\n .map((set) => {\n const optionValueIds = relationshipIds(set.optionValueIds)\n if (optionValueIds.length === 0) return null\n if (!optionValueIds.every((id) => selectedOptionValueIds.has(id))) {\n return null\n }\n const images = mediaSetItemsInPool(set, poolById)\n if (images.length === 0) return null\n return { optionValueCount: optionValueIds.length, images }\n })\n .filter(\n (\n match,\n ): match is {\n optionValueCount: number\n images: TMedia[]\n } => Boolean(match),\n )\n .sort((a, b) => b.optionValueCount - a.optionValueCount)\n\n if (optionSetMatches.length > 0) {\n const images = optionSetMatches[0]!.images\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'option_value_set',\n }\n }\n\n const defaultSet = input.mediaSets.find((set) => set.matchType === 'default')\n if (defaultSet) {\n const images = mediaSetItemsInPool(defaultSet, poolById)\n if (images.length > 0) {\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'default_set',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\n/** @deprecated Use `resolveProductSelectionMedia()`. */\nexport function resolveProductGallery<TMedia>(\n input: ResolveProductGalleryInput<TMedia>,\n): ResolveProductGalleryResult<TMedia> {\n const legacyResolved = resolveLegacyMediaSet(input)\n if (legacyResolved && legacyResolved.source !== 'none') return legacyResolved\n\n const selectedVariantId = mediaId(input.selectedVariantId)\n const selectedOptionValueIds = relationshipIds(input.selectedOptionValueIds)\n\n const selection = resolveProductSelectionMedia({\n ...input,\n productMediaPool: input.productMediaPool ?? input.pool ?? null,\n selectedVariant:\n input.selectedVariant ??\n (selectedVariantId ? { id: selectedVariantId } : null),\n selectedOptionValues:\n input.selectedOptionValues ??\n selectedOptionValueIds.map((id) => ({ id })),\n })\n\n if (selection.source !== 'none') {\n return selection\n }\n\n return resolveProductDisplayMedia({\n productMediaPool: input.productMediaPool ?? input.pool ?? null,\n productPrimaryMediaItemId: input.productPrimaryMediaItemId,\n listingPrimaryImage: input.listingPrimaryImage,\n })\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: Record<\n string,\n | {\n url?: string | null\n width?: number | null\n height?: number | null\n }\n | undefined\n >\n}\n\n/** Pre-generated image size breakpoints (px) */\nexport const IMAGE_SIZES = [384, 768, 1536] as const\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n if (size >= target) {\n const entry = sizes[String(size)]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-384 384w, url-768 768w, url-1536 1536w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n const entry = sizes[String(size)]\n if (entry?.url && entry.width) {\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n","export const generateOrderNumber = () => {\n // YYMMDDRRRRRR\n const now = new Date()\n const year = now.getFullYear().toString().slice(-2)\n const month = (now.getMonth() + 1).toString().padStart(2, '0')\n const day = now.getDate().toString().padStart(2, '0')\n // Use crypto.getRandomValues for cryptographically secure randomness (works in both browser and Node.js)\n const array = new Uint32Array(1)\n globalThis.crypto.getRandomValues(array)\n const random = ((array[0] ?? 0) % 1000000).toString().padStart(6, '0')\n\n return `${year}${month}${day}${random}`\n}\n","import { Product } from '../../payload-types'\nimport { resolveRelation } from '../types'\n\ntype OrderItem = {\n product: Product | string | null | undefined\n}\n\nexport const formatOrderName = (items: OrderItem[]) => {\n if (items.length === 0) return ''\n\n const firstTitle = resolveRelation(items[0]?.product)?.title || ''\n\n return items.length === 1\n ? firstTitle\n : `${firstTitle} 외 ${items.length - 1}건`\n}\n","const MUX_IMAGE_BASE = 'https://image.mux.com'\nconst MUX_STREAM_BASE = 'https://stream.mux.com'\n\n// ── Thumbnail ──\n\nexport interface VideoThumbnailOptions {\n /** Width in pixels (default: 640) */\n width?: number\n /** Height in pixels (auto if omitted) */\n height?: number\n /** Time offset in seconds (default: 0) */\n time?: number\n /** Fit mode (default: 'smartcrop') */\n fitMode?: 'preserve' | 'stretch' | 'crop' | 'smartcrop' | 'pad'\n /** Flip horizontally */\n flipH?: boolean\n /** Flip vertically */\n flipV?: boolean\n /** Rotation in degrees (90, 180, 270) */\n rotate?: 90 | 180 | 270\n}\n\n/**\n * Returns a Mux thumbnail URL for a video.\n *\n * @example\n * ```ts\n * getVideoThumbnail('abc123')\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=640'\n *\n * getVideoThumbnail('abc123', { width: 320, time: 5 })\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=320&time=5'\n * ```\n */\nexport function getVideoThumbnail(\n playbackId: string,\n options?: VideoThumbnailOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 640))\n if (options?.height) params.set('height', String(options.height))\n if (options?.time != null) params.set('time', String(options.time))\n if (options?.fitMode) params.set('fit_mode', options.fitMode)\n if (options?.flipH) params.set('flip_h', 'true')\n if (options?.flipV) params.set('flip_v', 'true')\n if (options?.rotate) params.set('rotate', String(options.rotate))\n return `${MUX_IMAGE_BASE}/${playbackId}/thumbnail.jpg?${params}`\n}\n\n// ── Animated GIF ──\n\nexport interface VideoGifOptions {\n /** Width in pixels (default: 320) */\n width?: number\n /** Start time in seconds (default: 0) */\n start?: number\n /** End time in seconds (default: start + 5) */\n end?: number\n /** Frames per second (default: 15) */\n fps?: number\n}\n\n/**\n * Returns a Mux animated GIF URL for a video.\n *\n * @example\n * ```ts\n * getVideoGif('abc123')\n * // => 'https://image.mux.com/abc123/animated.gif?width=320'\n *\n * getVideoGif('abc123', { width: 240, start: 2, end: 6 })\n * // => 'https://image.mux.com/abc123/animated.gif?width=240&start=2&end=6'\n * ```\n */\nexport function getVideoGif(\n playbackId: string,\n options?: VideoGifOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 320))\n if (options?.start != null) params.set('start', String(options.start))\n if (options?.end != null) params.set('end', String(options.end))\n if (options?.fps) params.set('fps', String(options.fps))\n return `${MUX_IMAGE_BASE}/${playbackId}/animated.gif?${params}`\n}\n\n// ── Storyboard ──\n\n/**\n * Returns a Mux storyboard VTT URL for timeline hover previews.\n *\n * @example\n * ```ts\n * getVideoStoryboard('abc123')\n * // => 'https://image.mux.com/abc123/storyboard.vtt'\n * ```\n */\nexport function getVideoStoryboard(playbackId: string): string {\n return `${MUX_IMAGE_BASE}/${playbackId}/storyboard.vtt`\n}\n\n// ── Stream / Playback URLs ──\n\n/**\n * Returns the HLS stream URL for a video.\n *\n * @example\n * ```ts\n * getVideoStreamUrl('abc123')\n * // => 'https://stream.mux.com/abc123.m3u8'\n * ```\n */\nexport function getVideoStreamUrl(playbackId: string): string {\n return `${MUX_STREAM_BASE}/${playbackId}.m3u8`\n}\n\n/**\n * Returns a Mux MP4 download URL for a video.\n * Only available if the asset was created with `mp4_support` enabled.\n *\n * @example\n * ```ts\n * getVideoMp4Url('abc123', 'high')\n * // => 'https://stream.mux.com/abc123/high.mp4'\n * ```\n */\nexport function getVideoMp4Url(\n playbackId: string,\n resolution: 'high' | 'medium' | 'low' = 'high',\n): string {\n return `${MUX_STREAM_BASE}/${playbackId}/${resolution}.mp4`\n}\n","/**\n * @01.software/sdk — Analytics Helper\n */\n\n/* ANALYTICS INVARIANTS START\n * @01.software/sdk — Analytics Helper\n *\n * ANALYTICS INVARIANTS\n * ====================\n * These invariants are the single source of truth for observable behavior.\n * They are mirrored verbatim in apps/console/src/app/api/analytics/script.js/route.ts.\n * Any change here MUST be reflected there, and vice versa.\n *\n * 1. DNT/GPC respect: when config.respectDnt !== false (default true) AND\n * (navigator.doNotTrack === '1' OR navigator.globalPrivacyControl === true),\n * all methods become no-ops. Zero network requests are made.\n *\n * 2. Prerender skip: when document.prerendering === true OR\n * document.visibilityState === 'prerender', pageview() sends zero requests.\n *\n * 3. 500ms same-path dedup: a pageview for the same pathname within 500ms of\n * the previous send is silently dropped. After 500ms the next call sends.\n *\n * 4. Transport: sendBeacon → fetch keepalive fallback.\n * Primary: navigator.sendBeacon(endpoint, new Blob([json], { type: 'text/plain' })).\n * Fallback (sendBeacon unavailable OR returns false):\n * fetch(endpoint, { method: 'POST', keepalive: true,\n * headers: { 'Content-Type': 'application/json' }, body: json }).catch(() => {})\n *\n * 5. Body-only publishableKey: publishableKey is always in the request body,\n * never in any HTTP header.\n *\n * 6. SSR no-op: when typeof window === 'undefined', createAnalytics() returns\n * a stub where all methods are no-ops. No side effects occur.\n *\n * 7. Error swallowing: all transport errors are caught and swallowed.\n * createAnalytics() and all returned methods never throw into the caller.\n *\n * 8. Client timestamp: every send carries eventTs (milliseconds since epoch)\n * captured with Date.now() immediately before transport. The collect\n * endpoint uses eventTs (a) to bucket the event into the client's\n * tenant-local day and (b) to enforce the late-arrival cutoff; events\n * submitted after the local-day-end grace window are dropped with\n * reason \"late\".\n * ANALYTICS INVARIANTS END */\n\nimport { resolveApiUrl } from './core/client/types'\n\n// ============================================================================\n// Public Types\n// ============================================================================\n\nexport interface AnalyticsConfig {\n publishableKey: string\n /** Override the collect endpoint URL. Defaults to {SDK_BASE_URL}/api/analytics/collect */\n endpoint?: string\n /** Auto-patch history.pushState/replaceState and listen to popstate. Default: true */\n autoTrack?: boolean\n /** Respect navigator.doNotTrack and navigator.globalPrivacyControl. Default: true */\n respectDnt?: boolean\n}\n\nexport interface Analytics {\n pageview(path?: string): void\n track(name: string, props?: Record<string, string | number | boolean>): void\n destroy(): void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport function createAnalytics(config: AnalyticsConfig): Analytics {\n // INVARIANT 6: SSR no-op\n if (typeof window === 'undefined') {\n return { pageview() {}, track() {}, destroy() {} }\n }\n\n const endpoint =\n config.endpoint ?? `${resolveApiUrl()}/api/analytics/collect`\n\n // INVARIANT 1: DNT/GPC check (evaluated once at init; stays as closure)\n const respectDnt = config.respectDnt !== false\n function isDntActive(): boolean {\n if (!respectDnt) return false\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean }\n return nav.doNotTrack === '1' || nav.globalPrivacyControl === true\n }\n\n // INVARIANT 3: 500ms same-path dedup state\n let lastPath: string | null = null\n let lastAt = 0\n\n // autoTrack state — save originals for destroy()\n const autoTrack = config.autoTrack !== false\n const originalPushState = history.pushState\n const originalReplaceState = history.replaceState\n let destroyed = false\n\n // -------------------------------------------------------------------------\n // Core send logic\n // -------------------------------------------------------------------------\n\n // Generate a unique event ID (crypto.randomUUID when available, Date+Math.random fallback)\n function newEventId(): string {\n return typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : String(Date.now()) + String(Math.random())\n }\n\n // INVARIANT 4: sendBeacon → fetch keepalive fallback\n // INVARIANT 5: publishableKey in body only\n function sendBeaconOrFetch(body: string): void {\n try {\n if (typeof navigator.sendBeacon === 'function') {\n const blob = new Blob([body], { type: 'text/plain' })\n const sent = navigator.sendBeacon(endpoint, blob)\n if (sent) return\n // sent === false → fall through to fetch\n }\n // Fetch fallback\n fetch(endpoint, {\n method: 'POST',\n keepalive: true,\n headers: { 'Content-Type': 'application/json' },\n body,\n }).catch(() => {})\n } catch {\n // INVARIANT 7: swallow all errors\n }\n }\n\n function sendPageview(pathname: string): void {\n // INVARIANT 1: DNT/GPC\n if (isDntActive()) return\n\n // INVARIANT 2: prerender skip\n const doc = document as Document & { prerendering?: boolean }\n // visibilityState cast to string to accommodate non-standard 'prerender' value\n if (doc.prerendering === true || (document.visibilityState as string) === 'prerender') return\n\n // INVARIANT 3: 500ms same-path dedup\n const now = Date.now()\n if (pathname === lastPath && now - lastAt < 500) return\n lastPath = pathname\n lastAt = now\n\n const body = JSON.stringify({\n publishableKey: config.publishableKey,\n pathname,\n referrer: document.referrer || '',\n eventId: newEventId(),\n eventTs: Date.now(),\n })\n\n sendBeaconOrFetch(body)\n }\n\n // -------------------------------------------------------------------------\n // autoTrack: patch history methods + listen to popstate\n // -------------------------------------------------------------------------\n function trackCurrentPath(): void {\n if (destroyed) return\n sendPageview(location.pathname)\n }\n\n function patchedPushState(\n this: History,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n originalPushState.apply(this, [data, unused, url] as Parameters<typeof history.pushState>)\n if (!destroyed) setTimeout(trackCurrentPath, 0)\n }\n\n function patchedReplaceState(\n this: History,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n originalReplaceState.apply(this, [data, unused, url] as Parameters<typeof history.replaceState>)\n if (!destroyed) setTimeout(trackCurrentPath, 0)\n }\n\n if (autoTrack) {\n history.pushState = patchedPushState\n history.replaceState = patchedReplaceState\n window.addEventListener('popstate', trackCurrentPath)\n\n // Initial pageview\n if (document.readyState === 'complete') {\n trackCurrentPath()\n } else {\n window.addEventListener('load', trackCurrentPath, { once: true })\n }\n }\n\n // -------------------------------------------------------------------------\n // track() — client-side validation + send\n // -------------------------------------------------------------------------\n\n // Dev-mode detection: warn in dev, silent in production.\n // process.env.NODE_ENV is unreliable in browser bundles (tsup does not replace it\n // by default). Instead we detect production at runtime via hostname heuristics.\n // SSR (window undefined) is caught at the top of createAnalytics and returns a\n // stub, so window is always defined here.\n const isProduction: boolean = (() => {\n try {\n const hostname = location.hostname\n return (\n hostname !== 'localhost' &&\n hostname !== '127.0.0.1' &&\n !hostname.endsWith('.local')\n )\n } catch {\n // hostname access failed (non-browser) — default to silent\n return true\n }\n })()\n\n // One-shot warn dedup per reason per page load (keyed by reason only)\n const warnedReasons = new Set<string>()\n\n function devWarn(name: string, reason: string): void {\n if (isProduction) return\n if (warnedReasons.has(reason)) return\n warnedReasons.add(reason)\n console.warn(`[01 analytics] dropped event ${name}: ${reason}`)\n }\n\n const EVENT_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_:-]{0,49}$/\n const RESERVED_PREFIXES = ['__', '_pv_']\n\n function validateEventName(name: string): string | null {\n if (!name || typeof name !== 'string') return 'name-empty'\n for (const prefix of RESERVED_PREFIXES) {\n if (name.startsWith(prefix)) return 'name-reserved'\n }\n if (!EVENT_NAME_RE.test(name)) return 'name-regex'\n return null\n }\n\n const PROP_KEY_RE = /^[a-zA-Z_][a-zA-Z0-9_]{0,31}$/\n\n function validateEventProps(\n props: Record<string, string | number | boolean> | undefined,\n ): string | null {\n if (props === undefined || props === null) return null\n if (typeof props !== 'object' || Array.isArray(props)) return 'props-value-type'\n const keys = Object.keys(props)\n if (keys.length > 10) return 'props-too-many-keys'\n for (const k of keys) {\n const v = props[k]\n if (!PROP_KEY_RE.test(k)) return 'props-key-regex'\n if (typeof v === 'string') {\n if (v.length > 80) return 'props-value-too-long'\n } else if (typeof v === 'number') {\n if (!isFinite(v)) return 'props-value-not-finite'\n } else if (typeof v === 'boolean') {\n // ok\n } else {\n return 'props-value-type'\n }\n }\n return null\n }\n\n // -------------------------------------------------------------------------\n // Public API\n // -------------------------------------------------------------------------\n return {\n pageview(path?: string): void {\n if (destroyed) return\n sendPageview(path ?? location.pathname)\n },\n\n track(name: string, props?: Record<string, string | number | boolean>): void {\n if (destroyed) return\n\n // INVARIANT 1: DNT/GPC (same as pageview)\n if (isDntActive()) return\n\n // INVARIANT 2: prerender skip\n const doc = document as Document & { prerendering?: boolean }\n if (doc.prerendering === true || (document.visibilityState as string) === 'prerender') return\n\n // Client-side validation\n const nameErr = validateEventName(name)\n if (nameErr) {\n devWarn(name, nameErr)\n return\n }\n\n if (props !== undefined) {\n const propsErr = validateEventProps(props)\n if (propsErr) {\n devWarn(name, propsErr)\n return\n }\n }\n\n // Build body — no dedup for track() events\n const body = JSON.stringify({\n publishableKey: config.publishableKey,\n pathname: location.pathname,\n referrer: document.referrer || '',\n eventId: newEventId(),\n eventName: name,\n eventProps: props,\n eventTs: Date.now(),\n })\n\n sendBeaconOrFetch(body)\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n\n if (autoTrack) {\n // Restore original history methods\n history.pushState = originalPushState\n history.replaceState = originalReplaceState\n window.removeEventListener('popstate', trackCurrentPath)\n }\n\n // Null out dedup state\n lastPath = null\n lastAt = 0\n },\n }\n}\n","import type {\n ClientConfig,\n RootClientWithEvents,\n} from './core/client/types'\nimport { createClient as createClientInternal } from './core/client/client'\n\n// Public domain types\nexport type {\n Article,\n ArticleAuthor,\n ArticleCategory,\n ArticleTag,\n Image,\n Post,\n PostCategory,\n Video,\n ProductVariant,\n Order,\n Cart,\n CartItem,\n Tenant,\n Document,\n} from './payload-types'\n\n// Core browser-safe SDK\nexport function createClient(options: ClientConfig): RootClientWithEvents {\n return createClientInternal(options) as RootClientWithEvents\n}\n\nexport type {\n ApiQueryOptions,\n ClientConfig,\n ClientMetadata,\n ClientState,\n Collection,\n DebugConfig,\n DeepPartial,\n ExtractArrayType,\n PayloadFindResponse,\n PayloadMutationResponse,\n PublicCollection,\n RootCollectionClient,\n RootClient as Client,\n RootClient as ClientType,\n RootClient,\n RootClientWithEvents,\n RootReadOnlyQueryBuilder,\n RetryConfig,\n Sort,\n Where,\n} from './core/client/types'\nexport type {\n CollectionType,\n PublicProduct as Product,\n PublicProductCollection as ProductCollection,\n} from './core/collection/types'\nexport * from './core/api'\nexport { CommerceClient } from './core/commerce/commerce-client'\nexport type { CommerceClientOptions } from './core/commerce/commerce-client'\nexport {\n mergeProductDetailWithStock,\n type MergedProductDetailResult,\n type ProductDetailStockMergeStatus,\n} from './core/commerce/merge-catalog-stock'\nexport { CommunityClient } from './core/community/community-client'\nexport type {\n CommunityClientOptions,\n CommunityComment,\n CommunityCommentListSort,\n CommunityPost,\n CommunityPostCategory,\n CommunityPostListSort,\n CommunityPostTag,\n Comment,\n} from './core/community/community-client'\nexport { EventsClient } from './core/events/events-client'\nexport type {\n EventGuestCancelParams,\n EventGuestRegistration,\n EventGuestRegistrationResponse,\n EventRegistrationAnswerInput,\n EventRegistrationAttendeeInput,\n EventRegistrationPublic,\n EventRegistrationRegisterParams,\n EventRegistrationRegisterResponse,\n EventsCalendarItem,\n EventsClientOptions,\n EventsDateParam,\n EventsExternalSource,\n EventsLocation,\n EventsOccurrenceLocation,\n EventsRangeEvent,\n EventsRangeOccurrence,\n EventsRangeParams,\n EventsRangeResponse,\n EventsTaxonomyItem,\n} from './core/events/events-client'\nexport * from './core/customer'\nexport * from './core/webhook'\nexport {\n COLLECTIONS,\n INTERNAL_COLLECTIONS,\n SERVER_COLLECTIONS,\n SERVER_ONLY_COLLECTIONS,\n} from './core/collection/const'\nexport { RealtimeConnection, type RealtimeEvent, type RealtimeListener } from './core/query/realtime'\n\n// Utils\nexport * from './utils'\n\n// Analytics\nexport { createAnalytics } from './analytics'\nexport type { Analytics, AnalyticsConfig } from './analytics'\n\n// Errors\nexport {\n SDKError,\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 isSDKError,\n isNetworkError,\n isValidationError,\n isApiError,\n isConfigError,\n isTimeoutError,\n isGoneError,\n isServiceUnavailableError,\n isUsageLimitError,\n isAuthError,\n isPermissionError,\n isNotFoundError,\n isConflictError,\n isRateLimitError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from './errors'\n"],"mappings":"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","names":["method","DEFAULT_TIMEOUT","isRecord","delay","mediaId","mediaArray","item","buildPoolById","createClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/collection/http-client.ts","../src/core/errors.ts","../src/core/internal/utils/credentials.ts","../src/core/client/types.ts","../src/core/internal/utils/http.ts","../src/core/internal/utils/query-string.ts","../src/utils/types.ts","../src/core/metadata/index.ts","../src/core/collection/query-builder.ts","../src/core/collection/collection-client.ts","../src/core/api/parse-response.ts","../src/core/api/customer-scoped-api.ts","../src/core/community/community-client.ts","../src/core/customer/customer-auth.ts","../src/core/customer/customer-namespace.ts","../src/core/api/cart-api.ts","../src/core/api/base-api.ts","../src/core/api/product-api.ts","../src/core/api/order-api.ts","../src/core/commerce/commerce-client.ts","../src/core/events/events-client.ts","../src/core/client/client.ts","../src/core/api/discount-api.ts","../src/core/api/shipping-api.ts","../src/core/commerce/merge-catalog-stock.ts","../src/core/webhook/index.ts","../src/core/collection/const.ts","../src/core/query/realtime.ts","../src/utils/product-selection-media.ts","../src/utils/ecommerce.ts","../src/utils/product-media.ts","../src/utils/product-gallery.ts","../src/utils/image.ts","../src/utils/order/generateOrderNumber.ts","../src/utils/order/formatOrderName.ts","../src/utils/video.ts","../src/analytics.ts","../src/index.ts"],"sourcesContent":["import { stringify } from 'qs-esm'\nimport {\n httpFetch,\n requirePublishableKeyForSecret,\n type FetchOptions,\n} from '../internal/utils'\nimport type {\n ApiQueryOptions,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { SDKError, createApiError } from '../internal/errors'\n\nexport class HttpClient {\n protected publishableKey: string\n protected secretKey?: string\n private getCustomerToken?: () => string | null\n private onUnauthorized?: () => Promise<string | null>\n private onRequestId?: (id: string | null) => void\n private apiUrl?: string\n\n constructor(\n publishableKey: string,\n secretKey?: string,\n getCustomerToken?: () => string | null,\n onUnauthorized?: () => Promise<string | null>,\n onRequestId?: (id: string | null) => void,\n apiUrl?: string,\n ) {\n this.publishableKey = requirePublishableKeyForSecret(\n 'CollectionClient',\n publishableKey,\n secretKey,\n )\n this.secretKey = secretKey\n this.getCustomerToken = getCustomerToken\n this.onUnauthorized = onUnauthorized\n this.onRequestId = onRequestId\n this.apiUrl = apiUrl\n }\n\n protected get defaultOptions(): FetchOptions {\n const opts: FetchOptions = {\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n }\n const token = this.getCustomerToken?.()\n if (token) {\n opts.customerToken = token\n if (this.onUnauthorized) {\n opts.onUnauthorized = this.onUnauthorized\n }\n }\n return opts\n }\n\n protected async fetchWithTracking(url: string, opts: FetchOptions): Promise<Response> {\n try {\n const response = await httpFetch(url, opts)\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return response\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n\n protected buildUrl(endpoint: string, options?: ApiQueryOptions): string {\n if (!options) return endpoint\n const queryString = stringify(options, { addQueryPrefix: true })\n return queryString ? `${endpoint}${queryString}` : endpoint\n }\n\n protected assertJsonResponse(response: Response): void {\n const contentType = response.headers.get('content-type')\n if (!contentType?.includes('application/json')) {\n throw createApiError('Response is not in JSON format.', response.status, {\n contentType,\n })\n }\n }\n\n /**\n * Parse Payload CMS find response (list query)\n * Returns native Payload response structure\n */\n protected async parseFindResponse<T>(\n response: Response,\n ): Promise<PayloadFindResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a find response\n if (jsonData.docs === undefined) {\n throw createApiError('Invalid find response.', response.status, {\n jsonData,\n })\n }\n\n return {\n docs: jsonData.docs,\n totalDocs: jsonData.totalDocs ?? 0,\n limit: jsonData.limit || 20,\n totalPages: jsonData.totalPages ?? 0,\n page: jsonData.page || 1,\n pagingCounter: jsonData.pagingCounter || 1,\n hasPrevPage: jsonData.hasPrevPage ?? false,\n hasNextPage: jsonData.hasNextPage ?? false,\n prevPage: jsonData.prevPage ?? null,\n nextPage: jsonData.nextPage ?? null,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS mutation response (create/update)\n * Returns native Payload response structure\n */\n protected async parseMutationResponse<T>(\n response: Response,\n ): Promise<PayloadMutationResponse<T>> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n\n // Validate it's a mutation response\n if (jsonData.doc === undefined) {\n throw createApiError('Invalid mutation response.', response.status, {\n jsonData,\n })\n }\n\n return {\n message: jsonData.message || '',\n doc: jsonData.doc,\n errors: jsonData.errors,\n }\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n\n /**\n * Parse Payload CMS document response (findById/delete)\n * Returns document directly without wrapper\n */\n protected async parseDocumentResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n try {\n this.assertJsonResponse(response)\n\n const jsonData = await response.json()\n return jsonData as T\n } catch (error) {\n if (error instanceof SDKError) throw error\n throw createApiError('Failed to parse response.', response.status, {\n contentType,\n error: error instanceof Error ? error.message : error,\n })\n }\n }\n}\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\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 }\n }\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 return error instanceof ValidationError\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 { createConfigError } from '../errors'\n\nexport function requirePublishableKeyForSecret(\n apiName: string,\n publishableKey: string | undefined,\n secretKey: string | undefined,\n): string {\n if (secretKey && !publishableKey) {\n throw createConfigError(\n `publishableKey is required for ${apiName} when secretKey is used. ` +\n 'It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.',\n )\n }\n\n return publishableKey ?? ''\n}\n","import type {\n Collection,\n PublicCollection,\n ServerCollection,\n ServerOnlyCollection,\n} from '../collection/const'\nimport type { CollectionType } from '../collection/types'\nimport type { CommunityClient } from '../community/community-client'\nimport type {\n BanCustomerParams,\n CommunityBan,\n UnbanCustomerParams,\n} from '../community/moderation-api'\nimport type { CommerceClient } from '../commerce/commerce-client'\nimport type { ServerCommerceClient } from '../commerce/server-commerce-client'\nimport type { CustomerNamespace } from '../customer/customer-namespace'\nimport type { EventsClient } from '../events/events-client'\nimport type { TenantIntrospectionClient } from '../api/tenant-introspection-api'\n\nexport type {\n Collection,\n PublicCollection,\n ServerCollection,\n ServerOnlyCollection,\n}\n\n// ============================================================================\n// API URL Configuration\n// ============================================================================\n\ndeclare const __DEFAULT_API_URL__: string\n\nexport function resolveApiUrl(apiUrl?: string): string {\n if (apiUrl) {\n return apiUrl.replace(/\\/$/, '')\n }\n\n if (typeof process !== 'undefined' && process.env) {\n const envUrl =\n process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL\n if (envUrl) {\n return envUrl.replace(/\\/$/, '')\n }\n }\n return __DEFAULT_API_URL__\n}\n\n// ============================================================================\n// Client Configuration\n// ============================================================================\n\nexport interface ClientConfig {\n publishableKey: string\n /** API base URL for staging, self-hosted, preview, or proxy deployments. */\n apiUrl?: string\n /**\n * Customer authentication options.\n * Used to initialize CustomerAuth on Client.\n */\n customer?: {\n /**\n * Persist token in localStorage. Defaults to `true`.\n * - `true` (default): uses key `'customer-token'`\n * - `string`: uses the given string as localStorage key\n * - `false`: disables persistence (token/onTokenChange used instead)\n *\n * Handles SSR safely (no-op on server).\n * When enabled, `token` and `onTokenChange` are ignored.\n */\n persist?: boolean | string\n /** Initial token (e.g. from SSR cookie) */\n token?: string\n /** Called when token changes (login/logout) — use to persist in localStorage/cookie */\n onTokenChange?: (token: string | null) => void\n }\n}\n\n// Server client: requires both publishableKey (for CDN routing + rate limit +\n// monthly quota enforcement via the edge proxy) and secretKey (sk01_ opaque\n// bearer token, the authentication credential).\n// The proxy keys its tenant lookup off `X-Publishable-Key`, so omitting\n// publishableKey would silently bypass rate limiting and plan-based quota\n// enforcement.\nexport interface ClientServerConfig extends ClientConfig {\n secretKey: string\n}\n\nexport interface ClientMetadata {\n userAgent?: string\n timestamp: number\n}\n\nexport interface ClientState {\n metadata: ClientMetadata\n}\n\nexport interface PaginationMeta {\n page: number\n limit: number\n totalDocs: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n pagingCounter: number\n prevPage: number | null\n nextPage: number | null\n}\n\n// ============================================================================\n// Payload CMS Native Response Types\n// ============================================================================\n\n/**\n * Payload CMS Find (List) Response\n * GET /api/{collection}\n */\nexport interface PayloadFindResponse<T = unknown> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\n/**\n * Payload CMS Create/Update Response\n * POST /api/{collection}\n * PATCH /api/{collection}/{id}\n */\nexport interface PayloadMutationResponse<T = unknown> {\n message: string\n doc: T\n errors?: unknown[]\n}\n\n// ============================================================================\n// Query Options\n// ============================================================================\n\nexport type Sort = string | string[]\nexport type Where = Record<string, unknown>\n\n/**\n * Do NOT replace with `Pick<FindOptions>` from `payload` or import Payload\n * types here. Payload's generic query types depend on `PayloadTypes` module\n * augmentation; external SDK consumers who only use `createClient` should not\n * install Payload just to type REST query objects. Excluded vs native:\n * Local-API-only fields, `locale`/`fallbackLocale`.\n */\nexport interface ApiQueryOptions {\n page?: number\n limit?: number\n sort?: Sort\n /**\n * Filter documents. Id-based relation filters (`where: { product: { equals: id } }`) are the\n * most reliable pattern. Dotted-path relation filters (`where: { 'product.slug': { equals } }`)\n * are Payload-native but may silently return empty when access control restricts the related\n * document or when the relation is polymorphic. String shorthand (`where: { slug: 'x' }`)\n * silently matches nothing — always use `{ slug: { equals: 'x' } }`.\n */\n where?: Where\n /**\n * Controls how deeply relationship fields are populated. This is the primary control for\n * populating relationships like `category`, `images`, `brand`. The configured Payload default\n * applies when unset.\n */\n depth?: number\n select?: Record<string, boolean>\n /**\n * Controls which fields are returned for already-populated relationships, keyed by collection\n * slug. Does NOT control which relationships to populate — that is `depth`.\n *\n * @example\n * // depth: 2 populates category; populate trims which fields come back\n * populate: { categories: { title: true, slug: true } }\n */\n populate?: Record<string, boolean | Record<string, boolean>>\n /**\n * Controls Payload `type: 'join'` virtual reverse-relation fields only (pagination, sort,\n * filter, count per join field, or `false` to disable all join-field population).\n *\n * Does NOT populate normal relationship fields like `category`, `images`, or `brand`.\n * For normal relationship population use `depth` (and optionally `populate` for field\n * selection).\n *\n * Pass `joins: false` to disable all join-field population — useful for lightweight list\n * queries where join fields are not needed.\n *\n * @example\n * // `article-authors` has a `type: 'join'` field `articles` (reverse-relation)\n * joins: { articles: { limit: 10, sort: '-publishedAt' } }\n *\n * // depth: 2 populates product.category — joins has no effect on this\n * depth: 2\n *\n * // Disable all join-field population\n * joins: false\n */\n joins?:\n | Record<\n string,\n | {\n limit?: number\n page?: number\n sort?: string\n where?: Where\n count?: boolean\n }\n | false\n >\n | false\n /** Set to `false` to skip the count query — returns docs without totalDocs/totalPages */\n pagination?: boolean\n /** Include draft versions (access control still applies on the server) */\n draft?: boolean\n /** Include soft-deleted documents (requires `trash` enabled on the collection) */\n trash?: boolean\n}\n\n// ============================================================================\n// Debug & Retry Configuration\n// ============================================================================\n\nexport interface DebugConfig {\n logRequests?: boolean\n logResponses?: boolean\n logErrors?: boolean\n}\n\nexport interface RetryConfig {\n maxRetries?: number\n retryableStatuses?: number[]\n retryDelay?: (attempt: number) => number\n}\n\n// ============================================================================\n// Lightweight root entry contracts\n// ============================================================================\n\ninterface RootQueryLookup<T extends string> {\n find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>>\n count(options?: ApiQueryOptions): Promise<{ totalDocs: number }>\n}\n\nexport type RootReadOnlyQueryBuilder<T extends PublicCollection> =\n RootQueryLookup<T>\n\nexport interface RootServerQueryBuilder<\n T extends ServerCollection,\n> extends RootQueryLookup<T> {\n create(\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>>\n update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>>\n updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n remove(id: string): Promise<CollectionType<T>>\n removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>>\n}\n\nexport interface RootCollectionClient {\n from<T extends PublicCollection>(collection: T): RootReadOnlyQueryBuilder<T>\n}\n\nexport interface RootServerCollectionClient {\n from<T extends ServerCollection>(collection: T): RootServerQueryBuilder<T>\n}\n\nexport interface RootClient {\n commerce: CommerceClient\n community: CommunityClient\n /** Set on {@link createClient} return values; optional for structural mocks. */\n events?: EventsClient\n customer: CustomerNamespace\n collections: RootCollectionClient\n lastRequestId: string | null\n getState(): ClientState\n getConfig(): ClientConfig\n}\n\nexport interface RootServerClient {\n commerce: ServerCommerceClient\n tenant: TenantIntrospectionClient\n /** Set on {@link createServerClient} return values; optional for structural mocks. */\n events?: EventsClient\n community: CommunityClient & {\n moderation: {\n banCustomer: (p: BanCustomerParams) => Promise<CommunityBan>\n unbanCustomer: (p: UnbanCustomerParams) => Promise<{ success: true }>\n }\n }\n collections: RootServerCollectionClient\n lastRequestId: string | null\n getState(): ClientState\n getConfig(): Omit<ClientServerConfig, 'secretKey'>\n}\n\nexport type RootClientWithEvents = RootClient & { events: EventsClient }\n\nexport type RootServerClientWithEvents = RootServerClient & { events: EventsClient }\n\n// ============================================================================\n// Type Utilities\n// ============================================================================\n\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]\n}\n\nexport type ExtractArrayType<T> = T extends (infer U)[] ? U : never\n","import {\n createAuthError,\n createConflictError,\n createNetworkError,\n createNotFoundError,\n createPermissionError,\n createValidationError,\n createUsageLimitError,\n createTimeoutError,\n TimeoutError,\n NetworkError,\n SDKError,\n} from '../errors'\nimport type { DebugConfig, RetryConfig } from '../../client/types'\nimport { resolveApiUrl } from '../../client/types'\nconst DEFAULT_TIMEOUT = 30000\nconst STOREFRONT_BROWSER_TIMEOUT = 15_000\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504]\nconst NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422]\nconst SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']\nconst DEFAULT_MAX_RETRIES = 3\nconst STOREFRONT_BROWSER_MAX_RETRIES = 1\n\nexport interface FetchOptions extends RequestInit {\n apiUrl?: string\n publishableKey?: string\n secretKey?: string\n customerToken?: string\n timeout?: number\n debug?: boolean | DebugConfig\n retry?: RetryConfig\n /** Called on 401 when customerToken is set and reason=token_expired. Return a new token to retry, or null to fail. */\n onUnauthorized?: () => Promise<string | null>\n}\n\nfunction debugLog(\n debug: boolean | DebugConfig | undefined,\n type: 'request' | 'response' | 'error',\n message: string,\n data?: unknown,\n) {\n if (!debug) return\n\n const shouldLog =\n debug === true ||\n (type === 'request' && (debug as DebugConfig).logRequests) ||\n (type === 'response' && (debug as DebugConfig).logResponses) ||\n (type === 'error' && (debug as DebugConfig).logErrors)\n\n if (shouldLog) {\n console.group(`[SDK ${type.toUpperCase()}] ${message}`)\n if (data) console.log(data)\n console.groupEnd()\n }\n}\n\nfunction redactSensitiveHeader(value: string): string {\n const prefix = value.toLowerCase().startsWith('bearer ') ? 'Bearer ' : ''\n return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : '****'\n}\n\nfunction redactSensitiveHeaders(headers: Headers): Record<string, string> {\n const redacted = Object.fromEntries(headers.entries())\n if (redacted.authorization) {\n redacted.authorization = redactSensitiveHeader(redacted.authorization)\n }\n if (redacted['x-preview-token']) {\n redacted['x-preview-token'] = redactSensitiveHeader(\n redacted['x-preview-token'],\n )\n }\n return redacted\n}\n\nfunction getErrorSuggestion(status: number): string | undefined {\n if (status === 400)\n return 'The request data failed validation. Check field values and types.'\n if (status === 401) return 'Please check your authentication credentials.'\n if (status === 403)\n return 'Access denied. Check your credentials or permissions.'\n if (status === 404) return 'The requested resource was not found.'\n if (status === 422) return 'The request data failed validation.'\n if (status >= 500) return 'A server error occurred. Please try again later.'\n return undefined\n}\n\nfunction isUsageLimitExceededResponse(response: Response): boolean {\n if (response.status !== 429) return false\n\n const limit = parseInt(response.headers.get('X-Usage-Limit') || '', 10)\n const current = parseInt(response.headers.get('X-Usage-Current') || '', 10)\n if (!Number.isFinite(limit) || !Number.isFinite(current)) return false\n\n return response.headers.get('X-Usage-Exceeded') === 'true' || current > limit\n}\n\n/**\n * Parse error details from HTTP response body.\n * Supports Payload native format:\n * - ValidationError: { errors: [{ message, data: { errors: [{ path, message }] } }] }\n * - Simple: { errors: [{ message, field? }] }\n * Also supports custom endpoint format ({ error: string, reason?: string, message?: string }).\n */\nasync function parseErrorBody(response: Response): Promise<{\n errorMessage: string\n userMessage: string\n reason?: string\n body?: Record<string, unknown>\n errors?: Array<{ message?: string; field?: string }>\n}> {\n const fallback = {\n errorMessage: `HTTP ${response.status}: ${response.statusText}`,\n userMessage: `Request failed (status: ${response.status})`,\n }\n\n try {\n const body = await response.json()\n const reason: string | undefined =\n typeof body.reason === 'string'\n ? body.reason\n : typeof body.code === 'string'\n ? body.code\n : undefined\n\n // Payload native: { errors: [{ message, field?, data? }] }\n if (body.errors && Array.isArray(body.errors)) {\n // Extract nested ValidationError field details\n // Payload ValidationError format: errors[].data.errors[].{path, message}\n const fieldErrors: Array<{ message?: string; field?: string }> = []\n for (const e of body.errors) {\n if (\n e.data?.errors &&\n Array.isArray(e.data.errors) &&\n e.data.errors.length > 0\n ) {\n for (const fe of e.data.errors) {\n fieldErrors.push({\n field: fe.path || fe.field,\n message: fe.message,\n })\n }\n } else if (e.field || e.message) {\n fieldErrors.push({ field: e.field, message: e.message })\n }\n }\n\n const details = (fieldErrors.length > 0 ? fieldErrors : body.errors)\n .map((e: { message?: string; field?: string }) =>\n e.field ? `${e.field}: ${e.message}` : e.message,\n )\n .filter(Boolean)\n .join('; ')\n if (details) {\n return {\n errorMessage: `HTTP ${response.status}: ${details}`,\n userMessage: details,\n reason,\n body,\n errors: fieldErrors.length > 0 ? fieldErrors : body.errors,\n }\n }\n }\n\n // Custom endpoint: { error: string, reason?: string, details?: { fieldErrors? } }\n if (typeof body.error === 'string') {\n return {\n errorMessage: `HTTP ${response.status}: ${body.error}`,\n userMessage: body.error,\n reason,\n body,\n }\n }\n\n // Fallback: { message: string }\n if (body.message) {\n return {\n errorMessage: `HTTP ${response.status}: ${body.message}`,\n userMessage: body.message,\n reason,\n body,\n }\n }\n\n return { ...fallback, reason, body }\n } catch {\n return fallback\n }\n}\n\nfunction getParsedErrorSuggestion(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n): string | undefined {\n if (status === 403 && parsed.reason === 'origin_not_allowed') {\n return 'Add the request origin to the tenant Browser API origins, then retry the browser request.'\n }\n\n return getErrorSuggestion(status)\n}\n\nasync function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// Attach requestId to any SDKError instance (readonly bypass is intentional — internal transport layer only)\nexport function attachRequestId<T extends SDKError>(\n err: T,\n id: string | undefined,\n): T {\n if (id) (err as Record<string, unknown>).requestId = id\n return err\n}\n\nfunction createHttpStatusError(\n status: number,\n parsed: Awaited<ReturnType<typeof parseErrorBody>>,\n details: Record<string, unknown>,\n requestId: string | undefined,\n): SDKError {\n const errorDetails = {\n ...details,\n ...(parsed.errors && { errors: parsed.errors }),\n ...(parsed.body && { body: parsed.body }),\n }\n const suggestion = getParsedErrorSuggestion(status, parsed)\n\n if (status === 400 || status === 422) {\n return attachRequestId(\n createValidationError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n status,\n ),\n requestId,\n )\n }\n\n if (status === 401) {\n return attachRequestId(\n createAuthError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 403) {\n return attachRequestId(\n createPermissionError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 404) {\n return attachRequestId(\n createNotFoundError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n if (status === 409) {\n return attachRequestId(\n createConflictError(\n parsed.errorMessage,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n }\n\n return attachRequestId(\n createNetworkError(\n parsed.errorMessage,\n status,\n errorDetails,\n parsed.userMessage,\n suggestion,\n ),\n requestId,\n )\n}\n\nexport async function httpFetch(\n url: string,\n options?: FetchOptions,\n): Promise<Response> {\n const {\n apiUrl,\n publishableKey,\n secretKey,\n customerToken,\n timeout: timeoutOption = DEFAULT_TIMEOUT,\n debug,\n retry,\n onUnauthorized,\n ...requestInit\n } = options || {}\n\n const baseUrl = resolveApiUrl(apiUrl)\n const method = (requestInit.method || 'GET').toUpperCase()\n const isPublishableKeyBrowserGet =\n typeof window !== 'undefined' &&\n !secretKey &&\n !customerToken &&\n Boolean(publishableKey) &&\n SAFE_METHODS.includes(method)\n\n const timeout =\n timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_TIMEOUT\n : timeoutOption\n\n const retryConfig = {\n maxRetries:\n retry?.maxRetries ??\n (isPublishableKeyBrowserGet\n ? STOREFRONT_BROWSER_MAX_RETRIES\n : DEFAULT_MAX_RETRIES),\n retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,\n retryDelay:\n retry?.retryDelay ??\n ((attempt: number) => Math.min(1000 * 2 ** attempt, 10000)),\n }\n\n // Server auth: secretKey is now the raw opaque bearer token (sk01_...).\n // Customer auth: customerToken is a JWT.\n let authToken: string | undefined\n if (secretKey) {\n authToken = secretKey\n } else if (customerToken) {\n authToken = customerToken\n }\n\n let lastError: Error | undefined\n let hasRetried401 = false\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n const headers = new Headers(requestInit.headers)\n\n if (publishableKey) {\n headers.set('X-Publishable-Key', publishableKey)\n }\n\n if (authToken) {\n headers.set('Authorization', `Bearer ${authToken}`)\n }\n\n if (\n !headers.has('Content-Type') &&\n requestInit.body &&\n !(requestInit.body instanceof FormData)\n ) {\n headers.set('Content-Type', 'application/json')\n }\n\n // Redact sensitive headers for debug logging\n const redactedHeaders = redactSensitiveHeaders(headers)\n\n debugLog(debug, 'request', url, {\n method: requestInit.method || 'GET',\n headers: redactedHeaders,\n attempt: attempt + 1,\n })\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const response = await fetch(`${baseUrl}${url}`, {\n ...requestInit,\n headers,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n const requestId = response.headers.get('x-request-id') ?? undefined\n\n debugLog(debug, 'response', url, {\n status: response.status,\n statusText: response.statusText,\n headers: redactSensitiveHeaders(response.headers),\n })\n\n if (!response.ok) {\n // Usage limit 429 — never retry. Older servers identify this when\n // current usage is above the limit; newer servers also send\n // X-Usage-Exceeded to avoid confusing other 429s with quota exhaustion.\n if (isUsageLimitExceededResponse(response)) {\n const limit = parseInt(\n response.headers.get('X-Usage-Limit') || '0',\n 10,\n )\n const current = parseInt(\n response.headers.get('X-Usage-Current') || '0',\n 10,\n )\n const remaining = parseInt(\n response.headers.get('X-Usage-Remaining') || '0',\n 10,\n )\n\n throw attachRequestId(\n createUsageLimitError(\n `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,\n { limit, current, remaining },\n {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n },\n 'Monthly API call limit exceeded. Please upgrade your plan.',\n 'Upgrade your tenant plan to increase the monthly API call limit.',\n ),\n requestId,\n )\n }\n\n // Parse body once — captures reason field for 401 branching and error details\n const parsed = await parseErrorBody(response)\n\n // Auto-refresh customer token on 401 — only when reason=token_expired\n if (\n response.status === 401 &&\n onUnauthorized &&\n customerToken &&\n !hasRetried401 &&\n parsed.reason === 'token_expired'\n ) {\n hasRetried401 = true\n try {\n const newToken = await onUnauthorized()\n if (newToken) {\n authToken = newToken\n continue\n }\n } catch {\n // Refresh failed, fall through to throw\n }\n }\n\n const details = {\n url,\n method: requestInit.method || 'GET',\n attempt: attempt + 1,\n }\n\n // Never retry non-retryable statuses regardless of user config\n if (NON_RETRYABLE_STATUSES.includes(response.status)) {\n throw createHttpStatusError(\n response.status,\n parsed,\n details,\n requestId,\n )\n }\n\n // Retryable errors\n const error = attachRequestId(\n createNetworkError(\n parsed.errorMessage,\n response.status,\n details,\n parsed.userMessage,\n getErrorSuggestion(response.status),\n ),\n requestId,\n )\n\n const method = (requestInit.method || 'GET').toUpperCase()\n if (\n attempt < retryConfig.maxRetries &&\n SAFE_METHODS.includes(method) &&\n retryConfig.retryableStatuses.includes(response.status)\n ) {\n lastError = error\n const retryDelay = retryConfig.retryDelay(attempt)\n debugLog(debug, 'error', `Retrying in ${retryDelay}ms...`, error)\n await delay(retryDelay)\n continue\n }\n\n throw error\n }\n\n return response\n } catch (error) {\n debugLog(debug, 'error', url, error)\n\n const method = (requestInit.method || 'GET').toUpperCase()\n const isSafe = SAFE_METHODS.includes(method)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError = createTimeoutError(\n `Request timed out after ${timeout}ms.`,\n { url, timeout, attempt: attempt + 1 },\n 'The request timed out.',\n 'Please check your network connection or try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = timeoutError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw timeoutError\n }\n\n if (error instanceof TypeError) {\n const networkError = createNetworkError(\n 'Network connection failed.',\n undefined,\n { url, originalError: error.message, attempt: attempt + 1 },\n 'Network connection failed.',\n 'Please check your internet connection and try again.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = networkError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw networkError\n }\n\n if (error instanceof NetworkError || error instanceof TimeoutError) {\n if (\n isSafe &&\n attempt < retryConfig.maxRetries &&\n error.status &&\n !NON_RETRYABLE_STATUSES.includes(error.status) &&\n retryConfig.retryableStatuses.includes(error.status)\n ) {\n lastError = error\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw error\n }\n\n // Re-throw any other SDKError subclass (e.g. UsageLimitError) without wrapping\n if (error instanceof SDKError) {\n throw error\n }\n\n const unknownError = createNetworkError(\n error instanceof Error\n ? error.message\n : 'An unknown network error occurred.',\n undefined,\n { url, originalError: error, attempt: attempt + 1 },\n 'An unknown error occurred.',\n 'Please try again later.',\n )\n\n if (isSafe && attempt < retryConfig.maxRetries) {\n lastError = unknownError\n await delay(retryConfig.retryDelay(attempt))\n continue\n }\n\n throw unknownError\n }\n }\n\n throw lastError ?? new NetworkError('Request failed after retries')\n}\n","export function productDetailQuery(\n params: { slug: string } | { id: string },\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n return `/api/products/detail?${search}`\n}\n\nexport function productDetailCatalogQuery(\n params: { slug: string } | { id: string },\n): string {\n const search = new URLSearchParams()\n if ('slug' in params) {\n search.set('slug', params.slug)\n } else {\n search.set('id', params.id)\n }\n return `/api/products/detail/catalog?${search}`\n}\n\nexport function listingGroupsQuery(params: { productIds: string[] }): string {\n return `/api/products/listing-groups?ids=${params.productIds.map(encodeURIComponent).join(',')}`\n}\n\nexport function listingGroupsCatalogQuery(params: {\n productIds: string[]\n}): string {\n return `/api/products/listing-groups/catalog?ids=${params.productIds.map(encodeURIComponent).join(',')}`\n}\n\ntype ListingGroupsQueryUrlOptions = {\n page?: number\n limit?: number\n sort?: string | string[]\n where?: Record<string, unknown>\n}\n\nfunction appendListingGroupsQuerySearchParams(\n search: URLSearchParams,\n options?: ListingGroupsQueryUrlOptions,\n): void {\n if (options?.page != null) search.set('page', String(options.page))\n if (options?.limit != null) search.set('limit', String(options.limit))\n if (options?.sort != null) {\n const sort = options.sort\n search.set(\n 'sort',\n Array.isArray(sort) ? sort.join(',') : sort,\n )\n }\n if (options?.where != null) {\n search.set('whereJson', JSON.stringify(options.where))\n }\n}\n\n/** GET cacheable PLP listing-groups query (full variant stock fields). */\nexport function listingGroupsQueryUrl(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n const query = search.toString()\n return `/api/products/listing-groups/query${query ? `?${query}` : ''}`\n}\n\n/** GET cacheable PLP listing-groups query (catalog / CDN-friendly). */\nexport function listingGroupsQueryCatalogUrl(\n options?: ListingGroupsQueryUrlOptions,\n): string {\n const search = new URLSearchParams()\n appendListingGroupsQuerySearchParams(search, options)\n const query = search.toString()\n return `/api/products/listing-groups/query/catalog${query ? `?${query}` : ''}`\n}\n\nexport function stockSnapshotQuery(params: { variantIds: string[] }): string {\n return `/api/products/stock?variantIds=${params.variantIds.map(encodeURIComponent).join(',')}`\n}\n","/**\n * Resolves a Payload CMS relation field value.\n * When depth is 0, relation fields return just the ID (string or number).\n * When depth > 0, they return the full document object (T).\n * This utility normalizes both cases to T | null.\n *\n * @param ref - The relation field value (T, string, number, null, or undefined)\n * @returns The resolved document object, or null if not populated\n */\nexport function resolveRelation<T>(\n ref: T | string | number | null | undefined,\n): T | null\nexport function resolveRelation<T>(ref: unknown): T | null\nexport function resolveRelation<T>(ref: unknown): T | null {\n if (\n typeof ref === 'string' ||\n typeof ref === 'number' ||\n ref === null ||\n ref === undefined\n )\n return null\n return ref as T\n}\n","import { resolveRelation } from '../../utils/types'\n\nexport interface MetadataImage {\n url: string\n width?: number\n height?: number\n alt?: string\n}\n\nexport interface Metadata {\n title?: string\n description?: string\n robots?: {\n index?: boolean\n follow?: boolean\n }\n alternates?: {\n canonical?: string\n }\n openGraph?: {\n title?: string\n description?: string\n siteName?: string\n images?: MetadataImage[]\n }\n twitter?: {\n card?: 'summary' | 'summary_large_image'\n title?: string\n description?: string\n images?: string[]\n }\n}\n\nexport interface ImageLike {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n sizes?: Record<\n string,\n | { url?: string | null; width?: number | null; height?: number | null }\n | undefined\n >\n}\n\nconst OPEN_GRAPH_IMAGE_SIZE = '1200'\nconst LEGACY_OPEN_GRAPH_IMAGE_SIZE = '1536'\n\nexport interface SeoInput {\n title?: string | null\n description?: string | null\n noIndex?: boolean | null\n canonical?: string | null\n openGraph?: {\n title?: string | null\n description?: string | null\n image?: ImageLike | string | null\n } | null\n}\n\nexport interface GenerateMetadataOptions {\n siteName?: string\n}\n\nexport function extractSeo(doc: Record<string, unknown>): SeoInput {\n const seo = (doc.seo ?? {}) as Record<string, unknown>\n const og = (seo.openGraph ?? {}) as Record<string, unknown>\n\n return {\n title: (seo.title as string) ?? (doc.title as string) ?? null,\n description: (seo.description as string) ?? null,\n noIndex: (seo.noIndex as boolean) ?? null,\n canonical: (seo.canonical as string) ?? null,\n openGraph: {\n title: (og.title as string) ?? null,\n description: (og.description as string) ?? null,\n image: (og.image as ImageLike | string | null) ?? null,\n },\n }\n}\n\nexport function generateMetadata(\n input: SeoInput,\n options?: GenerateMetadataOptions,\n): Metadata {\n const title = input.title ?? undefined\n const description = input.description ?? undefined\n\n const ogTitle = input.openGraph?.title ?? title\n const ogDescription = input.openGraph?.description ?? description\n const image = resolveMetaImage(input.openGraph?.image)\n\n return {\n title,\n description,\n ...(input.noIndex && { robots: { index: false, follow: false } }),\n ...(input.canonical && { alternates: { canonical: input.canonical } }),\n openGraph: {\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(options?.siteName && { siteName: options.siteName }),\n ...(image && { images: [image] }),\n },\n twitter: {\n card: image ? 'summary_large_image' : 'summary',\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(image && { images: [image.url] }),\n },\n }\n}\n\nfunction resolveMetaImage(\n ref: ImageLike | string | null | undefined,\n): MetadataImage | null {\n const image = resolveRelation<ImageLike>(ref)\n if (!image) return null\n\n // Prefer the generated 1200px rendition for social previews, preserving the\n // legacy 1536px fallback for records uploaded before the image-size change.\n const sized =\n image.sizes?.[OPEN_GRAPH_IMAGE_SIZE] ??\n image.sizes?.[LEGACY_OPEN_GRAPH_IMAGE_SIZE]\n const url = sized?.url || image.url\n if (!url) return null\n\n const width = sized?.url ? sized.width : image.width\n const height = sized?.url ? sized.height : image.height\n\n return {\n url,\n ...(width && { width }),\n ...(height && { height }),\n ...(image.alt && { alt: image.alt }),\n }\n}\n","import type {\n ApiQueryOptions,\n PublicCollection,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport { generateMetadata, extractSeo } from '../metadata'\nimport type { GenerateMetadataOptions, Metadata } from '../metadata'\nimport type { CollectionClient } from './collection-client'\nimport type { CollectionType } from './types'\n\ntype ReadOnlyCollectionApi = Pick<\n CollectionClient,\n 'requestFind' | 'requestFindById' | 'requestCount'\n>\n\n/**\n * Read-only subset of CollectionQueryBuilder.\n * Client.from() returns this type to prevent write operations at compile time.\n */\nexport type ReadOnlyQueryBuilder<T extends PublicCollection> =\n ReadOnlyCollectionQueryBuilder<T>\n\nexport class ReadOnlyCollectionQueryBuilder<T extends PublicCollection> {\n constructor(\n private api: ReadOnlyCollectionApi,\n private collection: T,\n ) {}\n\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n}\n\nexport class CollectionQueryBuilder<T extends string> {\n constructor(\n private api: CollectionClient,\n private collection: T,\n ) {}\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n * @returns Payload CMS find response with docs array and pagination\n */\n async find(\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestFind<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n options,\n )\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n * @returns Document object directly (no wrapper)\n */\n async findById(\n id: string | number,\n options?: ApiQueryOptions,\n ): Promise<CollectionType<T>> {\n return this.api.requestFindById<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n options,\n )\n }\n\n /**\n * Create a new document\n * POST /api/{collection}\n * @returns Payload CMS mutation response with doc and message\n */\n async create(\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}`\n if (options?.file) {\n return this.api.requestCreateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n )\n }\n return this.api.requestCreate<CollectionType<T>>(endpoint, data)\n }\n\n /**\n * Update a document by ID\n * PATCH /api/{collection}/{id}\n * @returns Payload CMS mutation response with doc and message\n */\n async update(\n id: string,\n data: Partial<CollectionType<T>>,\n options?: { file?: File | Blob; filename?: string },\n ): Promise<PayloadMutationResponse<CollectionType<T>>> {\n const endpoint = `/api/${String(this.collection)}/${String(id)}`\n if (options?.file) {\n return this.api.requestUpdateWithFile<CollectionType<T>>(\n endpoint,\n data,\n options.file,\n options.filename,\n )\n }\n return this.api.requestUpdate<CollectionType<T>>(endpoint, data)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n * @returns Count response with totalDocs\n */\n async count(options?: ApiQueryOptions): Promise<{ totalDocs: number }> {\n return this.api.requestCount(\n `/api/${String(this.collection)}/count`,\n options,\n )\n }\n\n /**\n * Find first matching document and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) and limit: 1 automatically.\n * @returns Metadata or null if no document matches\n */\n async findMetadata(\n options?: ApiQueryOptions,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata | null> {\n const { docs } = await this.find({ ...options, limit: 1, depth: 1 })\n const doc = docs[0]\n if (!doc) return null\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Find document by ID and return its Next.js Metadata.\n * Applies depth: 1 (SEO image populate) automatically.\n * @returns Metadata (throws on 404)\n */\n async findMetadataById(\n id: string,\n metadataOptions?: GenerateMetadataOptions,\n ): Promise<Metadata> {\n const doc = await this.findById(id, { depth: 1 })\n return generateMetadata(\n extractSeo(doc as unknown as Record<string, unknown>),\n metadataOptions,\n )\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n * @returns Payload CMS find response with updated docs\n */\n async updateMany(\n where: ApiQueryOptions['where'],\n data: Partial<CollectionType<T>>,\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestUpdateMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where, data },\n )\n }\n\n /**\n * Delete a document by ID\n * DELETE /api/{collection}/{id}\n * @returns Deleted document object directly (no wrapper)\n */\n async remove(id: string): Promise<CollectionType<T>> {\n return this.api.requestDelete<CollectionType<T>>(\n `/api/${String(this.collection)}/${String(id)}`,\n )\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n * @returns Payload CMS find response with deleted docs\n */\n async removeMany(\n where: ApiQueryOptions['where'],\n ): Promise<PayloadFindResponse<CollectionType<T>>> {\n return this.api.requestDeleteMany<CollectionType<T>>(\n `/api/${String(this.collection)}`,\n { where },\n )\n }\n}\n\nexport class ServerCollectionQueryBuilder<\n T extends ServerCollection,\n> extends CollectionQueryBuilder<T> {}\n","import { HttpClient } from './http-client'\nimport type {\n ApiQueryOptions,\n PublicCollection,\n ServerCollection,\n PayloadFindResponse,\n PayloadMutationResponse,\n} from '../client/types'\nimport {\n CollectionQueryBuilder,\n ReadOnlyCollectionQueryBuilder,\n ServerCollectionQueryBuilder,\n type ReadOnlyQueryBuilder,\n} from './query-builder'\n\nfunction buildPayloadFormData(\n data: unknown,\n file: File | Blob,\n filename?: string,\n): FormData {\n const formData = new FormData()\n formData.append('file', file, filename)\n if (data != null) {\n formData.append('_payload', JSON.stringify(data))\n }\n return formData\n}\n\nexport class CollectionClient<\n TCollection extends string = PublicCollection,\n> extends HttpClient {\n from<T extends TCollection>(collection: T): CollectionQueryBuilder<T> {\n return new CollectionQueryBuilder(this, collection)\n }\n\n // ============================================================================\n // Payload-native methods\n // ============================================================================\n\n /**\n * Find documents (list query)\n * GET /api/{collection}\n */\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a custom endpoint\n * POST /api/...custom-endpoint\n */\n async requestFindEndpoint<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find-like response from a cacheable GET custom endpoint.\n */\n async requestFindEndpointGet<T = unknown>(\n endpoint: string,\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Find document by ID\n * GET /api/{collection}/{id}\n */\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Create document\n * POST /api/{collection}\n */\n async requestCreate<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document\n * PATCH /api/{collection}/{id}\n */\n async requestUpdate<T = unknown>(\n endpoint: string,\n data?: unknown,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Count documents\n * GET /api/{collection}/count\n */\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n\n /**\n * Update multiple documents (bulk update)\n * PATCH /api/{collection}\n */\n async requestUpdateMany<T = unknown>(\n endpoint: string,\n data: { where?: unknown; data: unknown },\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: JSON.stringify(data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Delete document\n * DELETE /api/{collection}/{id}\n */\n async requestDelete<T = unknown>(endpoint: string): Promise<T> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'DELETE',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n /**\n * Delete multiple documents (bulk delete)\n * DELETE /api/{collection}\n */\n async requestDeleteMany<T = unknown>(\n endpoint: string,\n data: { where?: unknown },\n ): Promise<PayloadFindResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'DELETE',\n body: JSON.stringify(data),\n })\n return this.parseFindResponse<T>(response)\n }\n\n /**\n * Create document with file upload\n * POST /api/{collection} (multipart/form-data)\n */\n async requestCreateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'POST',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n\n /**\n * Update document with file upload\n * PATCH /api/{collection}/{id} (multipart/form-data)\n */\n async requestUpdateWithFile<T = unknown>(\n endpoint: string,\n data: unknown,\n file: File | Blob,\n filename?: string,\n ): Promise<PayloadMutationResponse<T>> {\n const response = await this.fetchWithTracking(endpoint, {\n ...this.defaultOptions,\n method: 'PATCH',\n body: buildPayloadFormData(data, file, filename),\n })\n return this.parseMutationResponse<T>(response)\n }\n}\n\nexport class ServerCollectionClient extends CollectionClient<ServerCollection> {\n override from<T extends ServerCollection>(\n collection: T,\n ): ServerCollectionQueryBuilder<T> {\n return new ServerCollectionQueryBuilder(this, collection)\n }\n}\n\nexport class ReadOnlyCollectionClient extends HttpClient {\n from<T extends PublicCollection>(collection: T): ReadOnlyQueryBuilder<T> {\n return new ReadOnlyCollectionQueryBuilder(this, collection)\n }\n\n async requestFind<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<PayloadFindResponse<T>> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseFindResponse<T>(response)\n }\n\n async requestFindById<T = unknown>(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<T> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<T>(response)\n }\n\n async requestCount(\n endpoint: string,\n options?: ApiQueryOptions,\n ): Promise<{ totalDocs: number }> {\n const url = this.buildUrl(endpoint, options)\n const response = await this.fetchWithTracking(url, {\n ...this.defaultOptions,\n method: 'GET',\n })\n return this.parseDocumentResponse<{ totalDocs: number }>(response)\n }\n}\n","import {\n createApiError,\n createValidationError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from '../internal/errors'\nimport { attachRequestId } from '../internal/utils/http'\n\n/**\n * Shared JSON response parser for BaseApi and CartApi.\n * Parses response JSON body and throws typed errors based on the `reason` field.\n * Only called for responses that passed httpFetch (i.e. response.ok = true);\n * handles application-level errors embedded in 2xx bodies.\n */\nexport async function parseApiResponse<T>(\n response: Response,\n endpoint: string,\n): Promise<T> {\n let data: Record<string, unknown>\n try {\n data = await response.json()\n } catch {\n throw createApiError(\n `Invalid JSON response from ${endpoint}`,\n response.status,\n undefined,\n 'Server returned an invalid response.',\n 'Check if the API endpoint is available.',\n )\n }\n\n if (data.error) {\n const errorMessage =\n typeof data.error === 'string' ? data.error : 'Unknown API error'\n const reason = typeof data.reason === 'string' ? data.reason : undefined\n const requestId = response.headers.get('x-request-id') ?? undefined\n const retryAfterRaw = response.headers.get('Retry-After')\n const retryAfter = retryAfterRaw ? parseInt(retryAfterRaw, 10) || undefined : undefined\n\n if (reason === 'validation_failed') {\n throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId)\n }\n if (\n reason === 'token_expired' ||\n reason === 'token_invalid' ||\n reason === 'preview_token_invalid' ||\n reason === 'preview_token_required' ||\n reason === 'key_invalid' ||\n reason === 'key_revoked'\n ) {\n throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'forbidden') {\n throw attachRequestId(createPermissionError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'rate_limit_exceeded') {\n throw attachRequestId(createRateLimitError(errorMessage, retryAfter, data, errorMessage), requestId)\n }\n if (reason === 'not_found') {\n throw attachRequestId(createNotFoundError(errorMessage, data, errorMessage), requestId)\n }\n if (reason === 'conflict') {\n throw attachRequestId(createConflictError(errorMessage, data, errorMessage), requestId)\n }\n throw attachRequestId(\n createApiError(errorMessage, response.status, data, errorMessage, 'An error occurred while processing the request.'),\n requestId,\n )\n }\n\n return data as T\n}\n","import { createConfigError, SDKError } from '../internal/errors'\nimport {\n httpFetch,\n requirePublishableKeyForSecret,\n} from '../internal/utils'\nimport { parseApiResponse } from './parse-response'\n\nexport interface CustomerScopedApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n requiresCredential?: boolean\n}\n\nexport interface CustomerScopedRequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n body?: unknown\n headers?: Record<string, string>\n}\n\nexport class CustomerScopedApi {\n private readonly publishableKey: string\n private readonly secretKey?: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(apiName: string, options: CustomerScopedApiOptions) {\n if (\n options.requiresCredential !== false &&\n !options.secretKey &&\n !options.customerToken\n ) {\n throw createConfigError(\n `Either secretKey or customerToken is required for ${apiName}.`,\n )\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n apiName,\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n protected async request<T>(\n endpoint: string,\n options: CustomerScopedRequestOptions,\n ): Promise<T> {\n const token =\n typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n\n try {\n const response = await httpFetch(endpoint, {\n method: options.method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n customerToken: token ?? undefined,\n ...(token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(options.body !== undefined && {\n body: JSON.stringify(options.body),\n }),\n ...(options.headers && { headers: options.headers }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n","import { CustomerScopedApi } from '../api/customer-scoped-api'\nimport { SDKError } from '../internal/errors'\nimport type { CollectionType } from '../collection/types'\n\nexport interface CommunityClientOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\n/** Public read shape for `posts` (tenant-scoped author profiles). */\nexport type CommunityPost = CollectionType<'posts'>\n\n/** Public read shape for `comments`. */\nexport type CommunityComment = CollectionType<'comments'>\n\n/** @deprecated Use {@link CommunityComment}. */\nexport type Comment = CommunityComment\n\n/** Public read shape for `post-categories`. */\nexport type CommunityPostCategory = CollectionType<'post-categories'>\n\n/** Public read shape for `post-tags`. */\nexport type CommunityPostTag = CollectionType<'post-tags'>\n\nexport type CommunityPostListSort =\n | 'createdAt'\n | '-createdAt'\n | 'lastActivityAt'\n | '-lastActivityAt'\n | 'viewCount'\n | '-viewCount'\n | 'commentCount'\n | '-commentCount'\n\nexport type CommunityCommentListSort = 'createdAt' | '-createdAt'\n\nexport interface Reaction {\n id: string\n post?: string\n comment?: string\n type?: string\n createdAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionSummary {\n counts: Record<string, number>\n total: number\n userReactions: string[]\n}\n\nexport interface Bookmark {\n id: string\n post?: string\n createdAt?: string\n [key: string]: unknown\n}\n\nexport interface ReactionType {\n id: string\n title: string\n slug: string\n emoji?: string\n [key: string]: unknown\n}\n\nexport interface PaginatedResponse<T> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\nconst DEFAULT_POST_LIST_SORT: CommunityPostListSort = '-lastActivityAt'\nconst DEFAULT_COMMENT_LIST_SORT: CommunityCommentListSort = '-createdAt'\n\nfunction unwrapPayloadDoc<T>(value: T | { doc: T }): T {\n if (value && typeof value === 'object' && 'doc' in value) {\n return (value as { doc: T }).doc\n }\n return value as T\n}\n\nexport class CommunityClient extends CustomerScopedApi {\n constructor(options: CommunityClientOptions) {\n super('CommunityClient', { ...options, requiresCredential: false })\n }\n\n private buildQuery(params?: Record<string, string | number | undefined>): string {\n if (!params) return ''\n const entries = Object.entries(params)\n .filter((e): e is [string, string | number] => e[1] !== undefined)\n .map(([k, v]) => [k, String(v)])\n return entries.length ? `?${new URLSearchParams(entries).toString()}` : ''\n }\n\n private buildPostsListQuery(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params?.sort ?? DEFAULT_POST_LIST_SORT\n urlParams.set('sort', sort)\n if (params?.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params?.page !== undefined) urlParams.set('page', String(params.page))\n if (params?.categoryId !== undefined) {\n urlParams.set('where[categories][in]', params.categoryId)\n }\n if (params?.tagId !== undefined) {\n urlParams.set('where[tags][in]', params.tagId)\n }\n return `/api/posts?${urlParams.toString()}`\n }\n\n private buildCommentsListQuery(params: {\n postId?: string\n parentId?: string\n rootComment?: string\n topLevelOnly?: boolean\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): string {\n const urlParams = new URLSearchParams()\n const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT\n urlParams.set('sort', sort)\n if (params.postId !== undefined) {\n urlParams.set('where[post][equals]', params.postId)\n }\n if (params.parentId !== undefined) {\n urlParams.set('where[parent][equals]', params.parentId)\n }\n if (params.rootComment !== undefined) {\n urlParams.set('where[rootComment][equals]', params.rootComment)\n }\n if (params.topLevelOnly) {\n urlParams.set('where[parent][exists]', 'false')\n }\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n return `/api/comments?${urlParams.toString()}`\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n body?: unknown,\n ): Promise<T> {\n return this.request<T>(endpoint, { method, body })\n }\n\n private async executeDoc<T>(\n endpoint: string,\n method: 'POST' | 'PATCH',\n body?: unknown,\n ): Promise<T> {\n const response = await this.execute<T | { doc: T }>(endpoint, method, body)\n return unwrapPayloadDoc(response)\n }\n\n createPost(params: {\n title?: string | null\n content?: unknown\n categories?: string[]\n thumbnail?: string\n }): Promise<CommunityPost> {\n return this.executeDoc<CommunityPost>('/api/posts', 'POST', params)\n }\n\n /**\n * Public post feed. Server applies the same visibility contract as\n * `communityPostRead` (published + visible + moderation-safe).\n */\n listPosts(params?: {\n page?: number\n limit?: number\n categoryId?: string\n tagId?: string\n sort?: CommunityPostListSort\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n this.buildPostsListQuery(params),\n 'GET',\n )\n }\n\n listPostCategories(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostCategory>> {\n return this.execute<PaginatedResponse<CommunityPostCategory>>(\n `/api/post-categories${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n listPostTags(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPostTag>> {\n return this.execute<PaginatedResponse<CommunityPostTag>>(\n `/api/post-tags${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getMyPosts(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n getTrending(params?: {\n page?: number\n limit?: number\n period?: string\n metric?: 'reactions' | 'comments' | 'views' | 'activity'\n }): Promise<PaginatedResponse<CommunityPost>> {\n return this.execute<PaginatedResponse<CommunityPost>>(\n `/api/posts/trending${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n incrementView(params: { postId: string }): Promise<{ viewCount: number }> {\n return this.execute<{ viewCount: number }>(\n `/api/posts/${params.postId}/view`,\n 'POST',\n )\n }\n\n reportPost(params: {\n postId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { postId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/report`,\n 'POST',\n body,\n )\n }\n\n // Comments\n\n createComment(params: {\n postId: string\n body: string\n parentId?: string\n }): Promise<CommunityComment> {\n const { postId, parentId, body: commentBody } = params\n const body: Record<string, unknown> = { post: postId, body: commentBody }\n if (parentId !== undefined) {\n body.parent = parentId\n }\n return this.executeDoc<CommunityComment>('/api/comments', 'POST', body)\n }\n\n /**\n * List comments for a post.\n *\n * - Default: all visible comments on the post (any depth).\n * - `topLevelOnly: true`: only root comments (`parent` unset).\n * - `rootComment`: comments belonging to a thread rooted at that comment.\n */\n listComments(params: {\n postId: string\n page?: number\n limit?: number\n rootComment?: string\n topLevelOnly?: boolean\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { postId, page, limit, rootComment, topLevelOnly, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n postId,\n page,\n limit,\n rootComment,\n topLevelOnly,\n sort,\n }),\n 'GET',\n )\n }\n\n /** Direct replies to a comment (`where[parent][equals]`). */\n listReplies(params: {\n commentId: string\n page?: number\n limit?: number\n sort?: CommunityCommentListSort\n }): Promise<PaginatedResponse<CommunityComment>> {\n const { commentId, page, limit, sort } = params\n return this.execute<PaginatedResponse<CommunityComment>>(\n this.buildCommentsListQuery({\n parentId: commentId,\n page,\n limit,\n sort,\n }),\n 'GET',\n )\n }\n\n updateComment(params: {\n commentId: string\n body: string\n }): Promise<CommunityComment> {\n const { commentId, body } = params\n return this.executeDoc<CommunityComment>(\n `/api/comments/${commentId}`,\n 'PATCH',\n { body },\n )\n }\n\n deleteComment(params: {\n commentId: string\n }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/comments/${params.commentId}`,\n 'DELETE',\n )\n }\n\n reportComment(params: {\n commentId: string\n reason?: string\n reasonDetail?: string\n }): Promise<{ success: boolean }> {\n const { commentId, ...body } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/report`,\n 'POST',\n body,\n )\n }\n\n // Reactions\n\n addReaction(params: {\n postId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<Reaction> {\n const { postId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<Reaction>('/api/reactions', 'POST', {\n post: postId,\n type: reactionType,\n })\n }\n\n removeReaction(params: {\n postId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { postId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n addCommentReaction(params: {\n commentId: string\n typeSlug?: string\n /** @deprecated Use `typeSlug`. */\n type?: string\n }): Promise<Reaction> {\n const { commentId, typeSlug, type } = params\n const reactionType = typeSlug ?? type\n if (!reactionType) {\n throw new SDKError(\n 'validation_failed',\n 'addCommentReaction requires typeSlug (or deprecated type)',\n 400,\n )\n }\n return this.executeDoc<Reaction>('/api/reactions', 'POST', {\n comment: commentId,\n type: reactionType,\n })\n }\n\n removeCommentReaction(params: {\n commentId: string\n type: string\n }): Promise<{ success: boolean }> {\n const { commentId, type } = params\n return this.execute<{ success: boolean }>(\n `/api/comments/${commentId}/react?type=${encodeURIComponent(type)}`,\n 'DELETE',\n )\n }\n\n getReactionSummary(params: {\n postId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/posts/${params.postId}/reactions`,\n 'GET',\n )\n }\n\n getCommentReactionSummary(params: {\n commentId: string\n }): Promise<ReactionSummary> {\n return this.execute<ReactionSummary>(\n `/api/comments/${params.commentId}/reactions`,\n 'GET',\n )\n }\n\n getReactionTypes(): Promise<PaginatedResponse<ReactionType>> {\n return this.execute<PaginatedResponse<ReactionType>>(\n '/api/reaction-types?limit=100',\n 'GET',\n )\n }\n\n // Bookmarks\n\n addBookmark(params: { postId: string }): Promise<Bookmark> {\n return this.executeDoc<Bookmark>('/api/bookmarks', 'POST', {\n post: params.postId,\n })\n }\n\n removeBookmark(params: {\n postId: string\n }): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n `/api/posts/${params.postId}/bookmark`,\n 'DELETE',\n )\n }\n\n getMyBookmarks(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<Bookmark>> {\n return this.execute<PaginatedResponse<Bookmark>>(\n `/api/bookmarks/my${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n // Profiles\n\n listProfileLists(params?: {\n page?: number\n limit?: number\n }): Promise<PaginatedResponse<CollectionType<'customer-profile-lists'>>> {\n return this.execute<PaginatedResponse<CollectionType<'customer-profile-lists'>>>(\n `/api/customer-profile-lists${this.buildQuery(params)}`,\n 'GET',\n )\n }\n\n async getProfileList(\n params: { slug: string } | { id: string },\n ): Promise<CollectionType<'customer-profile-lists'> | null> {\n const query =\n 'slug' in params\n ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1`\n : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`\n const res = await this.execute<\n PaginatedResponse<CollectionType<'customer-profile-lists'>>\n >(`/api/customer-profile-lists${query}`, 'GET')\n return res.docs[0] ?? null\n }\n\n updatePublicProfile(body: {\n displayName?: string | null\n handle?: string | null\n avatar?: string | null\n bio?: string | null\n bioRichText?: CollectionType<'customer-profiles'>['bioRichText']\n }): Promise<CollectionType<'customer-profiles'>> {\n return this.execute<CollectionType<'customer-profiles'>>(\n '/api/customers/me/profile',\n 'PATCH',\n body,\n )\n }\n}\n","import { ApiError, SDKError } from '../internal/errors'\nimport { parseApiResponse } from '../api/parse-response'\nimport { httpFetch } from '../internal/utils'\nimport { resolveApiUrl, type PayloadFindResponse } from '../client/types'\nimport type { Order } from '../../payload-types'\nimport type {\n CustomerAuthResponse,\n CustomerRefreshResponse,\n CustomerRegisterData,\n CustomerRegisterResponse,\n CustomerLoginData,\n CustomerProfile,\n CustomerAuthOptions,\n UpdateProfileData,\n} from './types'\n\nconst DEFAULT_TIMEOUT = 15000\n\nfunction safeGetItem(key: string): string | null {\n try {\n return localStorage.getItem(key)\n } catch {\n return null\n }\n}\n\n/**\n * Customer authentication client.\n *\n * Manages customer registration, login, logout, and token lifecycle.\n * All requests include X-Publishable-Key for tenant resolution.\n */\nexport class CustomerAuth {\n private publishableKey: string\n private baseUrl: string\n private token: string | null\n private onTokenChange?: (token: string | null) => void\n private refreshPromise: Promise<CustomerRefreshResponse> | null = null\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.publishableKey = publishableKey\n this.baseUrl = resolveApiUrl(apiUrl)\n\n const persist = options?.persist ?? true\n if (persist) {\n const key = typeof persist === 'string' ? persist : 'customer-token'\n const isBrowser = typeof window !== 'undefined'\n this.token = isBrowser ? safeGetItem(key) : null\n this.onTokenChange = isBrowser\n ? (token) => {\n try {\n if (token) localStorage.setItem(key, token)\n else localStorage.removeItem(key)\n } catch {\n // Safari private mode, iframe sandbox, etc.\n }\n }\n : undefined\n } else {\n this.token = options?.token ?? null\n this.onTokenChange = options?.onTokenChange\n }\n }\n\n /**\n * Register a new customer account\n */\n async register(\n data: CustomerRegisterData,\n ): Promise<CustomerRegisterResponse> {\n return this.requestJson('/api/customers/register', {\n method: 'POST',\n body: JSON.stringify(data),\n })\n }\n\n /**\n * Login with email and password. Stores the token internally.\n */\n async login(data: CustomerLoginData): Promise<CustomerAuthResponse> {\n const result: CustomerAuthResponse = await this.requestJson(\n '/api/customers/login',\n {\n method: 'POST',\n body: JSON.stringify(data),\n },\n )\n\n this.setToken(result.token)\n return result\n }\n\n /**\n * Refresh the current token. Requires a valid (non-expired) token.\n */\n async refreshToken(): Promise<CustomerRefreshResponse> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n if (this.refreshPromise) return this.refreshPromise\n\n this.refreshPromise = this._doRefreshToken()\n try {\n return await this.refreshPromise\n } finally {\n this.refreshPromise = null\n }\n }\n\n private async _doRefreshToken(): Promise<CustomerRefreshResponse> {\n const result: CustomerRefreshResponse = await this.requestJson(\n '/api/customers/refresh',\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.token}` },\n },\n )\n\n this.setToken(result.token)\n return result\n }\n\n /**\n * Clear the stored token\n */\n logout(): void {\n this.setToken(null)\n }\n\n /**\n * Get the current authenticated customer's profile\n */\n async me(): Promise<CustomerProfile | null> {\n if (!this.token) return null\n\n try {\n const data = await this.requestJson<{ customer: CustomerProfile }>(\n '/api/customers/me',\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.token}` },\n },\n )\n return data.customer ?? null\n } catch (error) {\n if (error instanceof SDKError && error.status === 401) {\n this.setToken(null)\n return null\n }\n throw error\n }\n }\n\n /**\n * Request a password reset email\n */\n async forgotPassword(email: string): Promise<void> {\n await this.requestJson('/api/customers/forgot-password', {\n method: 'POST',\n body: JSON.stringify({ email }),\n })\n }\n\n /**\n * Reset password using a token from the reset email\n */\n async resetPassword(token: string, password: string): Promise<void> {\n await this.requestJson('/api/customers/reset-password', {\n method: 'POST',\n body: JSON.stringify({ token, password }),\n })\n }\n\n /**\n * Update the authenticated customer's profile (name, phone, marketingConsent)\n */\n async updateProfile(data: UpdateProfileData): Promise<CustomerProfile> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n const result = await this.requestJson<{ customer: CustomerProfile }>(\n '/api/customers/me',\n {\n method: 'PATCH',\n headers: { Authorization: `Bearer ${this.token}` },\n body: JSON.stringify(data),\n },\n )\n return result.customer\n }\n\n /**\n * Change the password of the currently authenticated customer\n */\n async changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<void> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n await this.requestJson('/api/customers/change-password', {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.token}` },\n body: JSON.stringify({ currentPassword, newPassword }),\n })\n }\n\n /**\n * Get the authenticated customer's orders with pagination and optional status filter\n */\n async getMyOrders(options?: {\n page?: number\n limit?: number\n status?: string\n }): Promise<PayloadFindResponse<Order>> {\n if (!this.token) throw new ApiError('Not authenticated', 401)\n\n const params = new URLSearchParams()\n if (options?.page) params.set('page', String(options.page))\n if (options?.limit) params.set('limit', String(options.limit))\n if (options?.status) params.set('status', options.status)\n\n const qs = params.toString()\n return this.requestJson(`/api/customers/me/orders${qs ? `?${qs}` : ''}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.token}` },\n })\n }\n\n /**\n * Get the current token (or null if not authenticated)\n */\n getToken(): string | null {\n return this.token\n }\n\n /**\n * Set the token manually (e.g. from SSR)\n */\n setToken(token: string | null): void {\n this.token = token\n this.onTokenChange?.(token)\n }\n\n /**\n * Check if the customer is currently authenticated\n */\n isAuthenticated(): boolean {\n return this.token !== null\n }\n\n /**\n * Internal: make a request with timeout and error handling.\n * Auth endpoints don't retry — failures are final.\n */\n private async requestJson<T = unknown>(\n path: string,\n init: RequestInit,\n ): Promise<T> {\n const headers = new Headers(init.headers)\n headers.set('X-Publishable-Key', this.publishableKey)\n if (!headers.has('Content-Type') && init.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await httpFetch(path, {\n ...init,\n apiUrl: this.baseUrl,\n publishableKey: this.publishableKey,\n headers,\n timeout: DEFAULT_TIMEOUT,\n retry: { maxRetries: 0 },\n })\n\n return parseApiResponse<T>(response, path)\n }\n}\n","import { CustomerAuth } from './customer-auth'\nimport type { CustomerAuthOptions } from './types'\n\n/**\n * Customer namespace. Currently exposes .auth; reserved for future customer-\n * scoped capabilities (addresses, preferences, etc.).\n */\nexport class CustomerNamespace {\n readonly auth: CustomerAuth\n\n constructor(\n publishableKey: string,\n options?: CustomerAuthOptions,\n apiUrl?: string,\n ) {\n this.auth = new CustomerAuth(publishableKey, options, apiUrl)\n }\n}\n","import type { Cart, CartItem } from '../../payload-types'\nimport { CustomerScopedApi } from './customer-scoped-api'\n\nexport interface CartApiOptions {\n publishableKey?: string\n secretKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type AddItemParams = {\n cartId: string\n product: string\n variant: string\n option: string\n quantity: number\n}\n\nexport type UpdateItemParams = {\n cartItemId: string\n quantity: number\n}\n\nexport type RemoveItemParams = {\n cartItemId: string\n}\n\nexport type ApplyDiscountParams = {\n cartId: string\n discountCode: string\n}\n\nexport type RemoveDiscountParams = {\n cartId: string\n}\n\nexport type ClearCartParams = {\n cartId: string\n}\n\nexport class CartApi extends CustomerScopedApi {\n constructor(options: CartApiOptions) {\n super('CartApi', options)\n }\n\n private async execute<T>(\n endpoint: string,\n method: 'GET' | 'POST',\n body?: unknown,\n ): Promise<T> {\n return this.request<T>(endpoint, { method, body })\n }\n\n getCart(cartId: string): Promise<Cart> {\n return this.execute<Cart>(`/api/carts/${cartId}`, 'GET')\n }\n\n addItem(params: AddItemParams): Promise<CartItem> {\n return this.execute<CartItem>('/api/carts/add-item', 'POST', params)\n }\n\n updateItem(params: UpdateItemParams): Promise<CartItem> {\n return this.execute<CartItem>('/api/carts/update-item', 'POST', params)\n }\n\n removeItem(params: RemoveItemParams): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n '/api/carts/remove-item',\n 'POST',\n params,\n )\n }\n\n applyDiscount(params: ApplyDiscountParams): Promise<Cart> {\n return this.execute<Cart>('/api/carts/apply-discount', 'POST', params)\n }\n\n removeDiscount(params: RemoveDiscountParams): Promise<Cart> {\n return this.execute<Cart>('/api/carts/remove-discount', 'POST', params)\n }\n\n clearCart(params: ClearCartParams): Promise<{ success: boolean }> {\n return this.execute<{ success: boolean }>(\n '/api/carts/clear',\n 'POST',\n params,\n )\n }\n}\n","import { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\nimport { createConfigError, SDKError } from '../internal/errors'\nimport { parseApiResponse } from './parse-response'\n\nexport interface ServerApiOptions {\n publishableKey?: string\n secretKey: string\n apiUrl?: string\n onRequestId?: (id: string | null) => void\n}\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n headers?: Record<string, string>\n}\n\nexport abstract class BaseApi {\n protected readonly publishableKey: string\n protected readonly secretKey: string\n protected readonly apiUrl?: string\n protected readonly onRequestId?: (id: string | null) => void\n\n constructor(apiName: string, options: ServerApiOptions) {\n if (!options.secretKey) {\n throw createConfigError(`secretKey is required for ${apiName}.`)\n }\n\n this.publishableKey = requirePublishableKeyForSecret(\n apiName,\n options.publishableKey,\n options.secretKey,\n )\n this.secretKey = options.secretKey\n this.apiUrl = options.apiUrl\n this.onRequestId = options.onRequestId\n }\n\n protected async request<T>(\n endpoint: string,\n body: unknown,\n options?: RequestOptions,\n ): Promise<T> {\n const method = options?.method ?? 'POST'\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n secretKey: this.secretKey,\n ...(body !== undefined && { body: JSON.stringify(body) }),\n ...(options?.headers && { headers: options.headers }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\nimport { SDKError } from '../internal/errors'\nimport {\n listingGroupsCatalogQuery,\n listingGroupsQuery,\n productDetailCatalogQuery,\n productDetailQuery,\n stockSnapshotQuery,\n} from '../internal/utils/query-string'\nimport type {\n ProductListingGroup,\n ProductVariantShape,\n} from '../../utils/ecommerce'\nimport type { PublicProduct } from '../collection/types'\nimport type { ProductUpsertInput } from './product-upsert-contract'\n\nexport type ProductApiOptions = ServerApiOptions\n\nexport type StockCheckParams = {\n items: Array<{\n variantId: string\n quantity: number\n }>\n}\n\nexport type StockCheckResult = {\n variantId: string\n status: 'available' | 'not_published' | 'archived' | 'not_found'\n available: boolean\n availableStock: number\n isUnlimited: boolean\n requestedQuantity: number\n error?: string\n}\n\nexport type StockCheckResponse = {\n results: StockCheckResult[]\n allAvailable: boolean\n}\n\nexport type ListingGroupsParams = {\n productIds: string[]\n}\n\nexport type ProductListingGroupVariant = Pick<\n ProductVariantShape,\n | 'id'\n | 'optionValues'\n | 'price'\n | 'compareAtPrice'\n | 'stock'\n | 'isUnlimited'\n | 'isActive'\n | 'thumbnail'\n | 'images'\n | '_order'\n>\n\nexport type ProductListingGroupSummary =\n ProductListingGroup<ProductListingGroupVariant>\n\ntype ProductListingGroupsProductVariants = NonNullable<\n PublicProduct['variants']\n>\ntype ProductListingGroupsProductPrimaryMediaItemId =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ProductListingGroupsProduct = Omit<PublicProduct, 'variants'> & {\n id: string\n slug: string\n title: string\n primaryMediaItemId?: ProductListingGroupsProductPrimaryMediaItemId\n variants?:\n | (Omit<ProductListingGroupsProductVariants, 'docs'> & {\n docs: ProductListingGroupVariant[]\n })\n | null\n}\n\nexport type ProductListingGroupsItem = {\n product: ProductListingGroupsProduct\n groups: ProductListingGroupSummary[]\n}\n\nexport type ProductListingGroupsResponse = {\n /**\n * Matching products in the same order as the requested productIds, excluding\n * ids that were not found, not published, or not accessible for the current\n * tenant/key.\n */\n docs: ProductListingGroupsItem[]\n /** Requested productIds that could not be returned. */\n missing: string[]\n}\n\nexport type ProductDetailParams = { slug: string } | { id: string }\nexport type ProductDetailPreviewParams = { id: string }\nexport type ProductDetailPreviewOptions = {\n previewToken: string\n}\n\nexport interface ProductDetailVariantOptionValue {\n optionId: string | number\n optionSlug: string\n valueId: string | number\n valueSlug: string\n value?: string | null\n}\n\nexport type ProductDetailMedia =\n | string\n | number\n | {\n id?: string | number | null\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n }\n\nexport type ProductOptionValueColorSwatch = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductOptionValueMediaSwatch<TMedia = ProductDetailMedia> = {\n type: 'media'\n mediaItemId: TMedia\n color?: null\n}\n\nexport type ProductOptionValueSwatch<TMedia = ProductDetailMedia> =\n | ProductOptionValueColorSwatch\n | ProductOptionValueMediaSwatch<TMedia>\n | null\n\nexport type ProductUpsertColorSwatchInput = {\n type: 'color'\n color: string\n mediaItemId?: null\n}\n\nexport type ProductUpsertMediaSwatchInput = {\n type: 'media'\n mediaItemId: string\n color?: null\n}\n\nexport type ProductUpsertSwatchInput =\n | ProductUpsertColorSwatchInput\n | ProductUpsertMediaSwatchInput\n\nexport type ProductDetailMediaValue =\n | string\n | number\n | ProductDetailMedia\n | null\n\nexport type ProductDetailSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDetailDisplayMediaSource =\n | 'listing_primary'\n | 'product_primary'\n | 'product_pool'\n | 'none'\n\n/** Selection + display sources returned by `resolveProductSelection()` media. */\nexport type ProductDetailMediaPointerSource =\n | ProductDetailSelectionMediaSource\n | ProductDetailDisplayMediaSource\n\nexport interface ProductDetailVariant {\n id: string | number\n optionKey: string\n title?: string | null\n displayName: string\n sku?: string | null\n price: number\n compareAtPrice?: number | null\n stock: number\n reservedStock: number\n isUnlimited: boolean\n isActive: boolean\n thumbnail?: ProductDetailMedia | null\n images?: ProductDetailMedia[]\n media?: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source: ProductDetailSelectionMediaSource\n }\n optionValues: ProductDetailVariantOptionValue[]\n}\n\nexport interface ProductDetailOptionValue {\n id: string | number\n value: string\n slug: string\n swatch?: ProductOptionValueSwatch<ProductDetailMedia>\n}\n\nexport interface ProductDetailOption {\n id: string | number\n title: string\n slug: string\n values: ProductDetailOptionValue[]\n}\n\nexport interface ProductDetailBrand {\n id: string | number\n name: string\n slug?: string | null\n logo?: unknown | null\n}\n\nexport interface ProductDetailCategory {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailTag {\n id: string | number\n title: string\n slug?: string | null\n}\n\nexport interface ProductDetailImage {\n id: string | number\n url?: string | null\n alt?: string | null\n width?: number | null\n height?: number | null\n}\n\nexport interface ProductDetailVideo {\n id: string | number\n url?: string | null\n}\n\nexport interface ProductDetailListing {\n minPrice?: number | null\n maxPrice?: number | null\n minCompareAtPrice?: number | null\n maxCompareAtPrice?: number | null\n isPriceRange?: boolean | null\n primaryImage?: ProductDetailMedia | null\n availableForSale?: boolean | null\n selectionHintVariant?: string | number | null\n}\n\nexport type ProductDetailCatalogVariant = Omit<\n ProductDetailVariant,\n 'stock' | 'reservedStock'\n>\n\nexport type ProductDetailCatalogListing = Omit<\n ProductDetailListing,\n 'availableForSale'\n> & {\n liveStockRequired: true\n}\n\nexport interface ProductDetailCatalog {\n product: Omit<ProductDetail['product'], 'totalInventory'>\n variants: ProductDetailCatalogVariant[]\n options: ProductDetail['options']\n brand: ProductDetail['brand']\n categories: ProductDetail['categories']\n tags: ProductDetail['tags']\n images: ProductDetail['images']\n videos: ProductDetail['videos']\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n listing: ProductDetailCatalogListing\n}\n\nexport type StockSnapshotItemStatus =\n | 'available'\n | 'not_published'\n | 'archived'\n | 'not_found'\n\nexport interface StockSnapshotItem {\n variantId: string\n status: StockSnapshotItemStatus\n availableStock: number\n availableForSale: boolean\n isUnlimited: boolean\n}\n\nexport interface StockSnapshotResponse {\n snapshots: StockSnapshotItem[]\n}\n\nexport type StockSnapshotParams = {\n variantIds: string[]\n}\n\nexport interface ProductDetail {\n product: {\n id: string | number\n slug: string\n title: string\n subtitle?: string | null\n description?: string | null\n content?: unknown\n publishedAt?: string | null\n status: string\n totalInventory: number | null\n totalVariants: number\n hasUnlimitedVariant: boolean\n hasOnlyDefaultVariant: boolean\n }\n variants: ProductDetailVariant[]\n options: ProductDetailOption[]\n brand: ProductDetailBrand | null\n categories: ProductDetailCategory[]\n tags: ProductDetailTag[]\n images: ProductDetailImage[]\n videos: ProductDetailVideo[]\n /** Canonical product primary pointer (pool member). */\n primaryMediaItemId?: ProductDetailMediaValue\n listing: ProductDetailListing\n}\n\nexport type ProductDetailUnavailableReason =\n | 'not_found'\n | 'not_published'\n | 'feature_disabled'\n\nexport type ProductDetailResult =\n | { found: true; product: ProductDetail }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nexport type ProductDetailCatalogResult =\n | { found: true; product: ProductDetailCatalog }\n | { found: false; reason: ProductDetailUnavailableReason }\n\nconst PRODUCT_DETAIL_UNAVAILABLE_REASONS = new Set<string>([\n 'not_found',\n 'not_published',\n 'feature_disabled',\n])\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction readProductDetailUnavailableReason(\n value: unknown,\n): ProductDetailUnavailableReason | undefined {\n if (!isRecord(value)) return undefined\n\n const directReason = value.reason ?? value.code\n if (\n typeof directReason === 'string' &&\n PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)\n ) {\n return directReason as ProductDetailUnavailableReason\n }\n\n return readProductDetailUnavailableReason(value.body)\n}\n\nexport function productDetailResultFromError(\n error: unknown,\n): ProductDetailResult | undefined {\n if (!(error instanceof SDKError) || error.status !== 404) return undefined\n\n const reason = readProductDetailUnavailableReason(error.details)\n if (!reason) return undefined\n\n return { found: false, reason }\n}\n\nexport type ProductUpsertOptionSwatchInput = ProductUpsertSwatchInput\n\nexport type ProductUpsertOptionValueInput = {\n id?: string\n value: string\n slug?: string\n swatch?: ProductUpsertSwatchInput | null\n metadata?: unknown\n}\n\nexport type ProductUpsertOptionValuePayload = ProductUpsertOptionValueInput\n\nfunction rejectLegacyOptionValueSwatchColor(\n value: ProductUpsertOptionValueInput,\n): void {\n if (\n Object.prototype.hasOwnProperty.call(\n value as Record<string, unknown>,\n 'swatchColor',\n )\n ) {\n throw new TypeError(\n 'Product upsert option values no longer accept legacy flat \"swatchColor\"; use nested \"swatch\" instead.',\n )\n }\n}\n\nfunction normalizeProductUpsertOptionValue(\n value: ProductUpsertOptionValueInput,\n): ProductUpsertOptionValuePayload {\n rejectLegacyOptionValueSwatchColor(value)\n return value\n}\n\nfunction normalizeProductUpsertParams(\n params: ProductUpsertParams,\n): ProductUpsertInput {\n const options = params.options ?? []\n const variants = params.variants ?? []\n if (!options.length) {\n return { ...params, options, variants } as ProductUpsertInput\n }\n return {\n ...params,\n options: options.map((option) => ({\n ...option,\n values: option.values.map((value) =>\n normalizeProductUpsertOptionValue(value),\n ),\n })),\n variants,\n } as ProductUpsertInput\n}\n\nexport type ProductUpsertOptionInput = {\n id?: string\n title: string\n slug?: string\n values: ProductUpsertOptionValueInput[]\n}\n\nexport type ProductUpsertVariantOptionValue =\n | string\n | {\n valueSlug?: string\n valueId?: string\n value?: string\n }\n\nexport type ProductUpsertVariantInput = {\n id?: string\n optionValues?: Record<string, ProductUpsertVariantOptionValue> | string[]\n sku?: string | null\n title?: string | null\n price: number\n compareAtPrice?: number | null\n stock?: number\n isUnlimited?: boolean\n weight?: number | null\n requiresShipping?: boolean\n barcode?: string | null\n externalId?: string | null\n isActive?: boolean\n images?: string[]\n metadata?: unknown\n}\n\nexport type ProductUpsertParams = ProductUpsertInput\n\n/** Console `POST /api/products/upsert` field allowlist error reasons. */\nexport const PRODUCT_UPSERT_UNKNOWN_FIELD_REASON = 'unknown_field' as const\nexport const PRODUCT_UPSERT_READONLY_FIELD_REASON =\n 'product_field_readonly' as const\nexport const PRODUCT_GRAPH_CONFLICT_REASON = 'graph_conflict' as const\nexport const PRODUCT_GRAPH_REVISION_REQUIRED_REASON =\n 'graph_revision_required' as const\n\nexport type ProductUpsertFieldValidationErrorReason =\n | typeof PRODUCT_UPSERT_UNKNOWN_FIELD_REASON\n | typeof PRODUCT_UPSERT_READONLY_FIELD_REASON\n\n/** 400 response body when upsert rejects unknown or server-managed product fields. */\nexport type ProductUpsertFieldValidationErrorBody = {\n error: string\n reason: ProductUpsertFieldValidationErrorReason\n field: string\n requestId?: string\n}\n\nexport function isProductUpsertFieldValidationErrorBody(\n value: unknown,\n): value is ProductUpsertFieldValidationErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n const reason = body.reason\n return (\n typeof body.error === 'string' &&\n typeof body.field === 'string' &&\n (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON ||\n reason === PRODUCT_UPSERT_READONLY_FIELD_REASON)\n )\n}\n\nexport type ProductUpsertGraphConflictErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_CONFLICT_REASON\n currentGraphRevision: string\n currentGraphUpdatedAt: string\n requestId?: string\n}\n\nexport function isProductUpsertGraphConflictErrorBody(\n value: unknown,\n): value is ProductUpsertGraphConflictErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_CONFLICT_REASON &&\n typeof body.currentGraphRevision === 'string' &&\n typeof body.currentGraphUpdatedAt === 'string'\n )\n}\n\nexport type ProductUpsertGraphRevisionRequiredErrorBody = {\n error: string\n reason: typeof PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n requestId?: string\n}\n\nexport function isProductUpsertGraphRevisionRequiredErrorBody(\n value: unknown,\n): value is ProductUpsertGraphRevisionRequiredErrorBody {\n if (typeof value !== 'object' || value === null) return false\n const body = value as Record<string, unknown>\n return (\n typeof body.error === 'string' &&\n body.reason === PRODUCT_GRAPH_REVISION_REQUIRED_REASON\n )\n}\n\nexport type ProductUpsertResponse =\n | { ok: true; product: PublicProduct; listingProjectionStale: boolean }\n | {\n ok: false\n failedEntity: 'product' | 'option' | 'option-value' | 'variant'\n failedIndex?: number\n message: string\n }\n\nexport class ProductApi extends BaseApi {\n constructor(options: ProductApiOptions) {\n super('ProductApi', options)\n }\n\n /**\n * Check point-in-time stock availability for one or more product variants.\n * Results reflect available stock at the moment of the call and are not guaranteed\n * to remain available by the time an order is placed.\n */\n stockCheck(params: StockCheckParams): Promise<StockCheckResponse> {\n return this.request<StockCheckResponse>('/api/products/stock-check', params)\n }\n\n stockSnapshot(params: StockSnapshotParams): Promise<StockSnapshotResponse> {\n return this.request<StockSnapshotResponse>(\n stockSnapshotQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n listingGroups(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.request<ProductListingGroupsResponse>(\n listingGroupsQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n listingGroupsCatalog(\n params: ListingGroupsParams,\n ): Promise<ProductListingGroupsResponse> {\n return this.request<ProductListingGroupsResponse>(\n listingGroupsCatalogQuery(params),\n undefined,\n { method: 'GET' },\n )\n }\n\n /**\n * Fetch full product detail by slug or id.\n * Returns a discriminated result so storefronts can distinguish missing,\n * unpublished, and feature-disabled products.\n *\n * Only product-detail 404 responses carrying one of those allowlisted reasons\n * are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus\n * permission/auth errors such as tenant mismatch, continue to throw typed SDK\n * errors instead of being collapsed into a storefront absence result.\n */\n async detail(params: ProductDetailParams): Promise<ProductDetailResult> {\n try {\n const product = await this.request<ProductDetail>(\n productDetailQuery(params),\n undefined,\n { method: 'GET' },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n }\n\n async detailCatalog(\n params: ProductDetailParams,\n ): Promise<ProductDetailCatalogResult> {\n try {\n const product = await this.request<ProductDetailCatalog>(\n productDetailCatalogQuery(params),\n undefined,\n { method: 'GET' },\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n }\n\n /**\n * Atomically create or update a product together with its options,\n * option-values, and variants in a single transaction. Mirrors Shopify's\n * `productSet` shape and is the canonical write path for the MCP\n * `product-upsert` tool.\n */\n upsert(params: ProductUpsertParams): Promise<ProductUpsertResponse> {\n return this.request<ProductUpsertResponse>(\n '/api/products/upsert',\n normalizeProductUpsertParams(params),\n )\n }\n}\n","import type {\n Order,\n Transaction,\n Fulfillment,\n Return,\n} from '../../payload-types'\nimport { BaseApi, type RequestOptions, type ServerApiOptions } from './base-api'\n\nexport type OrderApiOptions = ServerApiOptions\n\n/** Header-only; never sent in the JSON body. */\nexport type WithIdempotencyKey<T> = T & {\n /**\n * Client-generated key for safe retries. Sent as `X-Idempotency-Key` when the\n * server endpoint supports HTTP idempotency.\n */\n idempotencyKey?: string\n}\n\nexport function idempotencyRequestOptions(\n idempotencyKey?: string,\n): RequestOptions | undefined {\n return idempotencyKey\n ? { headers: { 'X-Idempotency-Key': idempotencyKey } }\n : undefined\n}\n\nexport function splitIdempotencyKey<T extends { idempotencyKey?: string }>(\n params: T,\n): { body: Omit<T, 'idempotencyKey'>; idempotencyKey?: string } {\n const { idempotencyKey, ...body } = params\n return { body, idempotencyKey }\n}\n\nexport type CustomerSnapshot = {\n name?: string\n email: string\n phone?: string\n}\n\nexport type ReturnReason =\n | 'change_of_mind'\n | 'defective'\n | 'wrong_delivery'\n | 'damaged'\n | 'other'\n\nexport type ReturnItem = {\n orderItem: string | number\n quantity: number\n restockAction?: RestockAction\n restockingFee?: number\n}\n\ntype OrderCreateEntityID = string | number\n\nexport type CreateOrderItem = {\n product: OrderCreateEntityID\n variant: OrderCreateEntityID\n option: OrderCreateEntityID\n quantity: number\n /**\n * Compatibility input: the create-order endpoint accepts this, but the server\n * derives authoritative line pricing from the product variant.\n */\n unitPrice?: number\n /**\n * Compatibility input: the create-order endpoint accepts this, but the server\n * derives authoritative line totals from the product variant.\n */\n totalPrice?: number\n}\n\ntype CreateOrderLineItemsInput =\n | {\n orderItems: CreateOrderItem[]\n items?: never\n }\n | {\n /**\n * Storefront-facing alias for orderItems. The SDK serializes this to\n * orderItems for the existing create-order endpoint.\n */\n items: CreateOrderItem[]\n /**\n * @deprecated Use items for storefront-facing create-order inputs.\n */\n orderItems?: never\n }\n\ntype CreateOrderBodyBase = {\n orderNumber: string\n customer?: string\n customerSnapshot: CustomerSnapshot\n shippingAddress: Order['shippingAddress']\n totalAmount: number\n shippingAmount?: number\n pgPaymentId?: string\n discountCode?: string\n}\n\ntype CreateOrderRequestBody = CreateOrderBodyBase & {\n orderItems: CreateOrderItem[]\n}\n\nexport type CreateOrderParams = WithIdempotencyKey<\n CreateOrderBodyBase & CreateOrderLineItemsInput\n>\n\nfunction normalizeCreateOrderBody(\n params: CreateOrderParams,\n): CreateOrderRequestBody {\n if (params.items !== undefined) {\n const { idempotencyKey: _idempotencyKey, items, ...rest } = params\n return { ...rest, orderItems: items }\n }\n const { idempotencyKey: _idempotencyKey, ...body } = params\n return body\n}\n\nexport type UpdateOrderParams = {\n orderNumber: string\n status: 'confirmed'\n}\n\nexport type TransactionStatus = 'pending' | 'paid' | 'failed' | 'canceled'\n\nexport type UpdateTransactionParams = {\n pgPaymentId: string\n status: TransactionStatus\n paymentMethod?: string\n receiptUrl?: string\n paymentKey?: string\n amount?: number\n}\n\nexport type ConfirmPaymentParams = WithIdempotencyKey<{\n orderNumber?: string\n pgPaymentId: string\n pgProvider: string\n pgOrderId?: string\n amount: number\n currency?: string\n paymentMethod?: string\n receiptUrl?: string\n approvedAt?: string\n providerStatus?: string\n /** Provider event id; also used as idempotency key when `idempotencyKey` is omitted. */\n providerEventId?: string\n confirmationSource?:\n | 'provider_webhook'\n | 'provider_lookup'\n | 'provider_api_confirm'\n | 'manual_server'\n metadata?: Record<string, unknown>\n}>\n\nexport type ConfirmPaymentResponse = {\n orderId: string\n transactionId: string\n status: 'paid'\n alreadyConfirmed?: boolean\n}\n\nexport type CancelReasonCode =\n | 'customer'\n | 'inventory'\n | 'fraud'\n | 'declined'\n | 'staff'\n | 'other'\n\nexport type CancelOrderStatus =\n | 'pending'\n | 'paid'\n | 'failed'\n | 'canceled'\n | 'refunded'\n | 'preparing'\n | 'shipped'\n | 'delivered'\n | 'confirmed'\n | 'return_requested'\n | 'return_processing'\n | 'returned'\n\nexport type CancelOrderReconciliationStatus = Exclude<\n CancelOrderStatus,\n 'pending' | 'failed' | 'canceled'\n>\n\ntype CancelOrderResponseBase = {\n orderId: string\n}\n\ntype CancelOrderUnpaidCommittedResponseFields = {\n refundedAmount: 0\n providerRefunded: false\n}\n\ntype CancelOrderPaidCommittedResponseFields = {\n transactionId: string\n refundedAmount: 0\n providerRefunded: false\n refundPending: true\n}\n\ntype CancelOrderLegacyProviderRefundResponseFields = {\n transactionId: string\n refundedAmount: number\n refundSeq: number\n providerRefunded: true\n}\n\ntype CancelOrderAlreadyCanceledResponseFields = {\n refundedAmount: number\n providerRefunded: false\n}\n\ntype CancelOrderAlreadyCanceledRefundPendingResponseFields = {\n transactionId: string\n refundedAmount: number\n providerRefunded: false\n refundPending: true\n}\n\nexport type CancelOrderPaidCommittedResponse = CancelOrderResponseBase &\n CancelOrderPaidCommittedResponseFields & {\n status: 'canceled'\n cancelCommitted: true\n }\n\nexport type CancelOrderUnpaidCommittedResponse = CancelOrderResponseBase &\n CancelOrderUnpaidCommittedResponseFields & {\n status: 'canceled'\n cancelCommitted: true\n }\n\nexport type CancelOrderCommittedResponse =\n | CancelOrderPaidCommittedResponse\n | CancelOrderUnpaidCommittedResponse\n\nexport type CancelOrderAlreadyCanceledResponse = CancelOrderResponseBase &\n CancelOrderAlreadyCanceledResponseFields & {\n status: 'canceled'\n cancelCommitted: false\n alreadyCanceled: true\n }\n\nexport type CancelOrderAlreadyCanceledRefundPendingResponse =\n CancelOrderResponseBase &\n CancelOrderAlreadyCanceledRefundPendingResponseFields & {\n status: 'canceled'\n cancelCommitted: false\n alreadyCanceled: true\n }\n\n/** @deprecated Inline PG cancel reconciliation; retained for legacy API consumers. */\nexport type CancelOrderReconciliationResponse = CancelOrderResponseBase &\n CancelOrderLegacyProviderRefundResponseFields & {\n status: CancelOrderReconciliationStatus\n cancelCommitted: false\n reconciliationRequired: true\n }\n\nexport type CancelOrderResponse =\n | CancelOrderCommittedResponse\n | CancelOrderAlreadyCanceledResponse\n | CancelOrderAlreadyCanceledRefundPendingResponse\n | CancelOrderReconciliationResponse\n\nexport type CancelOrderParams = {\n orderNumber: string\n reasonCode?: CancelReasonCode\n reasonDetail?: string\n idempotencyKey?: string\n}\n\nexport type ResolveCancelRefundOutcome = 'succeeded' | 'failed'\n\nexport type ResolveCancelRefundSucceededParams = {\n orderNumber: string\n idempotencyKey: string\n outcome: 'succeeded'\n refundedAmount: number\n pgProvider: string\n pgRefundId: string\n}\n\nexport type ResolveCancelRefundFailedParams = {\n orderNumber: string\n idempotencyKey: string\n outcome: 'failed'\n refundedAmount: 0\n pgProvider: string\n pgRefundId?: string\n}\n\nexport type ResolveCancelRefundParams =\n | ResolveCancelRefundSucceededParams\n | ResolveCancelRefundFailedParams\n\nexport type ResolveCancelRefundSucceededResponse = {\n orderId: string\n transactionId: string\n refundTransactionId: string\n refundedAmount: number\n refundStatus: 'succeeded'\n transactionStatus: 'refunded'\n}\n\nexport type ResolveCancelRefundFailedResponse = {\n orderId: string\n transactionId: string\n refundTransactionId: string\n refundedAmount: 0\n refundStatus: 'failed'\n transactionStatus: 'paid'\n}\n\nexport type ResolveCancelRefundResponse =\n | ResolveCancelRefundSucceededResponse\n | ResolveCancelRefundFailedResponse\n\nexport type RestockAction = 'return_to_stock' | 'discard'\n\nexport type ReturnWithRefundItem = {\n orderItem: string | number\n quantity: number\n restockAction?: RestockAction\n restockingFee?: number\n}\n\nexport type ReturnWithRefundParams = WithIdempotencyKey<{\n orderNumber: string\n reason?: ReturnReason\n reasonDetail?: string\n returnItems: ReturnWithRefundItem[]\n refundAmount: number\n returnShippingFee?: number\n initialShippingRefundAmount?: number\n initialShippingRefundOverrideNote?: string\n pgPaymentId: string\n paymentKey?: string\n refundReceiptUrl?: string\n}>\n\nexport type CheckoutParams = WithIdempotencyKey<{\n cartId: string\n orderNumber: string\n customerSnapshot: CustomerSnapshot\n pgPaymentId?: string\n discountCode?: string\n}>\n\nexport type CreateFulfillmentParams = WithIdempotencyKey<{\n orderNumber: string\n fulfillmentOrderId?: string | number\n carrier?: string\n trackingNumber?: string\n items?: Array<{\n orderItem: string\n quantity: number\n }>\n}>\n\nexport type PrepareFulfillmentOrderParams = {\n orderNumber: string\n}\n\nexport type PrepareFulfillmentOrderResponse = {\n orderId: string\n fulfillmentOrders: Array<{ id: string; status: string }>\n}\n\nexport type UpdateFulfillmentParams = {\n fulfillmentId: string\n status?: 'shipped' | 'delivered' | 'failed'\n carrier?: string\n trackingNumber?: string\n}\n\nexport type BulkImportFulfillmentsParams = {\n items: Array<{\n orderNumber: string\n carrier: string\n trackingNumber: string\n }>\n}\n\nexport type BulkImportFulfillmentsResponse = {\n succeeded: Array<{ orderNumber: string; fulfillmentId: string }>\n failed: Array<{ orderNumber: string; error: string }>\n}\n\nexport type CreateReturnParams = WithIdempotencyKey<{\n orderNumber: string\n reason?: ReturnReason\n reasonDetail?: string\n returnItems: ReturnItem[]\n refundAmount: number\n returnShippingFee?: number\n initialShippingRefundAmount?: number\n initialShippingRefundOverrideNote?: string\n}>\n\nexport type UpdateReturnParams = {\n returnId: string\n status: 'processing' | 'approved' | 'rejected' | 'completed'\n}\n\nexport class OrderApi extends BaseApi {\n constructor(options: OrderApiOptions) {\n super('OrderApi', options)\n }\n\n createOrder(params: CreateOrderParams): Promise<Order> {\n const { idempotencyKey } = params\n const normalizedBody = normalizeCreateOrderBody(params)\n return this.request<Order>(\n '/api/orders/create',\n normalizedBody,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n updateOrder(params: UpdateOrderParams): Promise<Order> {\n return this.request<Order>('/api/orders/update', params)\n }\n\n updateTransaction(params: UpdateTransactionParams): Promise<Transaction> {\n return this.request<Transaction>('/api/transactions/update', params)\n }\n\n confirmPayment(\n params: ConfirmPaymentParams,\n ): Promise<ConfirmPaymentResponse> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n const headerKey = idempotencyKey ?? params.providerEventId\n return this.request<ConfirmPaymentResponse>(\n '/api/orders/confirm-payment',\n body,\n idempotencyRequestOptions(headerKey),\n )\n }\n\n cancelOrder(params: CancelOrderParams): Promise<CancelOrderResponse> {\n const { idempotencyKey } = params\n const body = {\n orderNumber: params.orderNumber,\n reasonCode: params.reasonCode,\n reasonDetail: params.reasonDetail,\n }\n return this.request<CancelOrderResponse>(\n '/api/orders/cancel',\n body,\n idempotencyKey\n ? { headers: { 'X-Idempotency-Key': idempotencyKey } }\n : undefined,\n )\n }\n\n resolveCancelRefund(\n params: ResolveCancelRefundParams,\n ): Promise<ResolveCancelRefundResponse> {\n return this.request<ResolveCancelRefundResponse>(\n '/api/orders/resolve-cancel-refund',\n {\n orderNumber: params.orderNumber,\n idempotencyKey: params.idempotencyKey,\n outcome: params.outcome,\n refundedAmount: params.refundedAmount,\n pgProvider: params.pgProvider,\n ...(params.pgRefundId ? { pgRefundId: params.pgRefundId } : {}),\n },\n idempotencyRequestOptions(params.idempotencyKey),\n )\n }\n\n checkout(params: CheckoutParams): Promise<Order> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Order>(\n '/api/orders/checkout',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n createFulfillment(params: CreateFulfillmentParams): Promise<Fulfillment> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Fulfillment>(\n '/api/orders/create-fulfillment',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n prepareFulfillmentOrder(\n params: PrepareFulfillmentOrderParams,\n ): Promise<PrepareFulfillmentOrderResponse> {\n return this.request<PrepareFulfillmentOrderResponse>(\n '/api/fulfillment-orders/prepare-fulfillment-order',\n params,\n )\n }\n\n updateFulfillment(params: UpdateFulfillmentParams): Promise<Fulfillment> {\n return this.request<Fulfillment>('/api/orders/update-fulfillment', params)\n }\n\n bulkImportFulfillments(\n params: BulkImportFulfillmentsParams,\n ): Promise<BulkImportFulfillmentsResponse> {\n return this.request<BulkImportFulfillmentsResponse>(\n '/api/fulfillments/bulk-import',\n params,\n )\n }\n\n returnWithRefund(\n params: ReturnWithRefundParams,\n ): Promise<{ return: Return; transaction: Transaction | null }> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<{ return: Return; transaction: Transaction | null }>(\n '/api/returns/return-refund',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n createReturn(params: CreateReturnParams): Promise<Return> {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return this.request<Return>(\n '/api/returns/create',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n }\n\n updateReturn(params: UpdateReturnParams): Promise<Return> {\n return this.request<Return>('/api/returns/update', params)\n }\n}\n","import { CartApi } from '../api/cart-api'\nimport { CustomerScopedApi } from '../api/customer-scoped-api'\nimport { productDetailResultFromError } from '../api/product-api'\nimport {\n listingGroupsCatalogQuery,\n listingGroupsQuery,\n productDetailCatalogQuery,\n productDetailQuery,\n stockSnapshotQuery,\n} from '../internal/utils/query-string'\nimport type { CustomerAuth } from '../customer/customer-auth'\nimport type {\n AddItemParams,\n UpdateItemParams,\n RemoveItemParams,\n ApplyDiscountParams,\n RemoveDiscountParams,\n ClearCartParams,\n} from '../api/cart-api'\nimport type {\n StockCheckParams,\n StockCheckResponse,\n StockSnapshotParams,\n StockSnapshotResponse,\n ListingGroupsParams,\n ProductListingGroupsResponse,\n ProductDetailParams,\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailCatalogResult,\n ProductDetailResult,\n} from '../api/product-api'\nimport type { ValidateDiscountParams, ValidateDiscountResult } from '../api/discount-api'\nimport type { CalculateShippingParams, CalculateShippingResult } from '../api/shipping-api'\nimport {\n idempotencyRequestOptions,\n splitIdempotencyKey,\n type CheckoutParams,\n} from '../api/order-api'\nimport type { RequestOptions } from '../api/base-api'\nimport type { Cart, CartItem, Order } from '../../payload-types'\nimport type { PayloadFindResponse } from '../client/types'\n\nclass BrowserCommerceApi extends CustomerScopedApi {\n post<T>(\n endpoint: string,\n body: unknown,\n requestOptions?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body,\n headers: requestOptions?.headers,\n })\n }\n\n get<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET' })\n }\n}\n\nexport interface CommerceClientOptions {\n publishableKey: string\n apiUrl?: string\n customerToken: () => string | null\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n customerAuth: CustomerAuth\n}\n\nexport class CommerceClient {\n readonly product: {\n stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>\n stockSnapshot: (params: StockSnapshotParams) => Promise<StockSnapshotResponse>\n listingGroups: (params: ListingGroupsParams) => Promise<ProductListingGroupsResponse>\n listingGroupsCatalog: (\n params: ListingGroupsParams,\n ) => Promise<ProductListingGroupsResponse>\n detail: (params: ProductDetailParams) => Promise<ProductDetailResult>\n detailCatalog: (params: ProductDetailParams) => Promise<ProductDetailCatalogResult>\n }\n\n readonly cart: {\n get: (cartId: string) => Promise<Cart>\n addItem: (params: AddItemParams) => Promise<CartItem>\n updateItem: (params: UpdateItemParams) => Promise<CartItem>\n removeItem: (params: RemoveItemParams) => Promise<{ success: boolean }>\n applyDiscount: (params: ApplyDiscountParams) => Promise<Cart>\n removeDiscount: (params: RemoveDiscountParams) => Promise<Cart>\n clear: (params: ClearCartParams) => Promise<{ success: boolean }>\n }\n\n readonly orders: {\n checkout: (params: CheckoutParams) => Promise<Order>\n listMine: (options?: {\n page?: number\n limit?: number\n status?: string\n }) => Promise<PayloadFindResponse<Order>>\n }\n\n readonly discounts: {\n validate: (params: ValidateDiscountParams) => Promise<ValidateDiscountResult>\n }\n\n readonly shipping: {\n calculate: (params: CalculateShippingParams) => Promise<CalculateShippingResult>\n }\n\n constructor(options: CommerceClientOptions) {\n const cartApi = new CartApi({\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n const api = new BrowserCommerceApi('CommerceClient', {\n publishableKey: options.publishableKey,\n apiUrl: options.apiUrl,\n customerToken: options.customerToken,\n onUnauthorized: options.onUnauthorized,\n onRequestId: options.onRequestId,\n })\n\n this.product = {\n stockCheck: (params) => api.post<StockCheckResponse>('/api/products/stock-check', params),\n stockSnapshot: (params) =>\n api.get<StockSnapshotResponse>(stockSnapshotQuery(params)),\n listingGroups: (params) =>\n api.get<ProductListingGroupsResponse>(listingGroupsQuery(params)),\n listingGroupsCatalog: (params) =>\n api.get<ProductListingGroupsResponse>(listingGroupsCatalogQuery(params)),\n detail: async (params) => {\n try {\n const product = await api.get<ProductDetail>(productDetailQuery(params))\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult) return notFoundResult\n throw err\n }\n },\n detailCatalog: async (params) => {\n try {\n const product = await api.get<ProductDetailCatalog>(\n productDetailCatalogQuery(params),\n )\n return { found: true, product }\n } catch (err) {\n const notFoundResult = productDetailResultFromError(err)\n if (notFoundResult?.found === false) return notFoundResult\n throw err\n }\n },\n }\n\n this.cart = {\n get: cartApi.getCart.bind(cartApi),\n addItem: cartApi.addItem.bind(cartApi),\n updateItem: cartApi.updateItem.bind(cartApi),\n removeItem: cartApi.removeItem.bind(cartApi),\n applyDiscount: cartApi.applyDiscount.bind(cartApi),\n removeDiscount: cartApi.removeDiscount.bind(cartApi),\n clear: cartApi.clearCart.bind(cartApi),\n }\n\n this.orders = {\n checkout: (params) => {\n const { body, idempotencyKey } = splitIdempotencyKey(params)\n return api.post<Order>(\n '/api/orders/checkout',\n body,\n idempotencyRequestOptions(idempotencyKey),\n )\n },\n listMine: (params) => options.customerAuth.getMyOrders(params),\n }\n\n this.discounts = {\n validate: (params) => api.post<ValidateDiscountResult>('/api/discounts/validate', params),\n }\n\n this.shipping = {\n calculate: (params) => api.post<CalculateShippingResult>('/api/shipping-policies/calculate', params),\n }\n }\n}\n","import { parseApiResponse } from '../api/parse-response'\nimport { SDKError } from '../internal/errors'\nimport { httpFetch, requirePublishableKeyForSecret } from '../internal/utils'\n\nexport interface EventsClientOptions {\n publishableKey?: string\n apiUrl?: string\n customerToken?: string | (() => string | null)\n onUnauthorized?: () => Promise<string | null>\n onRequestId?: (id: string | null) => void\n}\n\nexport type EventsDateParam = string | Date\n\nexport interface EventsRangeParams {\n start: EventsDateParam\n end: EventsDateParam\n limit?: number\n page?: number\n calendar?: string | string[]\n calendarSlug?: string | string[]\n category?: string | string[]\n categorySlug?: string | string[]\n tag?: string | string[]\n tagSlug?: string | string[]\n}\n\nexport interface EventsTaxonomyItem {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n color?: string | null\n}\n\nexport interface EventsCalendarItem extends EventsTaxonomyItem {\n timezone?: string | null\n visibility?: string | null\n}\n\nexport interface EventsLocation {\n type?: string | null\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n onlineNote?: string | null\n}\n\nexport interface EventsOccurrenceLocation {\n name?: string | null\n address?: string | null\n onlineUrl?: string | null\n note?: string | null\n}\n\nexport interface EventsExternalSource {\n provider?: string | null\n url?: string | null\n}\n\nexport interface EventsRangeEvent {\n id: string | number\n title?: string | null\n slug?: string | null\n description?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n visibility?: string | null\n sourceType?: string | null\n registrationPolicy?: string | null\n externalRegistrationUrl?: string | null\n externalSource: EventsExternalSource | null\n location: EventsLocation | null\n calendars: EventsCalendarItem[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n}\n\nexport interface EventsRangeOccurrence {\n id: string | number\n instanceKey?: string | null\n startsAt?: string | null\n endsAt?: string | null\n timezone?: string | null\n isAllDay: boolean\n status?: string | null\n capacity?: number\n registrationCount?: number\n waitlistCount?: number\n locationOverride: EventsOccurrenceLocation | null\n event: EventsRangeEvent\n}\n\nexport interface EventsRangeResponse {\n range: {\n start: string\n end: string\n }\n docs: EventsRangeOccurrence[]\n calendars: EventsCalendarItem[]\n events: EventsRangeEvent[]\n categories: EventsTaxonomyItem[]\n tags: EventsTaxonomyItem[]\n totalDocs: number\n limit: number\n page: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n}\n\nexport interface EventRegistrationAttendeeInput {\n name?: string\n email?: string\n phone?: string\n}\n\nexport interface EventRegistrationAnswerInput {\n question: string\n answer?: string\n}\n\nexport interface EventRegistrationRegisterParams {\n event: string\n occurrence: string\n quantity?: number\n attendee?: EventRegistrationAttendeeInput\n answers?: EventRegistrationAnswerInput[]\n}\n\nexport interface EventRegistrationPublic {\n id?: string | number\n event?: unknown\n occurrence?: unknown\n registrationStatus?: string | null\n attendanceStatus?: string | null\n quantity?: number | null\n guestTokenExpiresAt?: string | null\n}\n\nexport interface EventGuestRegistration extends EventRegistrationPublic {\n attendee: {\n name: string | null\n email: string | null\n phone: string | null\n } | null\n attendeeEmail: string | null\n answers: Array<{ question: string; answer?: string }>\n}\n\nexport interface EventRegistrationRegisterResponse {\n registration: EventRegistrationPublic\n guestToken: string\n guestTokenExpiresAt: string\n}\n\nexport interface EventGuestRegistrationResponse {\n registration: EventGuestRegistration\n}\n\nexport interface EventGuestCancelParams {\n reason?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\nexport class EventsClient {\n private readonly publishableKey: string\n private readonly apiUrl?: string\n private readonly customerToken?: string | (() => string | null)\n private readonly onUnauthorized?: () => Promise<string | null>\n private readonly onRequestId?: (id: string | null) => void\n\n constructor(options: EventsClientOptions) {\n const secretKey = (options as { secretKey?: string }).secretKey\n this.publishableKey = requirePublishableKeyForSecret(\n 'EventsClient',\n options.publishableKey,\n secretKey,\n )\n this.apiUrl = options.apiUrl\n this.customerToken = options.customerToken\n this.onUnauthorized = options.onUnauthorized\n this.onRequestId = options.onRequestId\n }\n\n getRange(params: EventsRangeParams): Promise<EventsRangeResponse> {\n return this.execute<EventsRangeResponse>(\n buildRangeEndpoint(params),\n 'GET',\n undefined,\n { useCustomerAuth: false },\n )\n }\n\n register(\n params: EventRegistrationRegisterParams,\n ): Promise<EventRegistrationRegisterResponse> {\n return this.execute<EventRegistrationRegisterResponse>(\n '/api/event-registrations/register',\n 'POST',\n buildRegistrationRequestBody(params),\n { useCustomerAuth: true },\n )\n }\n\n getGuestRegistration(token: string): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n '/api/event-registrations/guest/lookup',\n 'POST',\n { token },\n { useCustomerAuth: false },\n )\n }\n\n cancelGuestRegistration(\n token: string,\n params: EventGuestCancelParams = {},\n ): Promise<EventGuestRegistrationResponse> {\n return this.execute<EventGuestRegistrationResponse>(\n '/api/event-registrations/guest/cancel',\n 'POST',\n buildGuestCancelRequestBody(token, params),\n { useCustomerAuth: false },\n )\n }\n\n private async execute<T>(\n endpoint: string,\n method: HttpMethod,\n body?: unknown,\n options: { useCustomerAuth?: boolean } = {},\n ): Promise<T> {\n const useCustomerAuth = options.useCustomerAuth === true\n const token = useCustomerAuth\n ? typeof this.customerToken === 'function'\n ? this.customerToken()\n : this.customerToken\n : undefined\n\n try {\n const response = await httpFetch(endpoint, {\n method,\n apiUrl: this.apiUrl,\n publishableKey: this.publishableKey,\n ...(useCustomerAuth && token ? { customerToken: token } : {}),\n ...(useCustomerAuth &&\n token &&\n this.onUnauthorized && { onUnauthorized: this.onUnauthorized }),\n ...(body !== undefined && { body: JSON.stringify(body) }),\n })\n\n this.onRequestId?.(response.headers.get('x-request-id') ?? null)\n return parseApiResponse<T>(response, endpoint)\n } catch (err) {\n const id = err instanceof SDKError ? (err.requestId ?? null) : null\n this.onRequestId?.(id)\n throw err\n }\n }\n}\n\nfunction buildRegistrationRequestBody(\n params: EventRegistrationRegisterParams,\n): EventRegistrationRegisterParams {\n return {\n event: params.event,\n occurrence: params.occurrence,\n ...(params.quantity !== undefined && { quantity: params.quantity }),\n ...(params.attendee !== undefined && { attendee: params.attendee }),\n ...(params.answers !== undefined && { answers: params.answers }),\n }\n}\n\nfunction buildGuestCancelRequestBody(\n token: string,\n params: EventGuestCancelParams,\n): { token: string; reason?: string } {\n return {\n token,\n ...(params.reason !== undefined && { reason: params.reason }),\n }\n}\n\nfunction buildRangeEndpoint(params: EventsRangeParams): string {\n const urlParams = new URLSearchParams()\n urlParams.set('start', formatDateParam(params.start))\n urlParams.set('end', formatDateParam(params.end))\n if (params.limit !== undefined) urlParams.set('limit', String(params.limit))\n if (params.page !== undefined) urlParams.set('page', String(params.page))\n appendValues(urlParams, 'calendar', params.calendar)\n appendValues(urlParams, 'calendarSlug', params.calendarSlug)\n appendValues(urlParams, 'category', params.category)\n appendValues(urlParams, 'categorySlug', params.categorySlug)\n appendValues(urlParams, 'tag', params.tag)\n appendValues(urlParams, 'tagSlug', params.tagSlug)\n return `/api/event-occurrences/range?${urlParams.toString()}`\n}\n\nfunction formatDateParam(value: EventsDateParam): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nfunction appendValues(\n params: URLSearchParams,\n key: string,\n value: string | string[] | undefined,\n): void {\n if (value === undefined) return\n const values = Array.isArray(value) ? value : [value]\n for (const entry of values) {\n if (entry) params.append(key, entry)\n }\n}\n","import { ReadOnlyCollectionClient } from '../collection/collection-client'\nimport { CommunityClient } from '../community/community-client'\nimport { CustomerNamespace } from '../customer/customer-namespace'\nimport { CommerceClient } from '../commerce/commerce-client'\nimport { EventsClient } from '../events/events-client'\nimport { createConfigError } from '../internal/errors'\nimport {\n type ClientConfig,\n type ClientState,\n type ClientMetadata,\n} from './types'\n\nexport default class Client {\n commerce: CommerceClient\n community: CommunityClient\n events: EventsClient\n customer: CustomerNamespace\n collections: ReadOnlyCollectionClient\n lastRequestId: string | null = null\n\n protected state: ClientState\n protected config: ClientConfig\n\n constructor(options: ClientConfig) {\n const publishableKey = options.publishableKey\n if (!publishableKey) {\n throw createConfigError('publishableKey is required.')\n }\n\n this.config = { ...options, publishableKey }\n\n const metadata: ClientMetadata = {\n timestamp: Date.now(),\n userAgent:\n typeof window !== 'undefined' ? window.navigator?.userAgent : 'Node.js',\n }\n\n this.state = { metadata }\n\n this.customer = new CustomerNamespace(\n this.config.publishableKey,\n options.customer,\n this.config.apiUrl,\n )\n\n const onUnauthorized = async (): Promise<string | null> => {\n try {\n const result = await this.customer.auth.refreshToken()\n return result.token ?? null\n } catch {\n return null\n }\n }\n\n const onRequestId = (id: string | null) => {\n this.lastRequestId = id\n }\n\n this.commerce = new CommerceClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n customerAuth: this.customer.auth,\n })\n\n this.community = new CommunityClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.events = new EventsClient({\n publishableKey: this.config.publishableKey,\n apiUrl: this.config.apiUrl,\n customerToken: () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n })\n\n this.collections = new ReadOnlyCollectionClient(\n this.config.publishableKey,\n undefined,\n () => this.customer.auth.getToken(),\n onUnauthorized,\n onRequestId,\n this.config.apiUrl,\n )\n }\n\n getState(): ClientState {\n return { ...this.state }\n }\n\n getConfig(): ClientConfig {\n return { ...this.config }\n }\n}\n\n/**\n * Create an SDK client. Works in both browser and server environments.\n * Read-only collection queries + customer auth (cart, login, profile).\n * Use the server subpath when you need full CRUD with server credentials.\n */\nexport function createClient(options: ClientConfig): Client {\n return new Client(options)\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\n\nexport type DiscountApiOptions = ServerApiOptions\n\nexport type ValidateDiscountParams = {\n code: string\n orderAmount: number\n}\n\nexport type ValidateDiscountResult = {\n valid: boolean\n code: string\n type?: 'percentage' | 'fixed_amount' | 'free_shipping' | 'tiered'\n discountAmount: number\n freeShipping?: boolean\n reason?: string\n}\n\nexport class DiscountApi extends BaseApi {\n constructor(options: DiscountApiOptions) {\n super('DiscountApi', options)\n }\n\n validate(params: ValidateDiscountParams): Promise<ValidateDiscountResult> {\n return this.request<ValidateDiscountResult>('/api/discounts/validate', params)\n }\n}\n","import { BaseApi, type ServerApiOptions } from './base-api'\n\nexport type ShippingApiOptions = ServerApiOptions\n\nexport type CalculateShippingParams = {\n shippingPolicyId?: string\n orderAmount: number\n postalCode?: string\n}\n\nexport type CalculateShippingResult = {\n shippingAmount: number\n baseShippingAmount: number\n extraShippingAmount: number\n freeShipping: boolean\n freeShippingMinAmount: number | null\n isJeju: boolean\n isRemoteIsland: boolean\n}\n\nexport class ShippingApi extends BaseApi {\n constructor(options: ShippingApiOptions) {\n super('ShippingApi', options)\n }\n\n calculate(params: CalculateShippingParams): Promise<CalculateShippingResult> {\n return this.request<CalculateShippingResult>('/api/shipping-policies/calculate', params)\n }\n}\n","import type {\n ProductDetail,\n ProductDetailCatalog,\n ProductDetailVariant,\n} from '../api/product-api'\nimport type { StockSnapshotResponse } from '../api/product-api'\n\nexport type ProductDetailStockMergeStatus = 'complete' | 'partial'\n\nexport interface MergedProductDetailResult {\n stockMergeStatus: ProductDetailStockMergeStatus\n product: ProductDetail\n}\n\nexport function mergeProductDetailWithStock(\n catalog: ProductDetailCatalog,\n snapshot: StockSnapshotResponse,\n): MergedProductDetailResult {\n const snapshotByVariantId = new Map(\n snapshot.snapshots.map((item) => [item.variantId, item]),\n )\n\n let missingSnapshotCount = 0\n const variants: ProductDetailVariant[] = catalog.variants.map((variant) => {\n const snap = snapshotByVariantId.get(String(variant.id))\n if (!snap) {\n missingSnapshotCount += 1\n return { ...variant, stock: 0, reservedStock: 0 }\n }\n\n return {\n ...variant,\n stock: snap.isUnlimited ? 0 : snap.availableStock,\n reservedStock: 0,\n }\n })\n\n const trackedVariants = variants.filter((variant) => !variant.isUnlimited)\n const totalInventory =\n trackedVariants.length === 0\n ? null\n : trackedVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0)),\n 0,\n )\n\n const { liveStockRequired: _liveStockRequired, ...listingBase } = catalog.listing\n const availableForSale = snapshot.snapshots.some(\n (item) => item.status === 'available' && item.availableForSale,\n )\n\n return {\n stockMergeStatus: missingSnapshotCount === 0 ? 'complete' : 'partial',\n product: {\n ...catalog,\n product: { ...catalog.product, totalInventory },\n variants,\n listing: { ...listingBase, availableForSale },\n },\n }\n}\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Semantic event type for v1 commerce notification webhooks. */\nexport const COMMERCE_NOTIFICATION_EVENT_TYPE = 'commerce.notification' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange = WebhookOrderChange | WebhookCommerceNotificationChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n typeof obj.operation === 'string' &&\n obj.operation.length > 0 &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nexport const COMMERCE_NOTIFICATION_OPERATION = 'notification' as const\n\nexport const COMMERCE_NOTIFICATION_EVENTS = [\n 'orderPaid',\n 'orderCanceled',\n 'fulfillmentShipped',\n 'orderDelivered',\n 'returnRequested',\n 'returnCompleted',\n] as const\n\nexport type CommerceNotificationEventName =\n (typeof COMMERCE_NOTIFICATION_EVENTS)[number]\n\nexport type CommerceNotificationSourceCollection =\n | 'orders'\n | 'fulfillments'\n | 'returns'\n\nexport type CommerceNotificationSource = {\n collection: CommerceNotificationSourceCollection\n id: string | number\n}\n\nexport type CommerceNotificationData = {\n source?: CommerceNotificationSource\n orderId?: string | number\n orderNumber?: string\n status?: string\n totalAmount?: number\n currency?: string\n fulfillmentId?: string | number\n fulfillmentStatus?: string\n shippedAt?: string\n returnId?: string | number\n returnStatus?: string\n refundAmount?: number\n completedAt?: string\n}\n\nexport type CommerceNotification = {\n event: CommerceNotificationEventName\n intentId: string\n dedupeKey: string\n orderId?: string\n fulfillmentId?: string\n returnId?: string\n}\n\nexport type WebhookCommerceNotificationChange = {\n type: 'notification'\n source: 'commerce-notifications'\n event: CommerceNotificationEventName\n sourceCollection: CommerceNotificationSourceCollection\n sourceId: string | number\n}\n\n/** Webhook event emitted for v1 commerce notification deliveries. */\nexport type CommerceNotificationWebhookEvent = WebhookEvent<\n CommerceNotificationSourceCollection,\n CommerceNotificationData\n> & {\n operation: typeof COMMERCE_NOTIFICATION_OPERATION\n eventType: typeof COMMERCE_NOTIFICATION_EVENT_TYPE\n change?: WebhookCommerceNotificationChange\n notification: CommerceNotification\n}\n\nexport type CommerceEmailChannel = 'webhook' | 'provider'\n\nexport type CommerceEmailEventConfig = {\n enabled: boolean\n channel: CommerceEmailChannel\n template?: string\n}\n\nexport type CommerceEmailConfig = {\n version: 1\n commerceNotifications: Partial<\n Record<CommerceNotificationEventName, CommerceEmailEventConfig>\n >\n}\n\nexport type CommerceNotificationHandlerContext = {\n event: CommerceNotificationWebhookEvent\n idempotencyKey: string\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport type CommerceNotificationEventHandlers = Partial<\n Record<\n CommerceNotificationEventName,\n (context: CommerceNotificationHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nexport type CommerceEmailHandlerContext = CommerceNotificationHandlerContext\n\nexport type CommerceEmailEventHandlers = CommerceNotificationEventHandlers\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\nfunction isCommerceNotificationEventName(\n value: unknown,\n): value is CommerceNotificationEventName {\n return (\n typeof value === 'string' &&\n (COMMERCE_NOTIFICATION_EVENTS as readonly string[]).includes(value)\n )\n}\n\nfunction isCommerceNotificationSourceCollection(\n value: unknown,\n): value is CommerceNotificationSourceCollection {\n return value === 'orders' || value === 'fulfillments' || value === 'returns'\n}\n\nfunction isCommerceNotificationData(\n value: unknown,\n): value is CommerceNotificationData {\n if (!isRecord(value)) return false\n if (\n value.source !== undefined &&\n (!isRecord(value.source) ||\n !isCommerceNotificationSourceCollection(value.source.collection) ||\n !isStringOrNumber(value.source.id))\n ) {\n return false\n }\n\n return (\n (value.orderId === undefined || isStringOrNumber(value.orderId)) &&\n (value.orderNumber === undefined || typeof value.orderNumber === 'string') &&\n (value.status === undefined || typeof value.status === 'string') &&\n (value.totalAmount === undefined || typeof value.totalAmount === 'number') &&\n (value.currency === undefined || typeof value.currency === 'string') &&\n (value.fulfillmentId === undefined ||\n isStringOrNumber(value.fulfillmentId)) &&\n (value.fulfillmentStatus === undefined ||\n typeof value.fulfillmentStatus === 'string') &&\n (value.shippedAt === undefined || typeof value.shippedAt === 'string') &&\n (value.returnId === undefined || isStringOrNumber(value.returnId)) &&\n (value.returnStatus === undefined ||\n typeof value.returnStatus === 'string') &&\n (value.refundAmount === undefined ||\n typeof value.refundAmount === 'number') &&\n (value.completedAt === undefined || typeof value.completedAt === 'string')\n )\n}\n\nfunction isCommerceNotification(\n value: unknown,\n): value is CommerceNotification {\n if (!isRecord(value)) return false\n return (\n isCommerceNotificationEventName(value.event) &&\n typeof value.intentId === 'string' &&\n value.intentId.length > 0 &&\n typeof value.dedupeKey === 'string' &&\n value.dedupeKey.length > 0 &&\n (value.orderId === undefined || typeof value.orderId === 'string') &&\n (value.fulfillmentId === undefined ||\n typeof value.fulfillmentId === 'string') &&\n (value.returnId === undefined || typeof value.returnId === 'string')\n )\n}\n\nfunction isWebhookCommerceNotificationChange(\n value: unknown,\n): value is WebhookCommerceNotificationChange {\n if (!isRecord(value)) return false\n return (\n value.type === 'notification' &&\n value.source === 'commerce-notifications' &&\n isCommerceNotificationEventName(value.event) &&\n isCommerceNotificationSourceCollection(value.sourceCollection) &&\n isStringOrNumber(value.sourceId)\n )\n}\n\nfunction matchesOptionalId(\n actual: string | number | undefined,\n expected: string | number | undefined,\n): boolean {\n return actual === undefined || expected === undefined || actual === expected\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * Returns true for semantic commerce notification webhooks.\n *\n * Use `notification.intentId` and `notification.dedupeKey` for semantic\n * idempotency. `deliveryId`, when present, identifies a delivery attempt for\n * observability and is not the semantic notification identity.\n */\nexport function isCommerceNotificationWebhookEvent(\n event: unknown,\n): event is CommerceNotificationWebhookEvent {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== COMMERCE_NOTIFICATION_OPERATION ||\n event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE ||\n !isCommerceNotificationData(event.data) ||\n !isCommerceNotification((event as { notification?: unknown }).notification)\n ) {\n return false\n }\n\n const notification = (event as unknown as CommerceNotificationWebhookEvent)\n .notification\n const data = event.data\n const change = event.change\n const sourceCollection = data.source?.collection ?? event.collection\n const sourceId = data.source?.id\n\n if (!isCommerceNotificationSourceCollection(sourceCollection)) return false\n if (data.source !== undefined && event.collection !== data.source.collection) {\n return false\n }\n\n if (change !== undefined) {\n if (!isWebhookCommerceNotificationChange(change)) return false\n if (change.sourceCollection !== sourceCollection) return false\n if (change.event !== notification.event) return false\n if (!matchesOptionalId(change.sourceId, sourceId)) return false\n }\n const changeSourceId = isWebhookCommerceNotificationChange(change)\n ? change.sourceId\n : undefined\n\n if (\n notification.event === 'orderPaid' ||\n notification.event === 'orderCanceled' ||\n notification.event === 'orderDelivered'\n ) {\n return (\n sourceCollection === 'orders' &&\n typeof notification.orderId === 'string' &&\n notification.orderId.length > 0 &&\n matchesOptionalId(data.orderId, sourceId) &&\n matchesOptionalId(notification.orderId, sourceId) &&\n matchesOptionalId(data.orderId, notification.orderId) &&\n matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId)\n )\n }\n\n if (notification.event === 'fulfillmentShipped') {\n return (\n sourceCollection === 'fulfillments' &&\n matchesOptionalId(data.fulfillmentId, sourceId) &&\n typeof notification.fulfillmentId === 'string' &&\n notification.fulfillmentId.length > 0 &&\n matchesOptionalId(notification.fulfillmentId, sourceId) &&\n matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) &&\n matchesOptionalId(changeSourceId, notification.fulfillmentId)\n )\n }\n\n if (\n notification.event === 'returnRequested' ||\n notification.event === 'returnCompleted'\n ) {\n return (\n sourceCollection === 'returns' &&\n matchesOptionalId(data.returnId, sourceId) &&\n typeof notification.returnId === 'string' &&\n notification.returnId.length > 0 &&\n matchesOptionalId(notification.returnId, sourceId) &&\n matchesOptionalId(data.returnId, notification.returnId) &&\n matchesOptionalId(changeSourceId, notification.returnId)\n )\n }\n\n return false\n}\n\nexport function getCommerceNotificationIdempotencyKey(\n event: Pick<CommerceNotificationWebhookEvent, 'notification'>,\n): string {\n return `${event.notification.intentId}:${event.notification.dedupeKey}`\n}\n\nexport function defineCommerceEmailConfig<TConfig extends CommerceEmailConfig>(\n config: TConfig,\n): TConfig {\n return config\n}\n\nexport function createCommerceNotificationWebhookHandler(\n handlers: CommerceNotificationEventHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (!isCommerceNotificationWebhookEvent(event)) {\n await handlers.unhandled?.(event)\n return\n }\n\n const handler = handlers[event.notification.event]\n if (!handler) {\n await handlers.unhandled?.(event)\n return\n }\n\n await handler({\n event,\n idempotencyKey: getCommerceNotificationIdempotencyKey(event),\n })\n }\n}\n\nexport function createCommerceEmailWebhookHandler(\n handlers: CommerceEmailEventHandlers,\n): WebhookHandler<string, unknown> {\n return createCommerceNotificationWebhookHandler(handlers)\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n | typeof COMMERCE_NOTIFICATION_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n // Validate and convert hex signature to Uint8Array\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n // crypto.subtle.verify performs constant-time comparison internally\n return crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n encoder.encode(`${timestamp}.${deliveryId}.${payload}`),\n )\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const toleranceSeconds = options.toleranceSeconds ?? 300\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(\n rawBody,\n options.secret,\n signature,\n timestamp,\n deliveryId,\n ))\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n","import type { Config } from '../../payload-types'\n\n/**\n * Collection type derived from Payload Config.\n * This ensures type safety and automatic synchronization with payload-types.ts\n */\nexport type Collection = keyof Config['collections']\n\n/**\n * Internal collections that should not be exposed via SDK.\n * Includes Payload system collections and admin-only collections.\n */\nexport const INTERNAL_COLLECTIONS = [\n 'users',\n 'payload-kv',\n 'payload-locked-documents',\n 'payload-preferences',\n 'payload-migrations',\n 'payload-folders',\n 'field-configs',\n 'system-media',\n 'track-assets',\n 'audiences',\n 'email-logs',\n 'api-usage',\n 'tenant-analytics-daily',\n 'tenant-web-analytics-config',\n 'analytics-event-schemas',\n 'subscriptions',\n 'billing-history',\n 'inventory-reservations',\n 'commerce-notification-intents',\n 'product-collection-items',\n 'order-status-logs',\n 'api-keys',\n 'personal-access-tokens',\n 'tenant-entitlements',\n 'tenant-purge-jobs',\n 'direct-upload-sessions',\n 'webhook-events',\n 'webhook-deliveries',\n 'audit-logs',\n 'plans',\n 'webhooks',\n 'event-registrations',\n] as const\n\nexport type InternalCollection = (typeof INTERNAL_COLLECTIONS)[number]\n\n/**\n * Array of all public collection names for runtime use (e.g., Zod enum validation).\n * This is the single source of truth for which collections are publicly accessible via SDK.\n */\nexport const COLLECTIONS = [\n 'tenants',\n 'tenant-metadata',\n 'tenant-logos',\n 'products',\n 'product-variants',\n 'product-options',\n 'product-option-values',\n 'product-categories',\n 'product-tags',\n 'product-collections',\n 'brands',\n 'brand-logos',\n 'orders',\n 'order-items',\n 'returns',\n 'return-items',\n 'fulfillment-orders',\n 'fulfillment-order-items',\n 'fulfillments',\n 'fulfillment-items',\n 'transactions',\n 'customers',\n 'customer-profiles',\n 'customer-addresses',\n 'carts',\n 'cart-items',\n 'discounts',\n 'shipping-policies',\n 'shipping-zones',\n 'documents',\n 'document-categories',\n 'document-types',\n 'articles',\n 'article-authors',\n 'article-categories',\n 'article-tags',\n 'playlists',\n 'playlist-categories',\n 'playlist-tags',\n 'tracks',\n 'track-categories',\n 'track-tags',\n 'galleries',\n 'gallery-categories',\n 'gallery-tags',\n 'gallery-items',\n 'links',\n 'link-categories',\n 'link-tags',\n 'canvases',\n 'canvas-node-types',\n 'canvas-edge-types',\n 'canvas-categories',\n 'canvas-tags',\n 'canvas-nodes',\n 'canvas-edges',\n 'videos',\n 'video-categories',\n 'video-tags',\n 'live-streams',\n 'images',\n 'forms',\n 'form-submissions',\n // Community\n 'posts',\n 'comments',\n 'reactions',\n 'reaction-types',\n 'bookmarks',\n 'post-categories',\n 'post-tags',\n 'customer-profile-lists',\n // Events\n 'event-calendars',\n 'events',\n 'event-categories',\n 'event-occurrences',\n 'event-tags',\n] as const\n\n/**\n * Server-auth collection names for runtime use. These collections are safe for\n * secret-key/PAT SDK and MCP server tools, but must not appear in browser or\n * publishable-key collection discovery.\n */\nexport const SERVER_ONLY_COLLECTIONS = [\n 'customer-groups',\n 'reports',\n 'community-bans',\n] as const\n\n/**\n * Public collections available for SDK access.\n * Derived from the COLLECTIONS array (single source of truth).\n */\nexport type PublicCollection = (typeof COLLECTIONS)[number]\n\nexport type ServerOnlyCollection = (typeof SERVER_ONLY_COLLECTIONS)[number]\n\nexport const SERVER_COLLECTIONS = [\n ...COLLECTIONS,\n ...SERVER_ONLY_COLLECTIONS,\n] as const\n\nexport type ServerCollection = (typeof SERVER_COLLECTIONS)[number]\n\n/**\n * Compile-time classification checks: every Config collection must be public,\n * server-only, or internal, and each collection must appear in exactly one\n * classification bucket.\n */\ntype _Uncategorized = Exclude<\n Collection,\n PublicCollection | ServerOnlyCollection | InternalCollection\n>\nexport const _assertAllCategorized: [_Uncategorized] extends [never]\n ? true\n : _Uncategorized = true\n\ntype _Overcategorized =\n | Extract<PublicCollection, ServerOnlyCollection | InternalCollection>\n | Extract<ServerOnlyCollection, InternalCollection>\nexport const _assertNoDuplicateCategorization: [_Overcategorized] extends [\n never,\n]\n ? true\n : _Overcategorized = true\n","/**\n * Fetch-based SSE connection manager for real-time collection change events.\n * Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).\n */\n\nexport interface RealtimeEvent {\n collection: string\n operation: string\n id: string | null\n timestamp: string\n}\n\nexport type RealtimeListener = (event: RealtimeEvent) => void\n\nconst INITIAL_RECONNECT_DELAY = 1_000\nconst MAX_RECONNECT_DELAY = 30_000\nconst RECONNECT_BACKOFF_FACTOR = 2\nconst MAX_NO_TOKEN_RETRIES = 5\n\nexport class RealtimeConnection {\n private abortController: AbortController | null = null\n private reconnectAttempt = 0\n private noTokenAttempts = 0\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private listeners = new Set<RealtimeListener>()\n private _connected = false\n\n constructor(\n private baseUrl: string,\n private publishableKey: string,\n private getToken: () => string | null,\n private collections?: string[],\n ) {}\n\n get connected(): boolean {\n return this._connected\n }\n\n addListener(fn: RealtimeListener): () => void {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n connect(): void {\n if (this.abortController) return // Already connecting/connected\n\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }\n\n disconnect(): void {\n this._connected = false\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n this.reconnectAttempt = 0\n this.noTokenAttempts = 0\n }\n\n private async startStream(signal: AbortSignal): Promise<void> {\n const token = this.getToken()\n if (!token) {\n this.noTokenAttempts++\n if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {\n // Stop reconnecting — no token available after multiple attempts\n this._connected = false\n this.abortController = null\n return\n }\n this.scheduleReconnect()\n return\n }\n this.noTokenAttempts = 0\n\n const params = this.collections?.length\n ? `?collections=${this.collections.join(',')}`\n : ''\n const url = `${this.baseUrl}/api/events/stream${params}`\n\n try {\n const response = await fetch(url, {\n headers: {\n 'X-Publishable-Key': this.publishableKey,\n Authorization: `Bearer ${token}`,\n },\n signal,\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n // Token expired — try reconnecting (will get fresh token)\n this.scheduleReconnect()\n return\n }\n throw new Error(`SSE connection failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body')\n }\n\n this._connected = true\n this.reconnectAttempt = 0\n\n await this.readStream(response.body, signal)\n } catch {\n if (signal.aborted) return // Intentional disconnect\n this._connected = false\n this.scheduleReconnect()\n }\n }\n\n private async readStream(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent = ''\n let currentData = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done || signal.aborted) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? '' // Keep incomplete last line in buffer\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7)\n } else if (line.startsWith('data: ')) {\n currentData += (currentData ? '\\n' : '') + line.slice(6)\n } else if (line === '') {\n // Empty line = end of event\n if (currentEvent === 'collection:change' && currentData) {\n try {\n const event: RealtimeEvent = JSON.parse(currentData)\n for (const listener of this.listeners) {\n try {\n listener(event)\n } catch {\n // Listener error — ignore\n }\n }\n } catch {\n // Malformed JSON — ignore\n }\n }\n currentEvent = ''\n currentData = ''\n }\n // Ignore comment lines (: heartbeat)\n }\n }\n } catch {\n // Stream read error\n } finally {\n reader.releaseLock()\n this._connected = false\n if (!signal.aborted) {\n this.scheduleReconnect()\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return\n\n const delay = Math.min(\n INITIAL_RECONNECT_DELAY *\n Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),\n MAX_RECONNECT_DELAY,\n )\n this.reconnectAttempt++\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }, delay)\n }\n}\n","export type NormalizedOptionSwatch<TMedia = unknown> = {\n type: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: string | number | null\n /** Inlined swatch media when the API populated mediaItemId before pool indexing. */\n inlineMedia?: TMedia | null\n}\n\nexport function selectedSwatchMediaItemId(\n swatch: NormalizedOptionSwatch | null | undefined,\n): string | null {\n if (!swatch || swatch.type !== 'media') return null\n const id = swatch.mediaItemId\n if (id == null || id === '') return null\n return String(id)\n}\n\nexport type ProductSelectionMediaSource =\n | 'variant_media_selected'\n | 'variant_media_matching'\n | 'option_swatch'\n | 'none'\n\nexport type ProductDisplayMediaSource =\n | 'listing_primary'\n | 'product_primary'\n | 'product_pool'\n | 'none'\n\n/** @deprecated Use {@link ProductSelectionMediaSource} or {@link ProductDisplayMediaSource}. */\nexport type ProductMediaResolutionSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n\nexport type ProductSelectionVariant<TMedia> = {\n id?: string | number | null\n images?: Array<TMedia | string | number | null | undefined> | null\n}\n\nexport type ProductSelectionOptionValue = {\n id?: string | number | null\n swatch?: NormalizedOptionSwatch<unknown> | null\n}\n\nexport type ProductSelectionMediaPointer =\n | string\n | number\n | { id?: string | number | null }\n | null\n\nexport type ResolveProductSelectionMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n selectedVariant?: ProductSelectionVariant<TMedia> | null\n matchingVariants?: Array<\n ProductSelectionVariant<TMedia> | null | undefined\n > | null\n selectedOptionValues?: Array<\n ProductSelectionOptionValue | null | undefined\n > | null\n}\n\nexport type ResolveProductSelectionMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductSelectionMediaSource\n}\n\nexport type ResolveProductDisplayMediaInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n listingPrimaryImage?: ProductSelectionMediaPointer\n}\n\nexport type ResolveProductDisplayMediaResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductDisplayMediaSource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction getMediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction toPointerId(\n value: ProductSelectionMediaPointer | undefined,\n): string | null {\n return getMediaId(value)\n}\n\nfunction mediaArray<TMedia>(value: TMedia[] | null | undefined): TMedia[] {\n if (!Array.isArray(value)) return []\n return value.filter((entry): entry is TMedia => entry != null)\n}\n\nfunction uniqueWithPrimaryFirst<TMedia>(\n primary: TMedia | null,\n items: TMedia[],\n): TMedia[] {\n const unique = new Map<string, TMedia>()\n\n for (const item of items) {\n const id = getMediaId(item)\n const key = id ?? `inline:${unique.size}`\n if (!unique.has(key)) unique.set(key, item)\n }\n\n if (primary) {\n const primaryId = getMediaId(primary)\n const prefixed = new Map<string, TMedia>()\n const primaryKey = primaryId ?? 'inline:primary'\n prefixed.set(primaryKey, primary)\n\n for (const [key, value] of unique.entries()) {\n if (!prefixed.has(key)) prefixed.set(key, value)\n }\n\n return Array.from(prefixed.values())\n }\n\n return Array.from(unique.values())\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n\n for (const item of pool) {\n const id = getMediaId(item)\n if (id) poolById.set(id, item)\n }\n\n return poolById\n}\n\nfunction resolveVariantImageItems<TMedia>(\n variant: ProductSelectionVariant<TMedia> | null | undefined,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n if (!variant || !Array.isArray(variant.images)) return []\n\n const resolved: TMedia[] = []\n\n for (const entry of variant.images) {\n if (entry == null) continue\n\n if (typeof entry === 'string' || typeof entry === 'number') {\n const pooled = poolById.get(String(entry))\n if (pooled) resolved.push(pooled)\n continue\n }\n\n const mediaId = getMediaId(entry)\n if (mediaId) {\n const pooled = poolById.get(mediaId)\n if (pooled) {\n resolved.push(pooled)\n }\n continue\n }\n }\n\n return resolved\n}\n\nfunction resolveOptionSwatchPrimary<TMedia>(\n selectedOptionValues:\n | Array<ProductSelectionOptionValue | null | undefined>\n | null\n | undefined,\n poolById: Map<string, TMedia>,\n): TMedia | null {\n if (!selectedOptionValues?.length) return null\n\n for (const optionValue of selectedOptionValues) {\n const swatch = optionValue?.swatch\n const swatchPointer = selectedSwatchMediaItemId(swatch)\n if (swatchPointer) {\n const pooled = poolById.get(swatchPointer)\n if (pooled) return pooled\n }\n\n const inline = swatch?.inlineMedia\n if (inline != null && typeof inline === 'object') {\n return inline as TMedia\n }\n }\n\n return null\n}\n\nexport function resolveProductSelectionMedia<TMedia>(\n input: ResolveProductSelectionMediaInput<TMedia>,\n): ResolveProductSelectionMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const selectedVariantImages = resolveVariantImageItems(\n input.selectedVariant,\n poolById,\n )\n\n if (selectedVariantImages.length > 0) {\n const primaryImage = selectedVariantImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, selectedVariantImages),\n source: 'variant_media_selected',\n }\n }\n\n if (\n input.selectedVariant == null &&\n (input.matchingVariants?.length ?? 0) > 0\n ) {\n const mergedMatchingImages: TMedia[] = []\n\n for (const matchingVariant of input.matchingVariants ?? []) {\n mergedMatchingImages.push(\n ...resolveVariantImageItems(matchingVariant, poolById),\n )\n }\n\n if (mergedMatchingImages.length > 0) {\n const primaryImage = mergedMatchingImages[0] ?? null\n\n return {\n primaryImage,\n images: uniqueWithPrimaryFirst(primaryImage, mergedMatchingImages),\n source: 'variant_media_matching',\n }\n }\n }\n\n const optionSwatchPrimary = resolveOptionSwatchPrimary(\n input.selectedOptionValues,\n poolById,\n )\n\n if (optionSwatchPrimary) {\n return {\n primaryImage: optionSwatchPrimary,\n images: [optionSwatchPrimary],\n source: 'option_swatch',\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport function resolveProductDisplayMedia<TMedia>(\n input: ResolveProductDisplayMediaInput<TMedia>,\n): ResolveProductDisplayMediaResult<TMedia> {\n const pool = mediaArray(input.productMediaPool)\n const poolById = buildPoolById(pool)\n\n const listingPointer = toPointerId(input.listingPrimaryImage)\n if (listingPointer) {\n const listingPrimary = poolById.get(listingPointer)\n if (listingPrimary) {\n return {\n primaryImage: listingPrimary,\n images: uniqueWithPrimaryFirst(listingPrimary, pool),\n source: 'listing_primary',\n }\n }\n }\n\n const productPrimaryPointer = getMediaId(input.productPrimaryMediaItemId)\n if (productPrimaryPointer) {\n const productPrimary = poolById.get(productPrimaryPointer)\n if (productPrimary) {\n return {\n primaryImage: productPrimary,\n images: uniqueWithPrimaryFirst(productPrimary, pool),\n source: 'product_primary',\n }\n }\n }\n\n if (pool.length > 0) {\n const productPoolPrimary = pool[0] ?? null\n\n if (productPoolPrimary) {\n return {\n primaryImage: productPoolPrimary,\n images: uniqueWithPrimaryFirst(productPoolPrimary, pool),\n source: 'product_pool',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\nexport type ListingPrimaryImageFallbackInput<TMedia> = {\n productMediaPool?: TMedia[] | null\n productPrimaryMediaItemId?: ProductSelectionMediaPointer\n productThumbnail?: TMedia | string | number | null\n listingPrimaryImage?: TMedia | string | number | null\n resolvedPrimary?: TMedia | null\n resolvedSource?: ProductMediaResolutionSource\n}\n\nexport function resolveListingPrimaryImagePointer<TMedia>(\n input: ListingPrimaryImageFallbackInput<TMedia>,\n): string | null {\n const pool = mediaArray(input.productMediaPool)\n const resolvedPointer = getMediaId(input.resolvedPrimary)\n if (\n resolvedPointer &&\n input.resolvedSource !== 'product_pool' &&\n input.resolvedSource !== 'none'\n ) {\n return resolvedPointer\n }\n\n const poolById = buildPoolById(pool)\n const listingPointer = getMediaId(input.listingPrimaryImage)\n if (listingPointer && poolById.has(listingPointer)) {\n return listingPointer\n }\n\n const primaryPointer = toPointerId(input.productPrimaryMediaItemId)\n if (primaryPointer && poolById.has(primaryPointer)) return primaryPointer\n\n const thumbnailPointer = getMediaId(input.productThumbnail)\n if (thumbnailPointer && poolById.has(thumbnailPointer)) {\n return thumbnailPointer\n }\n\n if (pool.length > 0) {\n const firstPoolId = getMediaId(pool[0])\n if (firstPoolId) return firstPoolId\n }\n\n return null\n}\n","import type {\n ProductDetail,\n ProductDetailMedia,\n ProductDetailOptionValue,\n ProductDetailVariant,\n ProductListingGroupsItem,\n ProductOptionValueSwatch,\n} from '../core/api/product-api'\nimport type { ApiQueryOptions } from '../core/client/types'\nimport { type NormalizedOptionSwatch } from './product-media'\nimport {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n resolveListingPrimaryImagePointer,\n type ProductMediaResolutionSource,\n type ProductSelectionMediaSource,\n} from './product-selection-media'\n\nfunction normalizeMatrixSwatch(\n swatch: ProductDetailOptionValue['swatch'],\n): NormalizedOptionSwatch<ProductDetailMedia> | null {\n if (!swatch) return null\n const rawMedia = swatch.mediaItemId as MediaValue\n const inlineMedia =\n rawMedia != null &&\n typeof rawMedia === 'object' &&\n 'url' in rawMedia &&\n typeof (rawMedia as { url?: unknown }).url === 'string'\n ? (rawMedia as ProductDetailMedia)\n : null\n return {\n type: swatch.type ?? null,\n color: swatch.color ?? null,\n mediaItemId: extractEntityId(rawMedia),\n inlineMedia,\n }\n}\n\ntype EntityID = string\n\ntype RelationshipValue =\n | string\n | number\n | null\n | undefined\n | { id?: string | number | null }\n\nexport type MediaValue = ProductDetailMedia | null | undefined\n\nexport type { ProductOptionValueSwatch }\n\n/** Raw Payload / REST swatch before strict public normalization. */\nexport type ProductOptionValueSwatchInput = {\n type?: 'color' | 'media' | null\n color?: string | null\n mediaItemId?: RelationshipValue\n}\n\nexport interface ProductOptionValueShape {\n id?: string | number | null\n option?: RelationshipValue\n value?: string | null\n slug?: string | null\n swatch?: ProductOptionValueSwatch | ProductOptionValueSwatchInput | null\n _order?: string | null\n '_product-option-values_values_order'?: string | null\n}\n\nexport interface ProductOptionShape {\n id?: string | number | null\n title?: string | null\n slug?: string | null\n _order?: string | null\n '_product-options_options_order'?: string | null\n values?: {\n docs?: unknown[]\n } | null\n}\n\nexport interface ProductVariantShape {\n id?: string | number | null\n optionValues?: unknown[] | null\n price?: number | null\n compareAtPrice?: number | null\n stock?: number | null\n reservedStock?: number | null\n isUnlimited?: boolean | null\n isActive?: boolean | null\n thumbnail?: MediaValue\n images?: MediaValue[] | null\n _order?: string | null\n}\n\nexport interface ProductListingProductShape {\n id?: EntityID\n thumbnail?: MediaValue\n primaryMediaItemId?: MediaValue\n images?: MediaValue[] | null\n listing?: {\n primaryImage?: MediaValue\n } | null\n}\n\nexport type ProductOptionMatrixValue = {\n id: string\n optionId: string\n optionSlug: string\n label: string\n slug: string | null\n swatch: ProductOptionValueSwatch\n order: string\n}\n\nexport type ProductOptionMatrixOption = {\n id: string\n title: string\n slug: string\n order: string\n values: ProductOptionMatrixValue[]\n}\n\nexport type ProductOptionMatrixVariant<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n id: string\n optionValueIds: string[]\n optionValueByOptionId: Map<string, string>\n optionValueByOptionSlug: Map<string, string>\n source: TVariant\n}\n\nexport type ProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n options: ProductOptionMatrixOption[]\n optionIds: string[]\n optionSlugs: string[]\n optionById: Map<string, ProductOptionMatrixOption>\n optionBySlug: Map<string, ProductOptionMatrixOption>\n valueById: Map<string, ProductOptionMatrixValue>\n valueToOptionId: Map<string, string>\n valueToOptionSlug: Map<string, string>\n variants: ProductOptionMatrixVariant<TVariant>[]\n}\n\nexport type ProductListingProjection = {\n selectionHintVariant: EntityID | null\n primaryImage: EntityID | null\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n availableForSale: boolean\n}\n\nexport type ProductListingGroup<\n TVariant extends ProductVariantShape = ProductVariantShape,\n> = {\n optionId: EntityID\n optionTitle: string\n optionSlug: string\n optionValueId: EntityID\n optionValueLabel: string\n optionValueSlug: string | null\n optionValueSwatch: ProductOptionValueSwatch\n variantIds: EntityID[]\n variantCount: number\n variants: TVariant[]\n listing: ProductListingProjection\n}\n\nexport type ProductListingCardPriceRange = {\n minPrice: number | null\n maxPrice: number | null\n minCompareAtPrice: number | null\n maxCompareAtPrice: number | null\n isPriceRange: boolean\n}\n\nexport type ProductListingSwatch = {\n optionId: EntityID\n optionValueId: EntityID\n label: string\n swatch: ProductOptionValueSwatch<ProductDetailMedia>\n href: string\n availableForSale: boolean\n}\n\nexport type ProductListingCardRepresentativeVariant =\n ProductListingGroupsItem['groups'][number]['variants'][number]\n\nexport type ProductListingCard = {\n id: EntityID\n href: string\n title: string\n representativeVariant?: ProductListingCardRepresentativeVariant | null\n primaryImage: ProductDetailMedia | null\n priceRange: ProductListingCardPriceRange\n availableForSale: boolean\n swatches: ProductListingSwatch[]\n}\n\nexport type ProductSelectionByOptionValue =\n | string\n | number\n | null\n | undefined\n | {\n valueId?: string | number | null\n valueSlug?: string | null\n }\n\nexport type ProductSelectionInput = {\n variantId?: string | number | null\n byOptionSlug?: Record<string, ProductSelectionByOptionValue>\n byOptionId?: Record<string, ProductSelectionByOptionValue>\n valueIds?: Iterable<unknown>\n search?: string | URLSearchParams | URL | null\n}\n\nexport type NormalizedProductSelection = {\n byOptionSlug: Record<string, string>\n byOptionId: Record<string, string>\n valueIds: string[]\n variantId: string | null\n}\n\nexport type CompatibilityProductSelectionParamEvent = {\n optionId: string\n optionSlug: string\n valueSlug: string\n searchParam: string\n}\n\nexport type LegacyProductSelectionParamEvent =\n CompatibilityProductSelectionParamEvent\n\nexport type ProductSelectionUrlEmit = 'slug-compat' | 'canonical-id'\n\nconst DEFAULT_PRODUCT_SELECTION_URL_EMIT: ProductSelectionUrlEmit =\n 'slug-compat'\n\nfunction resolveProductSelectionUrlEmit(\n emit?: ProductSelectionUrlEmit,\n): ProductSelectionUrlEmit {\n return emit ?? DEFAULT_PRODUCT_SELECTION_URL_EMIT\n}\n\nfunction appendSlugCompatSelectionParam(\n params: URLSearchParams,\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n optionId: string,\n valueId: string,\n): boolean {\n const option = matrix.optionById.get(optionId)\n const value = matrix.valueById.get(valueId)\n if (!option?.slug || !value?.slug) return false\n\n const slugMatches = option.values.filter(\n (candidate) => candidate.slug === value.slug,\n )\n if (slugMatches.length !== 1) return false\n\n params.append(`opt.${option.slug}`, value.slug)\n return true\n}\n\nfunction appendCanonicalSelectionParam(\n params: URLSearchParams,\n optionId: string,\n valueId: string,\n): void {\n params.append(`opt.${optionId}`, valueId)\n}\n\nexport type ProductSelectionCodecOptions = {\n emit?: ProductSelectionUrlEmit\n /**\n * When true, `resolveProductSelection()` fills unselected options to reach a\n * concrete variant. Does not change codec parse/stringify behavior.\n */\n fillDefaults?: boolean\n onCompatibilityOptionIdParam?: (\n event: CompatibilityProductSelectionParamEvent,\n ) => void\n onLegacyOptionIdParam?: (event: LegacyProductSelectionParamEvent) => void\n}\n\nexport type ProductSelectionResolutionContext = {\n detail?: Pick<ProductDetail, 'images' | 'listing' | 'primaryMediaItemId'>\n images?: ProductDetail['images']\n listing?: ProductDetail['listing']\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n}\n\nexport type ProductSelectionAvailableSwatch = {\n color?: string | null\n image?: MediaValue | null\n}\n\nexport type ProductSelectionAvailableValue = {\n valueId: string\n value: string\n label: string\n slug: string\n selected: boolean\n available: boolean\n exists: boolean\n availableForSale: boolean\n isUnlimited: boolean\n availableStock: number | null\n swatch: ProductOptionValueSwatch\n}\n\nexport type ProductSelectionResolution = {\n normalizedSelection: NormalizedProductSelection\n selectedVariant: ProductDetailVariant | null\n matchingVariants: ProductDetailVariant[]\n partialVariants: ProductDetailVariant[]\n availableValuesByOptionSlug: Record<string, ProductSelectionAvailableValue[]>\n availableValuesByOptionId: Record<string, ProductSelectionAvailableValue[]>\n allOptionsSelected: boolean\n price: {\n min: number | null\n max: number | null\n compareAtMin: number | null\n compareAtMax: number | null\n isRange: boolean\n }\n media: {\n primaryImage: ProductDetailMedia | null\n images: ProductDetailMedia[]\n source?: ProductMediaResolutionSource\n }\n stock: {\n availableForSale: boolean\n isUnlimited: boolean\n stock: number | null\n reservedStock: number | null\n availableStock: number | null\n }\n}\n\nexport class ProductSelectionCodecError extends Error {\n code = 'ambiguous_product_selection_query'\n\n constructor(message: string) {\n super(message)\n this.name = 'ProductSelectionCodecError'\n }\n}\n\nfunction getRelationID(value: RelationshipValue): string | undefined {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n const id = value.id\n if (typeof id === 'string') return id\n if (typeof id === 'number') return String(id)\n }\n return undefined\n}\n\nfunction compareOrder(\n left: string | null | undefined,\n right: string | null | undefined,\n): number {\n return (left ?? '').localeCompare(right ?? '')\n}\n\nfunction isProductOptionValueDoc(\n value: unknown,\n): value is ProductOptionValueShape {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n ('value' in value || 'slug' in value)\n )\n}\n\nfunction extractEntityId(value: MediaValue): EntityID | null {\n if (typeof value === 'string') return value\n if (typeof value === 'number') return String(value)\n if (value && typeof value === 'object' && 'id' in value) {\n if (typeof value.id === 'string') return value.id\n if (typeof value.id === 'number') return String(value.id)\n }\n return null\n}\n\nfunction getFirstMediaId(\n values: MediaValue[] | null | undefined,\n): EntityID | null {\n if (!Array.isArray(values)) return null\n\n for (const value of values) {\n const id = extractEntityId(value)\n if (id != null) return id\n }\n\n return null\n}\n\nfunction getVariantPrimaryImage(\n variant: ProductVariantShape | null | undefined,\n): EntityID | null {\n if (!variant) return null\n return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images)\n}\n\nfunction resolveGenericListingPrimaryImage(\n product: ProductListingProductShape | null | undefined,\n resolvedPrimary: MediaValue | null,\n resolvedSource?: ProductSelectionMediaSource,\n): EntityID | null {\n return resolveListingPrimaryImagePointer({\n productMediaPool: product?.images ?? [],\n productPrimaryMediaItemId: getRelationID(\n product?.primaryMediaItemId ?? null,\n ),\n productThumbnail: product?.thumbnail ?? null,\n listingPrimaryImage: product?.listing?.primaryImage ?? null,\n resolvedPrimary,\n resolvedSource,\n })\n}\n\nfunction getFirstAvailableVariantPrimaryImage(\n variants: ProductVariantShape[],\n): EntityID | null {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n\n for (const variant of orderedVariants) {\n if (!isVariantAvailableForSale(variant)) continue\n const image = getVariantPrimaryImage(variant)\n if (image != null) return image\n }\n\n return null\n}\n\nfunction normalizeProductOptionValueSwatch(\n swatch:\n | ProductOptionValueSwatch\n | ProductOptionValueSwatchInput\n | null\n | undefined,\n): ProductOptionValueSwatch {\n if (swatch == null) return null\n if (typeof swatch !== 'object') return null\n\n const raw = swatch as ProductOptionValueSwatchInput\n const mediaItemId = extractEntityId(raw.mediaItemId as MediaValue)\n const color =\n typeof raw.color === 'string' ? raw.color.trim() : ''\n const hasColor = color.length > 0\n\n if (raw.type === 'media' || (mediaItemId && raw.type !== 'color')) {\n if (!mediaItemId || hasColor) return null\n return {\n type: 'media',\n mediaItemId: mediaItemId as ProductDetailMedia,\n color: null,\n }\n }\n\n if (raw.type === 'color' || hasColor) {\n if (mediaItemId || !hasColor) return null\n return { type: 'color', color, mediaItemId: null }\n }\n\n return null\n}\n\nfunction normalizeOptionValue(\n value: ProductOptionValueShape,\n fallbackOptionId: string,\n fallbackOptionSlug: string,\n): ProductOptionMatrixValue {\n return {\n id: String(value.id),\n optionId: getRelationID(value.option) ?? fallbackOptionId,\n optionSlug: fallbackOptionSlug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug ?? null,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: value._order ?? value['_product-option-values_values_order'] ?? '',\n }\n}\n\nfunction normalizeVariantOptionValues<TVariant extends ProductVariantShape>(\n variant: TVariant,\n optionById: Map<string, ProductOptionMatrixOption>,\n valueToOptionId: Map<string, string>,\n optionIds: string[],\n): ProductOptionMatrixVariant<TVariant> {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of Array.isArray(variant.optionValues)\n ? variant.optionValues\n : []) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId =\n valueToOptionId.get(valueId) ??\n (isProductOptionValueDoc(rawValue)\n ? getRelationID(rawValue.option)\n : undefined)\n if (!optionId || optionValueByOptionId.has(optionId)) continue\n\n optionValueByOptionId.set(optionId, valueId)\n const optionSlug = optionById.get(optionId)?.slug\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n}\n\nexport function buildProductOptionMatrix<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>({\n options,\n variants = [],\n}: {\n options: ProductOptionShape[]\n variants?: TVariant[]\n}): ProductOptionMatrix<TVariant> {\n const normalizedOptions = options\n .map((option) => {\n const valuesById = new Map<string, ProductOptionMatrixValue>()\n const optionSlug = option.slug ?? String(option.id)\n\n for (const rawValue of option.values?.docs ?? []) {\n if (!isProductOptionValueDoc(rawValue)) continue\n\n const normalizedValue = normalizeOptionValue(\n rawValue,\n String(option.id),\n optionSlug,\n )\n valuesById.set(normalizedValue.id, normalizedValue)\n }\n\n return {\n id: String(option.id),\n title: option.title ?? String(option.id),\n slug: optionSlug,\n order: option._order ?? option['_product-options_options_order'] ?? '',\n values: Array.from(valuesById.values()).sort((left, right) =>\n compareOrder(left.order, right.order),\n ),\n }\n })\n .sort((left, right) => compareOrder(left.order, right.order))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = variants.map((variant) =>\n normalizeVariantOptionValues(\n variant,\n optionById,\n valueToOptionId,\n optionIds,\n ),\n )\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nfunction matrixOrder(index: number): string {\n return String(index).padStart(6, '0')\n}\n\nexport function buildProductOptionMatrixFromDetail(\n detail: ProductDetail,\n): ProductOptionMatrix<ProductDetailVariant> {\n const normalizedOptions = detail.options.map((option, optionIndex) => ({\n id: String(option.id),\n title: option.title || String(option.id),\n slug: option.slug,\n order: matrixOrder(optionIndex),\n values: option.values.map((value, valueIndex) => ({\n id: String(value.id),\n optionId: String(option.id),\n optionSlug: option.slug,\n label: value.value || value.slug || String(value.id),\n slug: value.slug,\n swatch: normalizeProductOptionValueSwatch(value.swatch),\n order: matrixOrder(valueIndex),\n })),\n }))\n\n const optionById = new Map(\n normalizedOptions.map((option) => [option.id, option]),\n )\n const optionBySlug = new Map(\n normalizedOptions.map((option) => [option.slug, option]),\n )\n const valueById = new Map<string, ProductOptionMatrixValue>()\n const valueToOptionId = new Map<string, string>()\n const valueToOptionSlug = new Map<string, string>()\n\n for (const option of normalizedOptions) {\n for (const value of option.values) {\n valueById.set(value.id, value)\n valueToOptionId.set(value.id, option.id)\n valueToOptionSlug.set(value.id, option.slug)\n }\n }\n\n const optionIds = normalizedOptions.map((option) => option.id)\n const optionSlugs = normalizedOptions.map((option) => option.slug)\n const normalizedVariants = detail.variants.map((variant) => {\n const optionValueByOptionId = new Map<string, string>()\n const optionValueByOptionSlug = new Map<string, string>()\n\n for (const rawValue of variant.optionValues) {\n const optionId = String(rawValue.optionId)\n const valueId = String(rawValue.valueId)\n const optionSlug = rawValue.optionSlug\n if (!optionById.has(optionId)) continue\n if (valueToOptionId.get(valueId) !== optionId) continue\n if (optionValueByOptionId.has(optionId)) continue\n optionValueByOptionId.set(optionId, valueId)\n if (optionSlug && !optionValueByOptionSlug.has(optionSlug)) {\n optionValueByOptionSlug.set(optionSlug, valueId)\n }\n }\n\n const optionValueIds = optionIds\n .map((optionId) => optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n\n return {\n id: String(variant.id),\n optionValueIds,\n optionValueByOptionId,\n optionValueByOptionSlug,\n source: variant,\n }\n })\n\n return {\n options: normalizedOptions,\n optionIds,\n optionSlugs,\n optionById,\n optionBySlug,\n valueById,\n valueToOptionId,\n valueToOptionSlug,\n variants: normalizedVariants,\n }\n}\n\nexport function getSelectedValueByOptionId<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): Map<string, string> {\n const selectedByOption = new Map<string, string>()\n\n for (const rawValue of selectedValueIds) {\n const valueId = getRelationID(rawValue as RelationshipValue)\n if (!valueId) continue\n\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId || selectedByOption.has(optionId)) continue\n\n selectedByOption.set(optionId, valueId)\n }\n\n return selectedByOption\n}\n\nexport function normalizeSelectedValueIds<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): string[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n\n return matrix.optionIds\n .map((optionId) => selectedByOption.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId))\n}\n\nexport function getAvailableOptionValues<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n optionId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixValue[] {\n const option = matrix.optionById.get(optionId)\n if (!option) return []\n\n if (matrix.variants.length === 0) {\n return option.values\n }\n\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.delete(optionId)\n\n const matchingVariants = matrix.variants.filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) === selectedValueId,\n ),\n )\n\n const availableValueIds = new Set(\n matchingVariants\n .filter((variant) => variant.source.isActive !== false)\n .map((variant) => variant.optionValueByOptionId.get(optionId))\n .filter((valueId): valueId is string => Boolean(valueId)),\n )\n\n return option.values.filter((value) => availableValueIds.has(value.id))\n}\n\nexport function resolveVariantForSelection<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(\n matrix: ProductOptionMatrix<TVariant>,\n selectedValueIds: Iterable<unknown>,\n): ProductOptionMatrixVariant<TVariant> | undefined {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n if (selectedByOption.size !== matrix.optionIds.length) {\n return undefined\n }\n\n return matrix.variants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selectedByOption.get(optionId),\n ),\n )\n}\n\nfunction getVariantSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n variantId: string | number | null | undefined,\n): ProductOptionMatrixVariant<ProductDetailVariant> | undefined {\n if (variantId == null) return undefined\n const id = String(variantId)\n return matrix.variants.find((variant) => variant.id === id)\n}\n\nfunction hasExplicitSelection(selection: ProductSelectionInput): boolean {\n return Boolean(\n selection.variantId != null ||\n selection.search ||\n selection.valueIds ||\n Object.keys(selection.byOptionId ?? {}).length > 0 ||\n Object.keys(selection.byOptionSlug ?? {}).length > 0,\n )\n}\n\nfunction assignSelectedValue(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueId: string | number | null | undefined,\n): boolean {\n if (valueId == null) return false\n const normalizedValueId = String(valueId)\n if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return false\n selectedByOptionId.set(optionId, normalizedValueId)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionId(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionId: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionById.get(optionId)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionId}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(optionId, value.id)\n return true\n}\n\nfunction assignSelectedValueSlugByOptionSlug(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n optionSlug: string,\n valueSlug: string | null | undefined,\n): boolean {\n if (!valueSlug) return false\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return false\n const values = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (values.length > 1) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection value slug \"${valueSlug}\" for option \"${optionSlug}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n const value = values[0]\n if (!value) return false\n selectedByOptionId.set(option.id, value.id)\n return true\n}\n\nfunction toSearchParams(\n search: string | URLSearchParams | URL | null | undefined,\n): URLSearchParams {\n if (!search) return new URLSearchParams()\n if (search instanceof URLSearchParams) return new URLSearchParams(search)\n if (search instanceof URL) return new URLSearchParams(search.searchParams)\n\n const trimmed = search.trim()\n if (!trimmed) return new URLSearchParams()\n\n try {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) {\n return new URL(trimmed).searchParams\n }\n } catch {\n return new URLSearchParams()\n }\n\n return new URLSearchParams(\n trimmed.startsWith('?') ? trimmed.slice(1) : trimmed,\n )\n}\n\nfunction slugLike(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction assertNoAmbiguousSelectionParams(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n params: URLSearchParams,\n) {\n const knownSelectionKeys = new Set<string>()\n const hasVariantParam = params.has('variant')\n const hasOptionParams = Array.from(params.keys()).some((key) =>\n key.startsWith('opt.'),\n )\n\n if (hasVariantParam && hasOptionParams) {\n throw new ProductSelectionCodecError(\n 'Product selection URL cannot mix variant=<variantId> with opt.<optionId>=<valueId> params.',\n )\n }\n\n for (const option of matrix.options) {\n knownSelectionKeys.add(slugLike(option.slug))\n knownSelectionKeys.add(slugLike(option.title))\n for (const value of option.values) {\n if (value.slug) knownSelectionKeys.add(slugLike(value.slug))\n }\n }\n\n for (const [key, value] of params.entries()) {\n if (key.startsWith('opt.')) {\n const optionToken = key.slice(4)\n if (\n !optionToken ||\n (!matrix.optionBySlug.has(optionToken) &&\n !matrix.optionById.has(optionToken))\n ) {\n throw new ProductSelectionCodecError(\n `Unknown product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n if (!value) {\n throw new ProductSelectionCodecError(\n `Product selection query parameter \"${key}\" requires a value ID or compatibility value slug.`,\n )\n }\n continue\n }\n\n if (key === 'variant') {\n if (!value) {\n throw new ProductSelectionCodecError(\n 'Product selection query parameter \"variant\" requires a variant ID.',\n )\n }\n if (!getVariantSelection(matrix, value)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${value}\".`,\n )\n }\n continue\n }\n\n const keyToken = slugLike(key)\n if (\n knownSelectionKeys.has(keyToken) ||\n (value === '' && knownSelectionKeys.has(keyToken))\n ) {\n throw new ProductSelectionCodecError(\n `Ambiguous product selection query parameter \"${key}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n }\n}\n\nfunction emitCompatibilityOptionIdParam(\n options: ProductSelectionCodecOptions | undefined,\n event: CompatibilityProductSelectionParamEvent,\n) {\n try {\n if (options?.onCompatibilityOptionIdParam) {\n options.onCompatibilityOptionIdParam(event)\n return\n }\n options?.onLegacyOptionIdParam?.(event)\n } catch {\n // Compatibility telemetry must not change parser semantics.\n }\n}\n\nfunction assignSearchSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): string | null {\n if (!search) return null\n const params = toSearchParams(search)\n assertNoAmbiguousSelectionParams(matrix, params)\n\n const variantParam = params.get('variant')\n if (variantParam != null) {\n const variantSelection = getVariantSelection(matrix, variantParam)\n if (!variantSelection) {\n throw new ProductSelectionCodecError(\n `Unknown product selection variant \"${variantParam}\".`,\n )\n }\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n return variantSelection.id\n }\n\n for (const [key, valueToken] of params.entries()) {\n if (!key.startsWith('opt.')) continue\n const optionToken = key.slice(4)\n\n const optionById = matrix.optionById.get(optionToken)\n if (optionById) {\n if (\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n )\n ) {\n continue\n }\n\n const before = selectedByOptionId.get(optionById.id)\n if (\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionById.id,\n valueToken,\n ) &&\n selectedByOptionId.get(optionById.id) !== before\n ) {\n emitCompatibilityOptionIdParam(options, {\n optionId: optionById.id,\n optionSlug: optionById.slug,\n valueSlug: valueToken,\n searchParam: key,\n })\n continue\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n const optionBySlug = matrix.optionBySlug.get(optionToken)\n if (optionBySlug) {\n if (\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionBySlug.slug,\n valueToken,\n )\n ) {\n continue\n }\n\n if (matrix.valueById.has(valueToken)) {\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionId>=<valueId>.`,\n )\n }\n\n throw new ProductSelectionCodecError(\n `Unknown product selection value \"${valueToken}\" for option \"${optionToken}\". Use opt.<optionSlug>=<valueSlug> for compatibility URLs.`,\n )\n }\n }\n\n return null\n}\n\nexport function normalizeProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return normalizeProductSelectionFromMatrix(matrix, selection, options)\n}\n\nexport function normalizeProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>()\n const variantSelection = getVariantSelection(matrix, selection.variantId)\n const variantId = variantSelection?.id ?? null\n\n if (variantSelection) {\n for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {\n selectedByOptionId.set(optionId, valueId)\n }\n }\n\n for (const rawValueId of selection.valueIds ?? []) {\n const valueId = getRelationID(rawValueId as RelationshipValue)\n if (!valueId) continue\n const optionId = matrix.valueToOptionId.get(valueId)\n if (!optionId) continue\n selectedByOptionId.set(optionId, valueId)\n }\n\n const searchVariantId = assignSearchSelection(\n matrix,\n selectedByOptionId,\n selection.search,\n options,\n )\n\n for (const [rawOptionId, rawSelection] of Object.entries(\n selection.byOptionId ?? {},\n )) {\n const optionId = String(rawOptionId)\n if (!matrix.optionById.has(optionId)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueId,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValue(matrix, selectedByOptionId, optionId, rawSelection)\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionId(\n matrix,\n selectedByOptionId,\n optionId,\n rawSelection.valueSlug,\n )\n }\n }\n\n for (const [rawOptionSlug, rawSelection] of Object.entries(\n selection.byOptionSlug ?? {},\n )) {\n const optionSlug = String(rawOptionSlug)\n if (!matrix.optionBySlug.has(optionSlug)) continue\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueId' in rawSelection &&\n rawSelection.valueId != null\n ) {\n const option = matrix.optionBySlug.get(optionSlug)\n if (option) {\n assignSelectedValue(\n matrix,\n selectedByOptionId,\n option.id,\n rawSelection.valueId,\n )\n }\n continue\n }\n\n if (\n rawSelection &&\n typeof rawSelection === 'object' &&\n 'valueSlug' in rawSelection\n ) {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n rawSelection.valueSlug,\n )\n continue\n }\n\n if (typeof rawSelection === 'string' || typeof rawSelection === 'number') {\n assignSelectedValueSlugByOptionSlug(\n matrix,\n selectedByOptionId,\n optionSlug,\n String(rawSelection),\n )\n }\n }\n\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId: searchVariantId ?? variantId,\n }\n}\n\nexport function parseProductSelection(\n detail: ProductDetail,\n search: string | URLSearchParams | URL | null | undefined,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n return normalizeProductSelection(detail, { search }, options)\n}\n\nexport function stringifyProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): string {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const normalized = normalizeProductSelectionFromMatrix(\n matrix,\n selection,\n options,\n )\n const params = new URLSearchParams()\n\n if (hasExplicitSelection(selection)) {\n const matchingVariants = getMatchingVariantEntries(matrix, normalized)\n const exactVariant = getExactSelectedVariantEntry(\n matrix,\n normalized,\n matchingVariants,\n )\n if (exactVariant) {\n params.set('variant', exactVariant.id)\n return params.toString()\n }\n }\n\n const emit = resolveProductSelectionUrlEmit(options?.emit)\n\n for (const optionId of matrix.optionIds) {\n const valueId = normalized.byOptionId[optionId]\n if (!valueId) continue\n if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {\n continue\n }\n\n if (emit === 'slug-compat') {\n if (appendSlugCompatSelectionParam(params, matrix, optionId, valueId)) {\n continue\n }\n }\n\n appendCanonicalSelectionParam(params, optionId, valueId)\n }\n\n return params.toString()\n}\n\nexport function createProductSelectionCodec(\n detail: ProductDetail,\n options?: ProductSelectionCodecOptions,\n): {\n parse: (\n search: string | URLSearchParams | URL | null | undefined,\n ) => NormalizedProductSelection\n stringify: (selection?: ProductSelectionInput) => string\n} {\n return {\n parse: (search) => parseProductSelection(detail, search, options),\n stringify: (selection = {}) =>\n stringifyProductSelection(detail, selection, options),\n }\n}\n\nfunction selectedEntries(\n selection: NormalizedProductSelection,\n): Array<[string, string]> {\n return Object.entries(selection.byOptionId)\n}\n\nfunction getMatchingVariantEntries(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: NormalizedProductSelection,\n): ProductOptionMatrixVariant<ProductDetailVariant>[] {\n const entries = selectedEntries(selection)\n if (entries.length === 0) return matrix.variants\n\n return matrix.variants.filter((variant) =>\n entries.every(\n ([optionId, valueId]) =>\n variant.optionValueByOptionId.get(optionId) === valueId,\n ),\n )\n}\n\nfunction activeVariantEntries(\n variants: ProductOptionMatrixVariant<ProductDetailVariant>[],\n): ProductOptionMatrixVariant<ProductDetailVariant>[] {\n return variants.filter((variant) => variant.source.isActive !== false)\n}\n\nfunction getExactSelectedVariantEntry(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: NormalizedProductSelection,\n matchingVariants: ProductOptionMatrixVariant<ProductDetailVariant>[],\n): ProductOptionMatrixVariant<ProductDetailVariant> | null {\n if (matrix.optionIds.length === 0) {\n return (\n getVariantSelection(matrix, selection.variantId) ??\n (matchingVariants.length === 1 ? (matchingVariants[0] ?? null) : null)\n )\n }\n\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(selection.byOptionId[optionId]),\n )\n if (!allOptionsSelected) return null\n\n return (\n matchingVariants.find((variant) =>\n matrix.optionIds.every(\n (optionId) =>\n variant.optionValueByOptionId.get(optionId) ===\n selection.byOptionId[optionId],\n ),\n ) ?? null\n )\n}\n\nfunction normalizedSelectionFromByOptionId(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n variantId: string | null,\n): NormalizedProductSelection {\n const byOptionId = Object.fromEntries(\n matrix.optionIds\n .map((optionId) => [optionId, selectedByOptionId.get(optionId)])\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n const byOptionSlug = Object.fromEntries(\n matrix.options\n .map((option) => {\n const valueId = selectedByOptionId.get(option.id)\n const value = valueId ? matrix.valueById.get(valueId) : undefined\n return [option.slug, value?.slug ?? undefined]\n })\n .filter((entry): entry is [string, string] => Boolean(entry[1])),\n )\n\n return {\n byOptionSlug,\n byOptionId,\n valueIds: matrix.optionIds\n .map((optionId) => byOptionId[optionId])\n .filter((valueId): valueId is string => Boolean(valueId)),\n variantId,\n }\n}\n\nfunction buildFilledNormalizedSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n normalizedSelection: NormalizedProductSelection,\n listing: Partial<ProductDetail['listing']>,\n): NormalizedProductSelection {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedSelection.byOptionId),\n )\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n if (variantId === normalizedSelection.variantId) {\n return normalizedSelection\n }\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n for (const option of matrix.options) {\n if (selectedByOptionId.has(option.id)) continue\n if (option.values.length === 1) {\n selectedByOptionId.set(option.id, option.values[0]!.id)\n }\n }\n\n if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n const variantId =\n normalizedSelection.variantId ??\n resolveVariantIdForCompleteSelection(matrix, selectedByOptionId)\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n variantId,\n )\n }\n\n const partialNormalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n normalizedSelection.variantId,\n )\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n partialNormalized,\n )\n const orderedMatches = [...matchingVariantEntries].sort((left, right) =>\n compareVariantOrder(left.source, right.source),\n )\n\n const hintVariantId =\n listing.selectionHintVariant != null\n ? String(listing.selectionHintVariant)\n : null\n const hintedEntry =\n hintVariantId != null\n ? orderedMatches.find((entry) => entry.id === hintVariantId)\n : undefined\n const availableEntry = orderedMatches.find((entry) =>\n isVariantAvailableForSale(entry.source),\n )\n const chosenEntry = hintedEntry ?? availableEntry ?? orderedMatches[0]\n\n if (!chosenEntry) {\n return normalizedSelection\n }\n\n for (const optionId of matrix.optionIds) {\n if (selectedByOptionId.has(optionId)) continue\n const valueId = chosenEntry.optionValueByOptionId.get(optionId)\n if (valueId) selectedByOptionId.set(optionId, valueId)\n }\n\n const filledVariantId = matrix.optionIds.every((optionId) =>\n selectedByOptionId.has(optionId),\n )\n ? (resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) ??\n chosenEntry.id)\n : normalizedSelection.variantId\n\n return normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n filledVariantId,\n )\n}\n\nfunction resolveVariantIdForCompleteSelection(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selectedByOptionId: Map<string, string>,\n): string | null {\n if (!matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {\n return null\n }\n\n const normalized = normalizedSelectionFromByOptionId(\n matrix,\n selectedByOptionId,\n null,\n )\n const matchingVariantEntries = getMatchingVariantEntries(matrix, normalized)\n return (\n getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)\n ?.id ?? null\n )\n}\n\nfunction buildSelectionPrice(\n variants: ProductDetailVariant[],\n): ProductSelectionResolution['price'] {\n const { min, max } = getMinMax(variants.map((variant) => variant.price))\n const { min: compareAtMin, max: compareAtMax } = getMinMax(\n variants.map((variant) => variant.compareAtPrice),\n )\n\n return {\n min,\n max,\n compareAtMin,\n compareAtMax,\n isRange: min !== null && max !== null ? min !== max : false,\n }\n}\n\nfunction isPresentMedia(value: MediaValue): value is ProductDetailMedia {\n return value != null\n}\n\nfunction mediaArray(\n values: MediaValue[] | null | undefined,\n): ProductDetailMedia[] {\n if (!Array.isArray(values)) return []\n return values.filter(isPresentMedia)\n}\n\nfunction buildSelectionMedia(\n detail: {\n images: ProductDetail['images']\n listing: Pick<ProductDetail['listing'], 'primaryImage'>\n primaryMediaItemId?: ProductDetail['primaryMediaItemId']\n },\n selectedVariant: ProductDetailVariant | null,\n matchingVariants: ProductDetailVariant[],\n selectedValues: ProductOptionMatrixValue[],\n): ProductSelectionResolution['media'] {\n const productPool = mediaArray(detail.images)\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),\n selectedVariant: selectedVariant\n ? {\n id: selectedVariant.id,\n images: selectedVariant.images,\n }\n : null,\n matchingVariants: matchingVariants.map((variant) => ({\n id: variant.id,\n images: variant.images,\n })),\n selectedOptionValues: selectedValues.map((value) => ({\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n })),\n })\n if (resolvedMedia.source !== 'none') {\n return {\n primaryImage: resolvedMedia.primaryImage,\n images: resolvedMedia.images,\n source: resolvedMedia.source,\n }\n }\n\n const displayMedia = resolveProductDisplayMedia<ProductDetailMedia>({\n productMediaPool: productPool,\n productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),\n listingPrimaryImage: detail.listing.primaryImage ?? null,\n })\n if (displayMedia.source !== 'none') {\n return {\n primaryImage: displayMedia.primaryImage,\n images: displayMedia.images,\n source: displayMedia.source,\n }\n }\n\n return { primaryImage: null, images: [], source: 'none' }\n}\n\nfunction buildSelectionStock(\n selectedVariant: ProductDetailVariant | null,\n matchingVariants: ProductDetailVariant[],\n): ProductSelectionResolution['stock'] {\n if (selectedVariant) {\n const availableStock = selectedVariant.isUnlimited\n ? null\n : Math.max(0, selectedVariant.stock - selectedVariant.reservedStock)\n const isActive = selectedVariant.isActive !== false\n return {\n availableForSale:\n isActive && (selectedVariant.isUnlimited || (availableStock ?? 0) > 0),\n isUnlimited: selectedVariant.isUnlimited,\n stock: selectedVariant.stock,\n reservedStock: selectedVariant.reservedStock,\n availableStock,\n }\n }\n\n return {\n availableForSale: matchingVariants.some(isVariantAvailableForSale),\n isUnlimited: matchingVariants.some((variant) => variant.isUnlimited),\n stock: null,\n reservedStock: null,\n availableStock: null,\n }\n}\n\nfunction buildAvailableValueStock(\n variants: ProductDetailVariant[],\n): Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n> {\n const activeVariants = variants.filter(\n (variant) => variant.isActive !== false,\n )\n const isUnlimited = activeVariants.some((variant) => variant.isUnlimited)\n const availableStock = isUnlimited\n ? null\n : activeVariants.reduce(\n (sum, variant) =>\n sum + Math.max(0, variant.stock - variant.reservedStock),\n 0,\n )\n\n return {\n availableForSale: activeVariants.some(isVariantAvailableForSale),\n isUnlimited,\n availableStock,\n }\n}\n\nfunction buildProductSelectionAvailableValue(\n matrixValue: ProductOptionMatrixValue,\n _productImages: ProductDetailMedia[],\n selected: boolean,\n available: boolean,\n stock: Pick<\n ProductSelectionAvailableValue,\n 'availableForSale' | 'availableStock' | 'isUnlimited'\n >,\n): ProductSelectionAvailableValue {\n return {\n valueId: matrixValue.id,\n value: matrixValue.label,\n label: matrixValue.label,\n slug: matrixValue.slug ?? '',\n selected,\n available,\n exists: available,\n ...stock,\n swatch: matrixValue.swatch ?? null,\n }\n}\n\nfunction getCandidateVariantsForValue(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n optionId: string,\n valueId: string,\n selectedValueIds: Iterable<unknown>,\n): ProductDetailVariant[] {\n const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds)\n selectedByOption.set(optionId, valueId)\n\n return matrix.variants\n .filter((variant) =>\n Array.from(selectedByOption.entries()).every(\n ([selectedOptionId, selectedValueId]) =>\n variant.optionValueByOptionId.get(selectedOptionId) ===\n selectedValueId,\n ),\n )\n .map((variant) => variant.source)\n}\n\nfunction getResolutionContext(context?: ProductSelectionResolutionContext): {\n images: ProductDetail['images']\n listing: Partial<ProductDetail['listing']>\n primaryMediaItemId: ProductDetail['primaryMediaItemId']\n} {\n return {\n images: context?.images ?? context?.detail?.images ?? [],\n listing: context?.listing ?? context?.detail?.listing ?? {},\n primaryMediaItemId:\n context?.primaryMediaItemId ??\n context?.detail?.primaryMediaItemId ??\n null,\n }\n}\n\nexport function resolveProductSelectionFromMatrix(\n matrix: ProductOptionMatrix<ProductDetailVariant>,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n context?: ProductSelectionResolutionContext,\n): ProductSelectionResolution {\n const { images, listing, primaryMediaItemId } = getResolutionContext(context)\n const effectiveSelection =\n hasExplicitSelection(selection) || listing.selectionHintVariant == null\n ? selection\n : { ...selection, variantId: listing.selectionHintVariant }\n let normalizedSelection = normalizeProductSelectionFromMatrix(\n matrix,\n effectiveSelection,\n options,\n )\n\n if (options?.fillDefaults) {\n normalizedSelection = buildFilledNormalizedSelection(\n matrix,\n normalizedSelection,\n listing,\n )\n }\n const matchingVariantEntries = getMatchingVariantEntries(\n matrix,\n normalizedSelection,\n )\n const activeMatchingVariantEntries = activeVariantEntries(\n matchingVariantEntries,\n )\n const selectedVariantEntry = getExactSelectedVariantEntry(\n matrix,\n normalizedSelection,\n matchingVariantEntries,\n )\n const selectedVariant = selectedVariantEntry?.source ?? null\n const matchingVariants = activeMatchingVariantEntries.map(\n (variant) => variant.source,\n )\n const selectedValues = matrix.optionIds\n .map((optionId) => normalizedSelection.byOptionId[optionId])\n .map((valueId) => (valueId ? matrix.valueById.get(valueId) : undefined))\n .filter((value): value is ProductOptionMatrixValue => value !== undefined)\n const availableValuesByOptionId = Object.fromEntries(\n matrix.options.map((option) => {\n const availableValueIds = new Set(\n getAvailableOptionValues(\n matrix,\n option.id,\n normalizedSelection.valueIds,\n ).map((value) => value.id),\n )\n return [\n option.id,\n option.values.map((value) =>\n buildProductSelectionAvailableValue(\n value,\n images,\n normalizedSelection.byOptionId[option.id] === value.id,\n availableValueIds.has(value.id),\n buildAvailableValueStock(\n getCandidateVariantsForValue(\n matrix,\n option.id,\n value.id,\n normalizedSelection.valueIds,\n ),\n ),\n ),\n ),\n ]\n }),\n )\n const availableValuesByOptionSlug = Object.fromEntries(\n matrix.options.map((option) => [\n option.slug,\n availableValuesByOptionId[option.id] ?? [],\n ]),\n )\n const allOptionsSelected = matrix.optionIds.every((optionId) =>\n Boolean(normalizedSelection.byOptionId[optionId]),\n )\n const priceVariants = selectedVariant ? [selectedVariant] : matchingVariants\n\n return {\n normalizedSelection,\n selectedVariant,\n matchingVariants,\n partialVariants: selectedVariant ? [] : matchingVariants,\n availableValuesByOptionSlug,\n availableValuesByOptionId,\n allOptionsSelected,\n price: buildSelectionPrice(priceVariants),\n media: buildSelectionMedia(\n {\n images,\n listing: {\n primaryImage: listing.primaryImage ?? null,\n },\n primaryMediaItemId,\n },\n selectedVariant,\n matchingVariants,\n selectedValues,\n ),\n stock: buildSelectionStock(selectedVariant, matchingVariants),\n }\n}\n\nexport function resolveProductSelection(\n detail: ProductDetail,\n selection: ProductSelectionInput = {},\n options?: ProductSelectionCodecOptions,\n): ProductSelectionResolution {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n return resolveProductSelectionFromMatrix(matrix, selection, options, {\n detail,\n })\n}\n\nexport function selectNext(\n detail: ProductDetail,\n current: ProductSelectionInput = {},\n optionSlug: string,\n valueSlug: string,\n options?: ProductSelectionCodecOptions,\n): NormalizedProductSelection {\n const matrix = buildProductOptionMatrixFromDetail(detail)\n const listing = detail.listing ?? {}\n const normalizedCurrent = normalizeProductSelectionFromMatrix(\n matrix,\n current,\n options,\n )\n\n const option = matrix.optionBySlug.get(optionSlug)\n if (!option) return normalizedCurrent\n\n const valueMatches = option.values.filter(\n (candidate) => candidate.slug === valueSlug,\n )\n if (valueMatches.length !== 1) return normalizedCurrent\n const clickedValueId = valueMatches[0]!.id\n\n const keepClickedSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>()\n selectedByOptionId.set(option.id, clickedValueId)\n\n for (const otherOptionId of matrix.optionIds) {\n if (otherOptionId === option.id) continue\n const otherValueId = normalizedCurrent.byOptionId[otherOptionId]\n if (!otherValueId) continue\n\n const constraintIds = normalizeSelectedValueIds(\n matrix,\n Array.from(selectedByOptionId.values()),\n )\n const available = getAvailableOptionValues(\n matrix,\n otherOptionId,\n constraintIds,\n )\n if (available.some((candidate) => candidate.id === otherValueId)) {\n selectedByOptionId.set(otherOptionId, otherValueId)\n }\n }\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n listing,\n )\n }\n\n const keepPriorSelection = (): NormalizedProductSelection => {\n const selectedByOptionId = new Map<string, string>(\n Object.entries(normalizedCurrent.byOptionId),\n )\n selectedByOptionId.delete(option.id)\n\n return buildFilledNormalizedSelection(\n matrix,\n normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),\n listing,\n )\n }\n\n const clickedResult = keepClickedSelection()\n const clickedVariantId = resolveVariantIdForCompleteSelection(\n matrix,\n new Map(Object.entries(clickedResult.byOptionId)),\n )\n\n const priorValueIds = Object.entries(normalizedCurrent.byOptionId)\n .filter(([otherOptionId]) => otherOptionId !== option.id)\n .map(([, valueId]) => valueId)\n\n const clickedAvailableWithPrior =\n priorValueIds.length === 0 ||\n getAvailableOptionValues(matrix, option.id, priorValueIds).some(\n (candidate) => candidate.id === clickedValueId,\n )\n\n if (clickedVariantId != null) {\n const priorClickedValue = normalizedCurrent.byOptionId[option.id]\n if (priorClickedValue != null && priorClickedValue !== clickedValueId) {\n return clickedResult\n }\n if (clickedAvailableWithPrior) {\n return clickedResult\n }\n }\n\n return keepPriorSelection()\n}\n\nexport type ProductDetailImageMedia = Extract<\n ProductDetailMedia,\n { id?: string | number | null; url?: string | null }\n>\n\nfunction isProductDetailImageMedia(\n value: ProductDetailMedia | null | undefined,\n): value is ProductDetailImageMedia {\n return typeof value === 'object' && value !== null\n}\n\nfunction mediaDedupeKey(value: ProductDetailImageMedia): string | null {\n if (value.id != null) return `id:${String(value.id)}`\n if (value.url) return `url:${value.url}`\n return null\n}\n\nexport function getProductSelectionImages(\n resolution: Pick<ProductSelectionResolution, 'media'>,\n): ProductDetailImageMedia[] {\n const seen = new Set<string>()\n const images: ProductDetailImageMedia[] = []\n const candidates = [\n resolution.media.primaryImage,\n ...resolution.media.images,\n ].filter(isProductDetailImageMedia)\n\n for (const candidate of candidates) {\n const key = mediaDedupeKey(candidate)\n if (key && seen.has(key)) continue\n if (key) seen.add(key)\n images.push(candidate)\n }\n\n return images\n}\n\nexport type ProductHrefProduct =\n | ProductDetail\n | {\n slug?: string | null\n product?: { slug?: string | null } | null\n }\n\nexport type ProductHrefGroup = {\n optionId?: string | number | null\n optionSlug?: string | null\n optionValueId?: string | number | null\n optionValueSlug?: string | null\n variantId?: string | number | null\n listing?: {\n selectionHintVariant?: string | number | null\n } | null\n}\n\nexport type ProductHrefOptions = {\n basePath?: string\n detail?: ProductDetail\n matrix?: ProductOptionMatrix<ProductDetailVariant>\n selection?: ProductSelectionInput\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nexport type ProductListingCardOptions = {\n basePath?: string\n trailingSlash?: boolean\n emit?: ProductSelectionUrlEmit\n preferCompleteVariantFromHint?: boolean\n}\n\nfunction getProductHrefSlug(product: ProductHrefProduct): string {\n if ('product' in product && product.product?.slug) {\n return product.product.slug\n }\n if ('slug' in product && product.slug) return product.slug\n throw new ProductSelectionCodecError(\n 'Product slug is required to build a product href.',\n )\n}\n\nfunction joinProductPath(\n basePath: string,\n slug: string,\n trailingSlash: boolean,\n) {\n const base = basePath.replace(/\\/+$/, '')\n const encodedSlug = encodeURIComponent(slug)\n return `${base}/${encodedSlug}${trailingSlash ? '/' : ''}`\n}\n\nfunction getProductHrefGroupSelection(\n group: ProductHrefGroup | null | undefined,\n matrix?: ProductOptionMatrix<ProductDetailVariant>,\n): ProductSelectionInput | null {\n if (!group) return null\n\n if (group.variantId != null) return { variantId: group.variantId }\n\n const optionId =\n group.optionId != null\n ? String(group.optionId)\n : group.optionSlug\n ? matrix?.optionBySlug.get(group.optionSlug)?.id\n : undefined\n if (!optionId) return null\n\n const option = matrix?.optionById.get(optionId)\n const optionValueId =\n group.optionValueId != null\n ? String(group.optionValueId)\n : group.optionValueSlug && option\n ? option.values.find((value) => value.slug === group.optionValueSlug)\n ?.id\n : undefined\n\n if (!optionValueId) return null\n return { byOptionId: { [optionId]: optionValueId } }\n}\n\nfunction getProductHrefCodecOptions(\n options: ProductHrefOptions,\n): ProductSelectionCodecOptions | undefined {\n return options.emit != null ? { emit: options.emit } : undefined\n}\n\nfunction appendGroupByOptionIdHrefParams(\n params: URLSearchParams,\n group: ProductHrefGroup | null | undefined,\n groupSelection: ProductSelectionInput,\n options: ProductHrefOptions,\n): boolean {\n const emit = resolveProductSelectionUrlEmit(options.emit)\n const byOptionId = groupSelection.byOptionId ?? {}\n const entries = Object.entries(byOptionId)\n if (entries.length === 0) return false\n\n for (const [optionId, valueId] of entries) {\n const optionSlug =\n group?.optionSlug ??\n options.matrix?.optionById.get(optionId)?.slug ??\n null\n const valueSlug =\n group?.optionValueSlug ??\n options.matrix?.valueById.get(String(valueId))?.slug ??\n null\n\n if (\n emit === 'slug-compat' &&\n optionSlug &&\n valueSlug &&\n entries.length === 1\n ) {\n params.set(`opt.${optionSlug}`, valueSlug)\n return true\n }\n\n if (\n emit === 'slug-compat' &&\n options.matrix &&\n appendSlugCompatSelectionParam(\n params,\n options.matrix,\n optionId,\n String(valueId),\n )\n ) {\n continue\n }\n appendCanonicalSelectionParam(params, optionId, String(valueId))\n }\n\n return params.size > 0\n}\n\nfunction getPreferCompleteVariantFromHintSelection(\n group: ProductHrefGroup | null | undefined,\n options: ProductHrefOptions,\n): ProductSelectionInput | null {\n if (!options.preferCompleteVariantFromHint) return null\n if (group?.optionValueId != null || group?.optionValueSlug) return null\n\n const hintVariantId = group?.listing?.selectionHintVariant\n if (hintVariantId == null) return null\n\n return { variantId: hintVariantId }\n}\n\nexport function buildProductHref(\n product: ProductHrefProduct,\n group?: ProductHrefGroup | null,\n options: ProductHrefOptions = {},\n): string {\n const path = joinProductPath(\n options.basePath ?? '/products',\n getProductHrefSlug(product),\n options.trailingSlash ?? false,\n )\n const params = new URLSearchParams()\n\n if (options.detail && options.selection) {\n const selection = stringifyProductSelection(\n options.detail,\n options.selection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n\n const preferVariantSelection = getPreferCompleteVariantFromHintSelection(\n group,\n options,\n )\n if (preferVariantSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n preferVariantSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (preferVariantSelection.variantId != null) {\n params.set('variant', String(preferVariantSelection.variantId))\n return `${path}?${params.toString()}`\n }\n }\n\n const groupSelection = getProductHrefGroupSelection(group, options.matrix)\n if (groupSelection) {\n if (options.detail) {\n const selection = stringifyProductSelection(\n options.detail,\n groupSelection,\n getProductHrefCodecOptions(options),\n )\n return selection ? `${path}?${selection}` : path\n }\n if (groupSelection.variantId != null) {\n params.set('variant', String(groupSelection.variantId))\n return `${path}?${params.toString()}`\n }\n if (\n appendGroupByOptionIdHrefParams(params, group, groupSelection, options)\n ) {\n return `${path}?${params.toString()}`\n }\n }\n\n if (group?.optionValueSlug) {\n const optionSlug =\n group.optionSlug ??\n (group.optionId != null\n ? options.matrix?.optionById.get(String(group.optionId))?.slug\n : undefined)\n if (optionSlug) {\n params.set(`opt.${optionSlug}`, group.optionValueSlug)\n }\n }\n\n return params.size > 0 ? `${path}?${params.toString()}` : path\n}\n\nfunction compareVariantOrder(a: ProductVariantShape, b: ProductVariantShape) {\n const aOrder = Number(a._order ?? Number.MAX_SAFE_INTEGER)\n const bOrder = Number(b._order ?? Number.MAX_SAFE_INTEGER)\n\n if (Number.isFinite(aOrder) && Number.isFinite(bOrder) && aOrder !== bOrder) {\n return aOrder - bOrder\n }\n\n const aId = String(getRelationID(a.id) ?? '')\n const bId = String(getRelationID(b.id) ?? '')\n return aId.localeCompare(bId)\n}\n\nfunction isVariantAvailableForSale(variant: ProductVariantShape) {\n if (variant.isActive === false) return false\n if (variant.isUnlimited) return true\n return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0\n}\n\nfunction sortVariantsForMediaSelection(\n variants: ProductVariantShape[],\n): ProductVariantShape[] {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const unavailableActiveVariants = activeVariants.filter(\n (variant) => !isVariantAvailableForSale(variant),\n )\n\n return [...availableVariants, ...unavailableActiveVariants]\n}\n\nfunction variantHasPoolMedia(\n variant: ProductVariantShape | null,\n productMediaPool: MediaValue[],\n): boolean {\n if (!variant?.images?.length) return false\n return variant.images.some((image) => {\n const imageId = getRelationID(image)\n return Boolean(\n imageId &&\n productMediaPool.some((poolItem) => getRelationID(poolItem) === imageId),\n )\n })\n}\n\nfunction getMinMax(values: Array<number | null | undefined>) {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number',\n )\n if (numbers.length === 0) {\n return { min: null, max: null }\n }\n\n return {\n min: Math.min(...numbers),\n max: Math.max(...numbers),\n }\n}\n\nexport function buildProductListingProjection(\n product: ProductListingProductShape | null | undefined,\n variants: ProductVariantShape[],\n): ProductListingProjection {\n const orderedVariants = [...variants].sort(compareVariantOrder)\n const activeVariants = orderedVariants.filter(\n (variant) => variant.isActive !== false,\n )\n const availableVariants = activeVariants.filter(isVariantAvailableForSale)\n const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null\n\n const { min: minPrice, max: maxPrice } = getMinMax(\n activeVariants.map((variant) => variant.price),\n )\n const { min: minCompareAtPrice, max: maxCompareAtPrice } = getMinMax(\n activeVariants.map((variant) => variant.compareAtPrice),\n )\n\n const productMediaPool = product?.images ?? []\n const selectionHintHasPoolMedia = variantHasPoolMedia(\n selectionHintVariant,\n productMediaPool,\n )\n const mediaSelectionVariants = sortVariantsForMediaSelection(variants)\n const resolvedProductMedia = resolveProductSelectionMedia<MediaValue>({\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product?.primaryMediaItemId),\n selectedVariant:\n selectionHintVariant && selectionHintHasPoolMedia\n ? {\n id: selectionHintVariant.id,\n images: selectionHintVariant.images,\n }\n : null,\n matchingVariants: selectionHintHasPoolMedia ? [] : mediaSelectionVariants,\n })\n\n return {\n selectionHintVariant: getRelationID(selectionHintVariant?.id) ?? null,\n primaryImage: resolveGenericListingPrimaryImage(\n product,\n resolvedProductMedia.primaryImage,\n resolvedProductMedia.source,\n ),\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange:\n minPrice !== null && maxPrice !== null ? minPrice !== maxPrice : false,\n availableForSale: availableVariants.length > 0,\n }\n}\n\nexport function buildProductListingCard(\n item: ProductListingGroupsItem,\n options: ProductListingCardOptions = {},\n): ProductListingCard {\n const product = item.product\n const groups = item.groups\n const variants = getProductListingCardVariants(item)\n const projectedListing = buildProductListingProjection(product, variants)\n const selectionHintVariant =\n getRelationID(product.listing?.selectionHintVariant) ??\n projectedListing.selectionHintVariant\n const representativeVariant = findListingCardRepresentativeVariant(\n variants,\n selectionHintVariant,\n )\n\n const productMediaPool = mediaArray(product.images)\n const representativeHasPoolMedia = Boolean(\n representativeVariant?.images?.some((image) =>\n productMediaPool.some(\n (poolItem) => getRelationID(poolItem) === getRelationID(image),\n ),\n ),\n )\n const resolvedPrimaryMedia = resolveProductSelectionMedia<ProductDetailMedia>(\n {\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),\n selectedVariant: representativeHasPoolMedia\n ? representativeVariant\n : null,\n matchingVariants: representativeHasPoolMedia ? [] : variants,\n },\n )\n const listingPrimaryPointer = resolveListingPrimaryImagePointer({\n productMediaPool,\n productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),\n productThumbnail: product.thumbnail ?? null,\n listingPrimaryImage: product.listing?.primaryImage ?? null,\n resolvedPrimary: resolvedPrimaryMedia.primaryImage,\n resolvedSource: resolvedPrimaryMedia.source,\n })\n const listingPrimaryMedia = listingPrimaryPointer\n ? (productMediaPool.find(\n (item) => getRelationID(item) === listingPrimaryPointer,\n ) ??\n resolvedPrimaryMedia.primaryImage ??\n null)\n : null\n\n const priceRange = resolveListingCardPriceRange(\n product,\n projectedListing,\n groups,\n )\n\n const availableForSale =\n product.listing?.availableForSale != null\n ? product.listing.availableForSale\n : groups.length > 0\n ? groups.some((group) => group.listing.availableForSale)\n : projectedListing.availableForSale\n\n const swatches: ProductListingSwatch[] =\n groups.length > 1\n ? groups.map((group) => buildListingSwatch(product, group, options))\n : []\n\n return {\n id: String(product.id),\n href: buildProductHref(\n { slug: product.slug },\n { listing: { selectionHintVariant } },\n options,\n ),\n title: product.title,\n representativeVariant,\n primaryImage: listingPrimaryMedia,\n priceRange,\n availableForSale,\n swatches,\n }\n}\n\nfunction getProductListingCardVariants(\n item: ProductListingGroupsItem,\n): ProductListingCardRepresentativeVariant[] {\n const productVariants = item.product.variants?.docs\n if (Array.isArray(productVariants) && productVariants.length > 0) {\n return productVariants\n }\n\n const variants: ProductListingCardRepresentativeVariant[] = []\n const seen = new Set<string>()\n\n for (const group of item.groups) {\n for (const variant of group.variants) {\n const id = getRelationID(variant.id)\n if (id && seen.has(id)) continue\n if (id) seen.add(id)\n variants.push(variant)\n }\n }\n\n return variants\n}\n\nfunction findListingCardRepresentativeVariant(\n variants: ProductListingCardRepresentativeVariant[],\n representativeVariantId: EntityID | null,\n): ProductListingCardRepresentativeVariant | null {\n if (representativeVariantId == null) return null\n return (\n variants.find(\n (variant) => getRelationID(variant.id) === representativeVariantId,\n ) ?? null\n )\n}\n\n/** Shopify `priceRangeV2` naming for persisted listing projection fields. */\nexport function toShopifyPriceRangeV2(listing: {\n minPrice?: number | null\n maxPrice?: number | null\n}): {\n minVariantPrice: { amount: number | null }\n maxVariantPrice: { amount: number | null }\n} {\n return {\n minVariantPrice: { amount: listing.minPrice ?? null },\n maxVariantPrice: { amount: listing.maxPrice ?? null },\n }\n}\n\nfunction hasCompleteListingPriceProjection(\n listing: ProductListingGroupsItem['product']['listing'] | null | undefined,\n): listing is NonNullable<ProductListingGroupsItem['product']['listing']> & {\n minPrice: number\n maxPrice: number\n} {\n return listing?.minPrice != null && listing?.maxPrice != null\n}\n\nfunction listingDefinesCompareAtProjection(\n listing: NonNullable<ProductListingGroupsItem['product']['listing']>,\n): boolean {\n return 'minCompareAtPrice' in listing || 'maxCompareAtPrice' in listing\n}\n\nfunction resolveListingCardPriceRange(\n product: ProductListingGroupsItem['product'],\n projectedListing: ReturnType<typeof buildProductListingProjection>,\n groups: ProductListingGroupsItem['groups'],\n): ProductListingCardPriceRange {\n const listing = product.listing\n if (hasCompleteListingPriceProjection(listing)) {\n const groupRange =\n groups.length > 0 ? aggregateListingPriceRange(groups) : null\n const definesCompareAt = listingDefinesCompareAtProjection(listing)\n\n return {\n minPrice: listing.minPrice,\n maxPrice: listing.maxPrice,\n minCompareAtPrice: definesCompareAt\n ? (listing.minCompareAtPrice ?? null)\n : (groupRange?.minCompareAtPrice ??\n projectedListing.minCompareAtPrice),\n maxCompareAtPrice: definesCompareAt\n ? (listing.maxCompareAtPrice ?? null)\n : (groupRange?.maxCompareAtPrice ??\n projectedListing.maxCompareAtPrice),\n isPriceRange:\n listing.isPriceRange ??\n (listing.minPrice !== listing.maxPrice),\n }\n }\n\n if (groups.length > 0) {\n return aggregateListingPriceRange(groups)\n }\n\n return {\n minPrice: projectedListing.minPrice,\n maxPrice: projectedListing.maxPrice,\n minCompareAtPrice: projectedListing.minCompareAtPrice,\n maxCompareAtPrice: projectedListing.maxCompareAtPrice,\n isPriceRange: projectedListing.isPriceRange,\n }\n}\n\nfunction aggregateListingPriceRange(\n groups: ProductListingGroupsItem['groups'],\n): ProductListingCardPriceRange {\n const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice))\n const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice))\n const minCompareAtPrice = minOfNullable(\n groups.map((g) => g.listing.minCompareAtPrice),\n )\n const maxCompareAtPrice = maxOfNullable(\n groups.map((g) => g.listing.maxCompareAtPrice),\n )\n const isPriceRange =\n minPrice !== null && maxPrice !== null && minPrice !== maxPrice\n return {\n minPrice,\n maxPrice,\n minCompareAtPrice,\n maxCompareAtPrice,\n isPriceRange,\n }\n}\n\nfunction buildListingSwatch(\n product: ProductListingGroupsItem['product'],\n group: ProductListingGroupsItem['groups'][number],\n options: ProductListingCardOptions,\n): ProductListingSwatch {\n return {\n optionId: group.optionId,\n optionValueId: group.optionValueId,\n label: group.optionValueLabel,\n swatch: group.optionValueSwatch ?? null,\n href: buildProductHref(\n { slug: product.slug },\n {\n optionId: group.optionId,\n optionSlug: group.optionSlug,\n optionValueId: group.optionValueId,\n optionValueSlug: group.optionValueSlug,\n listing: group.listing,\n },\n options,\n ),\n availableForSale: group.listing.availableForSale,\n }\n}\n\nfunction minOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.min(...numbers)\n}\n\nfunction maxOfNullable(values: Array<number | null>): number | null {\n const numbers = values.filter((v): v is number => v !== null)\n return numbers.length === 0 ? null : Math.max(...numbers)\n}\n\n/**\n * PLP-safe query preset for the `products` collection.\n *\n * Payload's top-level `type: 'join'` fields on `products` (`variants`,\n * `options`) return at most 10 docs by default when queried via the REST API.\n * Storefront PLPs calling `client.collections.from('products').find()` without\n * explicit join limits silently receive truncated variant/option join data.\n * `buildProductListingGroupsByOption()` then drops primary-option values with\n * no matching variant in the response — a common cause of missing color swatches\n * even when the product has more variants than the default join cap.\n *\n * Spread this constant into your `find()` call to raise both top-level limits:\n *\n * ```typescript\n * const { docs } = await client.collections.from('products').find({\n * ...PRODUCT_PLP_FIND_OPTIONS,\n * where: { status: { equals: 'published' } },\n * limit: 24,\n * })\n * ```\n *\n * **Limitation:** This preset cures top-level `products.options` and\n * `products.variants` join truncation. It cannot cure the nested\n * `options[].values.docs` join — the Payload REST `joins` param is flat and\n * nested join limits require the listing-groups endpoint. Prefer\n * `commerce.product.listingGroupsCatalog()` + `buildProductListingCard()` as\n * the primary PLP path; they apply unlimited join fetches server-side and\n * return pre-grouped data ready for rendering.\n */\nexport const PRODUCT_PLP_FIND_OPTIONS: ApiQueryOptions = {\n joins: {\n variants: { limit: 200, sort: '_order' },\n options: { limit: 50, sort: '_order' },\n },\n}\n\n/**\n * Builds product-first listing groups for one primary option.\n *\n * The returned groups are intended for product cards with nested swatches or\n * option-value sections. They do not make a product-paginated API response into\n * an expanded-card paginator; one product can still emit several groups.\n */\nexport function buildProductListingGroupsByOption<\n TVariant extends ProductVariantShape = ProductVariantShape,\n>(args: {\n product: ProductListingProductShape | null | undefined\n options: ProductOptionShape[]\n variants: TVariant[]\n primaryOptionId?: string | null\n}): ProductListingGroup<TVariant>[] {\n const primaryOptionId = args.primaryOptionId ?? undefined\n if (!primaryOptionId) return []\n\n const matrix = buildProductOptionMatrix({\n options: args.options,\n variants: args.variants,\n })\n const primaryOption = matrix.optionById.get(primaryOptionId)\n if (!primaryOption) return []\n\n return primaryOption.values.flatMap((value) => {\n const variants = matrix.variants\n .filter(\n (variant) =>\n variant.optionValueByOptionId.get(primaryOption.id) === value.id,\n )\n .map((variant) => variant.source)\n\n if (variants.length === 0) {\n return []\n }\n\n const listingBase = buildProductListingProjection(undefined, variants)\n const orderedVariants = sortVariantsForMediaSelection(variants)\n const productMediaPool = (args.product?.images ?? []).filter(\n (image): image is ProductDetailMedia =>\n image != null && typeof image === 'object',\n )\n const resolvedMedia = resolveProductSelectionMedia<ProductDetailMedia>({\n productMediaPool,\n productPrimaryMediaItemId: extractEntityId(\n args.product?.primaryMediaItemId ?? null,\n ),\n selectedVariant: null,\n matchingVariants: orderedVariants,\n selectedOptionValues: [\n {\n id: value.id,\n swatch: normalizeMatrixSwatch(value.swatch),\n },\n ],\n })\n const groupPrimaryImage =\n extractEntityId(resolvedMedia.primaryImage) ??\n getFirstAvailableVariantPrimaryImage(variants) ??\n extractEntityId(args.product?.thumbnail) ??\n getFirstMediaId(args.product?.images)\n\n return [\n {\n optionId: primaryOption.id,\n optionTitle: primaryOption.title,\n optionSlug: primaryOption.slug,\n optionValueId: value.id,\n optionValueLabel: value.label,\n optionValueSlug: value.slug,\n optionValueSwatch: value.swatch ?? null,\n variantIds: variants.map((variant) => String(variant.id)),\n variantCount: variants.length,\n variants,\n listing: {\n ...listingBase,\n primaryImage: groupPrimaryImage,\n },\n },\n ]\n })\n}\n","import {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n type ProductDisplayMediaSource,\n type ProductSelectionMediaSource,\n type ResolveProductSelectionMediaInput,\n type ResolveProductSelectionMediaResult,\n} from './product-selection-media'\n\nexport type { NormalizedOptionSwatch } from './product-selection-media'\nexport { selectedSwatchMediaItemId } from './product-selection-media'\n\n/** @deprecated Use `ProductSelectionMediaSource` or `ProductDisplayMediaSource`. */\nexport type MediaPointerSource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n | 'variant_featured'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput`. */\nexport type ResolveProductMediaInput<TMedia> =\n ResolveProductSelectionMediaInput<TMedia> & {\n variantFeaturedMediaItemId?: string | number | null\n selectedOptionValueMediaItemIds?: Array<string | number | null | undefined>\n legacy?: {\n variantThumbnail?: TMedia | null\n variantImages?: TMedia[] | null\n optionValueThumbnails?: Array<TMedia | null | undefined>\n optionValueImages?: Array<TMedia[] | null | undefined>\n productThumbnail?: TMedia | null\n productImages?: TMedia[] | null\n }\n }\n\n/** @deprecated Use `ResolveProductSelectionMediaResult`. */\nexport type ResolveProductMediaResult<TMedia> = Omit<\n ResolveProductSelectionMediaResult<TMedia>,\n 'source'\n> & {\n source: MediaPointerSource\n}\n\nfunction mediaPointerOptionValues(\n values: Array<string | number | null | undefined> | undefined,\n) {\n return (values ?? [])\n .filter((value): value is string | number => value != null && value !== '')\n .map((value) => ({\n swatch: {\n type: 'media' as const,\n mediaItemId: value,\n },\n }))\n}\n\n/**\n * @deprecated One-release shim for ADR 0016. Prefer\n * `resolveProductSelectionMedia()`. Legacy direct-media fallbacks are ignored;\n * callers fall through to product display media (`resolveProductDisplayMedia`)\n * or `none`.\n */\nexport function resolveProductMedia<TMedia>(\n input: ResolveProductMediaInput<TMedia>,\n): ResolveProductMediaResult<TMedia> {\n const resolved = resolveProductSelectionMedia({\n ...input,\n selectedVariant:\n input.selectedVariant ??\n (input.variantFeaturedMediaItemId\n ? { images: [input.variantFeaturedMediaItemId] }\n : null),\n selectedOptionValues:\n input.selectedOptionValues ??\n mediaPointerOptionValues(input.selectedOptionValueMediaItemIds),\n })\n\n if (resolved.source !== 'none') {\n return {\n ...resolved,\n source:\n resolved.source === 'variant_media_selected'\n ? 'variant_featured'\n : resolved.source,\n }\n }\n\n const display = resolveProductDisplayMedia({\n productMediaPool: input.productMediaPool,\n productPrimaryMediaItemId: input.productPrimaryMediaItemId,\n })\n\n return {\n primaryImage: display.primaryImage,\n images: display.images,\n source: display.source,\n }\n}\n","import {\n resolveProductDisplayMedia,\n resolveProductSelectionMedia,\n type ProductDisplayMediaSource,\n type ProductSelectionMediaPointer,\n type ProductSelectionMediaSource,\n type ResolveProductSelectionMediaInput,\n} from './product-selection-media'\n\n/** @deprecated ADR 0016 replaces media sets with variant `images[]` subsets. */\nexport type ProductMediaSetMatchType =\n | 'default'\n | 'option-values'\n | 'exact-variant'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput` and variant `images[]`. */\nexport type ProductMediaSetInput = {\n label?: string | null\n matchType: ProductMediaSetMatchType\n optionValueIds?: Array<string | number | null | undefined> | null\n variantIds?: Array<string | number | null | undefined> | null\n items: Array<string | number | null | undefined>\n primaryMediaItemId?: string | number | null\n}\n\ntype LegacyProductGallerySource =\n | 'exact_variant_set'\n | 'option_value_set'\n | 'default_set'\n\n/** @deprecated Use `ResolveProductSelectionMediaInput`. */\nexport type ResolveProductGalleryInput<TMedia> =\n ResolveProductSelectionMediaInput<TMedia> & {\n pool?: TMedia[] | null\n mediaSets?: ProductMediaSetInput[] | null\n selectedVariantId?: string | number | null\n selectedOptionValueIds?: Array<string | number | null | undefined> | null\n listingPrimaryImage?: ProductSelectionMediaPointer\n }\n\n/** @deprecated Use selection or display media source types. */\nexport type ProductGallerySource =\n | ProductSelectionMediaSource\n | ProductDisplayMediaSource\n | LegacyProductGallerySource\n\n/** @deprecated Use `ResolveProductSelectionMediaResult`. */\nexport type ResolveProductGalleryResult<TMedia> = {\n primaryImage: TMedia | null\n images: TMedia[]\n source: ProductGallerySource\n}\n\ntype MediaWithOptionalId = {\n id?: string | number | null\n}\n\nfunction mediaId(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as MediaWithOptionalId).id\n if (typeof id === 'string' || typeof id === 'number') return String(id)\n }\n\n return null\n}\n\nfunction relationshipIds(\n values: Array<string | number | null | undefined> | null | undefined,\n): string[] {\n if (!Array.isArray(values)) return []\n return values\n .map((value) => mediaId(value))\n .filter((value): value is string => Boolean(value))\n}\n\nfunction buildPoolById<TMedia>(pool: TMedia[]): Map<string, TMedia> {\n const poolById = new Map<string, TMedia>()\n for (const item of pool) {\n const id = mediaId(item)\n if (id) poolById.set(id, item)\n }\n return poolById\n}\n\nfunction mediaSetItemsInPool<TMedia>(\n mediaSet: ProductMediaSetInput,\n poolById: Map<string, TMedia>,\n): TMedia[] {\n const seen = new Set<string>()\n const items: TMedia[] = []\n const primaryId = mediaId(mediaSet.primaryMediaItemId)\n\n if (primaryId) {\n const primary = poolById.get(primaryId)\n if (primary) {\n seen.add(primaryId)\n items.push(primary)\n }\n }\n\n for (const itemId of relationshipIds(mediaSet.items)) {\n if (seen.has(itemId)) continue\n const item = poolById.get(itemId)\n if (!item) continue\n seen.add(itemId)\n items.push(item)\n }\n\n return items\n}\n\nfunction resolveLegacyMediaSet<TMedia>(\n input: ResolveProductGalleryInput<TMedia>,\n): ResolveProductGalleryResult<TMedia> | null {\n if (!Array.isArray(input.mediaSets)) return null\n\n const pool = input.productMediaPool ?? input.pool ?? []\n const poolById = buildPoolById(pool)\n\n const selectedVariantId = mediaId(input.selectedVariantId)\n if (selectedVariantId) {\n const exactSet = input.mediaSets.find(\n (set) =>\n set.matchType === 'exact-variant' &&\n relationshipIds(set.variantIds).includes(selectedVariantId),\n )\n if (exactSet) {\n const images = mediaSetItemsInPool(exactSet, poolById)\n if (images.length > 0) {\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'exact_variant_set',\n }\n }\n }\n }\n\n const selectedOptionValueIds = new Set(\n relationshipIds(input.selectedOptionValueIds),\n )\n const optionSetMatches = input.mediaSets\n .filter((set) => set.matchType === 'option-values')\n .map((set) => {\n const optionValueIds = relationshipIds(set.optionValueIds)\n if (optionValueIds.length === 0) return null\n if (!optionValueIds.every((id) => selectedOptionValueIds.has(id))) {\n return null\n }\n const images = mediaSetItemsInPool(set, poolById)\n if (images.length === 0) return null\n return { optionValueCount: optionValueIds.length, images }\n })\n .filter(\n (\n match,\n ): match is {\n optionValueCount: number\n images: TMedia[]\n } => Boolean(match),\n )\n .sort((a, b) => b.optionValueCount - a.optionValueCount)\n\n if (optionSetMatches.length > 0) {\n const images = optionSetMatches[0]!.images\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'option_value_set',\n }\n }\n\n const defaultSet = input.mediaSets.find((set) => set.matchType === 'default')\n if (defaultSet) {\n const images = mediaSetItemsInPool(defaultSet, poolById)\n if (images.length > 0) {\n return {\n primaryImage: images[0] ?? null,\n images,\n source: 'default_set',\n }\n }\n }\n\n return {\n primaryImage: null,\n images: [],\n source: 'none',\n }\n}\n\n/** @deprecated Use `resolveProductSelectionMedia()`. */\nexport function resolveProductGallery<TMedia>(\n input: ResolveProductGalleryInput<TMedia>,\n): ResolveProductGalleryResult<TMedia> {\n const legacyResolved = resolveLegacyMediaSet(input)\n if (legacyResolved && legacyResolved.source !== 'none') return legacyResolved\n\n const selectedVariantId = mediaId(input.selectedVariantId)\n const selectedOptionValueIds = relationshipIds(input.selectedOptionValueIds)\n\n const selection = resolveProductSelectionMedia({\n ...input,\n productMediaPool: input.productMediaPool ?? input.pool ?? null,\n selectedVariant:\n input.selectedVariant ??\n (selectedVariantId ? { id: selectedVariantId } : null),\n selectedOptionValues:\n input.selectedOptionValues ??\n selectedOptionValueIds.map((id) => ({ id })),\n })\n\n if (selection.source !== 'none') {\n return selection\n }\n\n return resolveProductDisplayMedia({\n productMediaPool: input.productMediaPool ?? input.pool ?? null,\n productPrimaryMediaItemId: input.productPrimaryMediaItemId,\n listingPrimaryImage: input.listingPrimaryImage,\n })\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Structural image size entry accepted by public image helpers. */\nexport interface ImageDataSizeEntry {\n url?: string | null\n width?: number | null\n height?: number | null\n}\n\n/** Structural image sizes accepted from Payload upload-like collections. */\nexport type ImageDataSizes = Partial<\n Record<string, ImageDataSizeEntry | null | undefined>\n>\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: ImageDataSizes\n}\n\n/** Pre-generated image size breakpoints (px), aligned with Payload Image.sizes. */\nexport const IMAGE_SIZES = [200, 400, 800, 1200, 1600] as const\n\n/** Numeric rendition keys from `IMAGE_SIZES` plus any numeric keys on the image. */\nfunction imageSizeCandidates(sizes: ImageDataSizes): number[] {\n const keys = new Set<number>(IMAGE_SIZES)\n for (const key of Object.keys(sizes)) {\n const value = Number(key)\n if (Number.isFinite(value) && value > 0) keys.add(value)\n }\n return [...keys].sort((a, b) => a - b)\n}\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n if (size >= target) {\n const entry = sizes[`${size}`]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-200 200w, url-400 400w, url-800 800w, url-1200 1200w, url-1600 1600w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const emittedWidths = new Set<number>()\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of imageSizeCandidates(sizes)) {\n const entry = sizes[`${size}`]\n if (entry?.url && entry.width && !emittedWidths.has(entry.width)) {\n emittedWidths.add(entry.width)\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width && !emittedWidths.has(image.width)) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n","export const generateOrderNumber = () => {\n // YYMMDDRRRRRR\n const now = new Date()\n const year = now.getFullYear().toString().slice(-2)\n const month = (now.getMonth() + 1).toString().padStart(2, '0')\n const day = now.getDate().toString().padStart(2, '0')\n // Use crypto.getRandomValues for cryptographically secure randomness (works in both browser and Node.js)\n const array = new Uint32Array(1)\n globalThis.crypto.getRandomValues(array)\n const random = ((array[0] ?? 0) % 1000000).toString().padStart(6, '0')\n\n return `${year}${month}${day}${random}`\n}\n","import { Product } from '../../payload-types'\nimport { resolveRelation } from '../types'\n\ntype OrderItem = {\n product: Product | string | null | undefined\n}\n\nexport const formatOrderName = (items: OrderItem[]) => {\n if (items.length === 0) return ''\n\n const firstTitle = resolveRelation(items[0]?.product)?.title || ''\n\n return items.length === 1\n ? firstTitle\n : `${firstTitle} 외 ${items.length - 1}건`\n}\n","const MUX_IMAGE_BASE = 'https://image.mux.com'\nconst MUX_STREAM_BASE = 'https://stream.mux.com'\n\n// ── Thumbnail ──\n\nexport interface VideoThumbnailOptions {\n /** Width in pixels (default: 640) */\n width?: number\n /** Height in pixels (auto if omitted) */\n height?: number\n /** Time offset in seconds (default: 0) */\n time?: number\n /** Fit mode (default: 'smartcrop') */\n fitMode?: 'preserve' | 'stretch' | 'crop' | 'smartcrop' | 'pad'\n /** Flip horizontally */\n flipH?: boolean\n /** Flip vertically */\n flipV?: boolean\n /** Rotation in degrees (90, 180, 270) */\n rotate?: 90 | 180 | 270\n}\n\n/**\n * Returns a Mux thumbnail URL for a video.\n *\n * @example\n * ```ts\n * getVideoThumbnail('abc123')\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=640'\n *\n * getVideoThumbnail('abc123', { width: 320, time: 5 })\n * // => 'https://image.mux.com/abc123/thumbnail.jpg?width=320&time=5'\n * ```\n */\nexport function getVideoThumbnail(\n playbackId: string,\n options?: VideoThumbnailOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 640))\n if (options?.height) params.set('height', String(options.height))\n if (options?.time != null) params.set('time', String(options.time))\n if (options?.fitMode) params.set('fit_mode', options.fitMode)\n if (options?.flipH) params.set('flip_h', 'true')\n if (options?.flipV) params.set('flip_v', 'true')\n if (options?.rotate) params.set('rotate', String(options.rotate))\n return `${MUX_IMAGE_BASE}/${playbackId}/thumbnail.jpg?${params}`\n}\n\n// ── Animated GIF ──\n\nexport interface VideoGifOptions {\n /** Width in pixels (default: 320) */\n width?: number\n /** Start time in seconds (default: 0) */\n start?: number\n /** End time in seconds (default: start + 5) */\n end?: number\n /** Frames per second (default: 15) */\n fps?: number\n}\n\n/**\n * Returns a Mux animated GIF URL for a video.\n *\n * @example\n * ```ts\n * getVideoGif('abc123')\n * // => 'https://image.mux.com/abc123/animated.gif?width=320'\n *\n * getVideoGif('abc123', { width: 240, start: 2, end: 6 })\n * // => 'https://image.mux.com/abc123/animated.gif?width=240&start=2&end=6'\n * ```\n */\nexport function getVideoGif(\n playbackId: string,\n options?: VideoGifOptions,\n): string {\n const params = new URLSearchParams()\n params.set('width', String(options?.width ?? 320))\n if (options?.start != null) params.set('start', String(options.start))\n if (options?.end != null) params.set('end', String(options.end))\n if (options?.fps) params.set('fps', String(options.fps))\n return `${MUX_IMAGE_BASE}/${playbackId}/animated.gif?${params}`\n}\n\n// ── Storyboard ──\n\n/**\n * Returns a Mux storyboard VTT URL for timeline hover previews.\n *\n * @example\n * ```ts\n * getVideoStoryboard('abc123')\n * // => 'https://image.mux.com/abc123/storyboard.vtt'\n * ```\n */\nexport function getVideoStoryboard(playbackId: string): string {\n return `${MUX_IMAGE_BASE}/${playbackId}/storyboard.vtt`\n}\n\n// ── Stream / Playback URLs ──\n\n/**\n * Returns the HLS stream URL for a video.\n *\n * @example\n * ```ts\n * getVideoStreamUrl('abc123')\n * // => 'https://stream.mux.com/abc123.m3u8'\n * ```\n */\nexport function getVideoStreamUrl(playbackId: string): string {\n return `${MUX_STREAM_BASE}/${playbackId}.m3u8`\n}\n\n/**\n * Returns a Mux MP4 download URL for a video.\n * Only available if the asset was created with `mp4_support` enabled.\n *\n * @example\n * ```ts\n * getVideoMp4Url('abc123', 'high')\n * // => 'https://stream.mux.com/abc123/high.mp4'\n * ```\n */\nexport function getVideoMp4Url(\n playbackId: string,\n resolution: 'high' | 'medium' | 'low' = 'high',\n): string {\n return `${MUX_STREAM_BASE}/${playbackId}/${resolution}.mp4`\n}\n","/**\n * @01.software/sdk — Analytics Helper\n */\n\n/* ANALYTICS INVARIANTS START\n * @01.software/sdk — Analytics Helper\n *\n * ANALYTICS INVARIANTS\n * ====================\n * These invariants are the single source of truth for observable behavior.\n * They are mirrored verbatim in apps/console/src/app/api/analytics/script.js/route.ts.\n * Any change here MUST be reflected there, and vice versa.\n *\n * 1. DNT/GPC respect: when config.respectDnt !== false (default true) AND\n * (navigator.doNotTrack === '1' OR navigator.globalPrivacyControl === true),\n * all methods become no-ops. Zero network requests are made.\n *\n * 2. Prerender skip: when document.prerendering === true OR\n * document.visibilityState === 'prerender', pageview() sends zero requests.\n *\n * 3. 500ms same-path dedup: a pageview for the same pathname within 500ms of\n * the previous send is silently dropped. After 500ms the next call sends.\n *\n * 4. Transport: sendBeacon → fetch keepalive fallback.\n * Primary: navigator.sendBeacon(endpoint, new Blob([json], { type: 'text/plain' })).\n * Fallback (sendBeacon unavailable OR returns false):\n * fetch(endpoint, { method: 'POST', keepalive: true,\n * headers: { 'Content-Type': 'application/json' }, body: json }).catch(() => {})\n *\n * 5. Body-only publishableKey: publishableKey is always in the request body,\n * never in any HTTP header.\n *\n * 6. SSR no-op: when typeof window === 'undefined', createAnalytics() returns\n * a stub where all methods are no-ops. No side effects occur.\n *\n * 7. Error swallowing: all transport errors are caught and swallowed.\n * createAnalytics() and all returned methods never throw into the caller.\n *\n * 8. Client timestamp: every send carries eventTs (milliseconds since epoch)\n * captured with Date.now() immediately before transport. The collect\n * endpoint uses eventTs (a) to bucket the event into the client's\n * tenant-local day and (b) to enforce the late-arrival cutoff; events\n * submitted after the local-day-end grace window are dropped with\n * reason \"late\".\n *\n * 9. Dev / local-host send skip: in 'auto' mode (the default) all send paths\n * become no-ops when the page runs on a local host — location.hostname is\n * 'localhost', '127.0.0.1', or ends with '.local'. Validation and dev\n * warnings still run; only the network send is suppressed, and a one-time\n * console notice is emitted. SSR (6), DNT/GPC (1), and prerender (2) skips\n * are evaluated first. Overrides: the SDK accepts mode 'production' (always\n * send, even locally) and 'development' (never send, on any host); the\n * mirrored hosted snippet accepts captureOnLocalhost === true (via\n * window.__01_analytics__.captureOnLocalhost or the script's\n * data-capture-localhost attribute) to force sending on a local host.\n * ANALYTICS INVARIANTS END */\n\nimport { resolveApiUrl } from './core/client/types'\n\n// ============================================================================\n// Public Types\n// ============================================================================\n\nexport interface AnalyticsConfig {\n publishableKey: string\n /** Override the collect endpoint URL. Defaults to {SDK_BASE_URL}/api/analytics/collect */\n endpoint?: string\n /** Auto-patch history.pushState/replaceState and listen to popstate. Default: true */\n autoTrack?: boolean\n /** Respect navigator.doNotTrack and navigator.globalPrivacyControl. Default: true */\n respectDnt?: boolean\n /**\n * Send mode. 'auto' (default) skips all sends on local hosts\n * (localhost / 127.0.0.1 / *.local). 'production' always sends, even\n * locally. 'development' never sends, on any host. See INVARIANT 9.\n */\n mode?: 'auto' | 'production' | 'development'\n}\n\nexport interface Analytics {\n pageview(path?: string): void\n track(name: string, props?: Record<string, string | number | boolean>): void\n destroy(): void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport function createAnalytics(config: AnalyticsConfig): Analytics {\n // INVARIANT 6: SSR no-op\n if (typeof window === 'undefined') {\n return { pageview() {}, track() {}, destroy() {} }\n }\n\n const endpoint =\n config.endpoint ?? `${resolveApiUrl()}/api/analytics/collect`\n\n // INVARIANT 1: DNT/GPC check (evaluated once at init; stays as closure)\n const respectDnt = config.respectDnt !== false\n function isDntActive(): boolean {\n if (!respectDnt) return false\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean }\n return nav.doNotTrack === '1' || nav.globalPrivacyControl === true\n }\n\n // INVARIANT 9: local-host detection drives both dev warnings and the\n // auto send-skip. Hostname is the one signal shared with the hosted snippet.\n const isLocalHost: boolean = (() => {\n try {\n const h = location.hostname\n return h === 'localhost' || h === '127.0.0.1' || h.endsWith('.local')\n } catch {\n return false\n }\n })()\n\n const mode = config.mode ?? 'auto'\n const sendSuppressed =\n mode === 'development' || (mode === 'auto' && isLocalHost)\n\n let suppressNoticeShown = false\n function devSuppressNotice(): void {\n if (suppressNoticeShown) return\n suppressNoticeShown = true\n try {\n console.info(\n `[01 analytics] events disabled on local host (mode: '${mode}'). ` +\n `Pass mode: 'production' to send while developing.`,\n )\n } catch {\n // INVARIANT 7: swallow\n }\n }\n\n // INVARIANT 3: 500ms same-path dedup state\n let lastPath: string | null = null\n let lastAt = 0\n\n // autoTrack state — save originals for destroy()\n const autoTrack = config.autoTrack !== false\n const originalPushState = history.pushState\n const originalReplaceState = history.replaceState\n let destroyed = false\n\n // -------------------------------------------------------------------------\n // Core send logic\n // -------------------------------------------------------------------------\n\n // Generate a unique event ID (crypto.randomUUID when available, Date+Math.random fallback)\n function newEventId(): string {\n return typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : String(Date.now()) + String(Math.random())\n }\n\n // INVARIANT 4: sendBeacon → fetch keepalive fallback\n // INVARIANT 5: publishableKey in body only\n function sendBeaconOrFetch(body: string): void {\n try {\n if (typeof navigator.sendBeacon === 'function') {\n const blob = new Blob([body], { type: 'text/plain' })\n const sent = navigator.sendBeacon(endpoint, blob)\n if (sent) return\n // sent === false → fall through to fetch\n }\n // Fetch fallback\n fetch(endpoint, {\n method: 'POST',\n keepalive: true,\n headers: { 'Content-Type': 'application/json' },\n body,\n }).catch(() => {})\n } catch {\n // INVARIANT 7: swallow all errors\n }\n }\n\n function sendPageview(pathname: string): void {\n // INVARIANT 1: DNT/GPC\n if (isDntActive()) return\n\n // INVARIANT 2: prerender skip\n const doc = document as Document & { prerendering?: boolean }\n // visibilityState cast to string to accommodate non-standard 'prerender' value\n if (doc.prerendering === true || (document.visibilityState as string) === 'prerender') return\n\n // INVARIANT 9: skip sends on local hosts in auto mode\n if (sendSuppressed) {\n devSuppressNotice()\n return\n }\n\n // INVARIANT 3: 500ms same-path dedup\n const now = Date.now()\n if (pathname === lastPath && now - lastAt < 500) return\n lastPath = pathname\n lastAt = now\n\n const body = JSON.stringify({\n publishableKey: config.publishableKey,\n pathname,\n referrer: document.referrer || '',\n eventId: newEventId(),\n eventTs: Date.now(),\n })\n\n sendBeaconOrFetch(body)\n }\n\n // -------------------------------------------------------------------------\n // autoTrack: patch history methods + listen to popstate\n // -------------------------------------------------------------------------\n function trackCurrentPath(): void {\n if (destroyed) return\n sendPageview(location.pathname)\n }\n\n function patchedPushState(\n this: History,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n originalPushState.apply(this, [data, unused, url] as Parameters<typeof history.pushState>)\n if (!destroyed) setTimeout(trackCurrentPath, 0)\n }\n\n function patchedReplaceState(\n this: History,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n originalReplaceState.apply(this, [data, unused, url] as Parameters<typeof history.replaceState>)\n if (!destroyed) setTimeout(trackCurrentPath, 0)\n }\n\n if (autoTrack) {\n history.pushState = patchedPushState\n history.replaceState = patchedReplaceState\n window.addEventListener('popstate', trackCurrentPath)\n\n // Initial pageview\n if (document.readyState === 'complete') {\n trackCurrentPath()\n } else {\n window.addEventListener('load', trackCurrentPath, { once: true })\n }\n }\n\n // -------------------------------------------------------------------------\n // track() — client-side validation + send\n // -------------------------------------------------------------------------\n\n // Dev-mode detection for warnings: warn in dev, silent in production.\n // Reuses the same local-host signal as the send-skip (INVARIANT 9).\n const isProduction = !isLocalHost\n\n // One-shot warn dedup per reason per page load (keyed by reason only)\n const warnedReasons = new Set<string>()\n\n function devWarn(name: string, reason: string): void {\n if (isProduction) return\n if (warnedReasons.has(reason)) return\n warnedReasons.add(reason)\n console.warn(`[01 analytics] dropped event ${name}: ${reason}`)\n }\n\n const EVENT_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_:-]{0,49}$/\n const RESERVED_PREFIXES = ['__', '_pv_']\n\n function validateEventName(name: string): string | null {\n if (!name || typeof name !== 'string') return 'name-empty'\n for (const prefix of RESERVED_PREFIXES) {\n if (name.startsWith(prefix)) return 'name-reserved'\n }\n if (!EVENT_NAME_RE.test(name)) return 'name-regex'\n return null\n }\n\n const PROP_KEY_RE = /^[a-zA-Z_][a-zA-Z0-9_]{0,31}$/\n\n function validateEventProps(\n props: Record<string, string | number | boolean> | undefined,\n ): string | null {\n if (props === undefined || props === null) return null\n if (typeof props !== 'object' || Array.isArray(props)) return 'props-value-type'\n const keys = Object.keys(props)\n if (keys.length > 10) return 'props-too-many-keys'\n for (const k of keys) {\n const v = props[k]\n if (!PROP_KEY_RE.test(k)) return 'props-key-regex'\n if (typeof v === 'string') {\n if (v.length > 80) return 'props-value-too-long'\n } else if (typeof v === 'number') {\n if (!isFinite(v)) return 'props-value-not-finite'\n } else if (typeof v === 'boolean') {\n // ok\n } else {\n return 'props-value-type'\n }\n }\n return null\n }\n\n // -------------------------------------------------------------------------\n // Public API\n // -------------------------------------------------------------------------\n return {\n pageview(path?: string): void {\n if (destroyed) return\n sendPageview(path ?? location.pathname)\n },\n\n track(name: string, props?: Record<string, string | number | boolean>): void {\n if (destroyed) return\n\n // INVARIANT 1: DNT/GPC (same as pageview)\n if (isDntActive()) return\n\n // INVARIANT 2: prerender skip\n const doc = document as Document & { prerendering?: boolean }\n if (doc.prerendering === true || (document.visibilityState as string) === 'prerender') return\n\n // Client-side validation\n const nameErr = validateEventName(name)\n if (nameErr) {\n devWarn(name, nameErr)\n return\n }\n\n if (props !== undefined) {\n const propsErr = validateEventProps(props)\n if (propsErr) {\n devWarn(name, propsErr)\n return\n }\n }\n\n // INVARIANT 9: skip sends on local hosts in auto mode (validation above\n // still runs so dev warnings fire)\n if (sendSuppressed) {\n devSuppressNotice()\n return\n }\n\n // Build body — no dedup for track() events\n const body = JSON.stringify({\n publishableKey: config.publishableKey,\n pathname: location.pathname,\n referrer: document.referrer || '',\n eventId: newEventId(),\n eventName: name,\n eventProps: props,\n eventTs: Date.now(),\n })\n\n sendBeaconOrFetch(body)\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n\n if (autoTrack) {\n // Restore original history methods\n history.pushState = originalPushState\n history.replaceState = originalReplaceState\n window.removeEventListener('popstate', trackCurrentPath)\n }\n\n // Null out dedup state\n lastPath = null\n lastAt = 0\n },\n }\n}\n","import type {\n ClientConfig,\n RootClientWithEvents,\n} from './core/client/types'\nimport { createClient as createClientInternal } from './core/client/client'\n\n// Public domain types\nexport type {\n Article,\n ArticleAuthor,\n ArticleCategory,\n ArticleTag,\n Image,\n Post,\n PostCategory,\n Video,\n ProductVariant,\n Order,\n Cart,\n CartItem,\n Tenant,\n Document,\n} from './payload-types'\n\n// Core browser-safe SDK\nexport function createClient(options: ClientConfig): RootClientWithEvents {\n return createClientInternal(options) as RootClientWithEvents\n}\n\nexport type {\n ApiQueryOptions,\n ClientConfig,\n ClientMetadata,\n ClientState,\n Collection,\n DebugConfig,\n DeepPartial,\n ExtractArrayType,\n PayloadFindResponse,\n PayloadMutationResponse,\n PublicCollection,\n RootCollectionClient,\n RootClient as Client,\n RootClient as ClientType,\n RootClient,\n RootClientWithEvents,\n RootReadOnlyQueryBuilder,\n RetryConfig,\n Sort,\n Where,\n} from './core/client/types'\nexport type {\n CollectionType,\n PublicProduct as Product,\n PublicProductCollection as ProductCollection,\n} from './core/collection/types'\nexport * from './core/api'\nexport { CommerceClient } from './core/commerce/commerce-client'\nexport type { CommerceClientOptions } from './core/commerce/commerce-client'\nexport {\n mergeProductDetailWithStock,\n type MergedProductDetailResult,\n type ProductDetailStockMergeStatus,\n} from './core/commerce/merge-catalog-stock'\nexport { CommunityClient } from './core/community/community-client'\nexport type {\n CommunityClientOptions,\n CommunityComment,\n CommunityCommentListSort,\n CommunityPost,\n CommunityPostCategory,\n CommunityPostListSort,\n CommunityPostTag,\n Comment,\n} from './core/community/community-client'\nexport { EventsClient } from './core/events/events-client'\nexport type {\n EventGuestCancelParams,\n EventGuestRegistration,\n EventGuestRegistrationResponse,\n EventRegistrationAnswerInput,\n EventRegistrationAttendeeInput,\n EventRegistrationPublic,\n EventRegistrationRegisterParams,\n EventRegistrationRegisterResponse,\n EventsCalendarItem,\n EventsClientOptions,\n EventsDateParam,\n EventsExternalSource,\n EventsLocation,\n EventsOccurrenceLocation,\n EventsRangeEvent,\n EventsRangeOccurrence,\n EventsRangeParams,\n EventsRangeResponse,\n EventsTaxonomyItem,\n} from './core/events/events-client'\nexport * from './core/customer'\nexport * from './core/webhook'\nexport {\n COLLECTIONS,\n INTERNAL_COLLECTIONS,\n SERVER_COLLECTIONS,\n SERVER_ONLY_COLLECTIONS,\n} from './core/collection/const'\nexport { RealtimeConnection, type RealtimeEvent, type RealtimeListener } from './core/query/realtime'\n\n// Utils\nexport * from './utils'\n\n// Analytics\nexport { createAnalytics } from './analytics'\nexport type { Analytics, AnalyticsConfig } from './analytics'\n\n// Errors\nexport {\n SDKError,\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 isSDKError,\n isNetworkError,\n isValidationError,\n isApiError,\n isConfigError,\n isTimeoutError,\n isGoneError,\n isServiceUnavailableError,\n isUsageLimitError,\n isAuthError,\n isPermissionError,\n isNotFoundError,\n isConflictError,\n isRateLimitError,\n createAuthError,\n createPermissionError,\n createNotFoundError,\n createConflictError,\n createRateLimitError,\n} from './errors'\n"],"mappings":"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","names":["method","DEFAULT_TIMEOUT","_idempotencyKey","isRecord","delay","mediaId","mediaArray","item","buildPoolById","createClient"]}
|