@ekomerc/storefront 0.3.10 → 0.4.1-nightly-20261010170026

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/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/cache.ts","../src/storage.ts","../src/account.ts","../../../shared/tracking-policy/src/policy.ts","../src/analytics-retry-queue.ts","../src/tracking-attribution.ts","../src/tracking-runtime.ts","../src/analytics.ts","../src/auth.ts","../../../shared/cart-contract/src/index.ts","../src/url.ts","../src/cart-shared.ts","../src/cart-mutation-runner.ts","../src/cart-snapshot-cache.ts","../src/cart.ts","../src/categories.ts","../src/payment-lifecycle.ts","../src/checkout.ts","../src/list-all.ts","../src/collections.ts","../src/consent.ts","../src/content.ts","../src/browser-helpers.ts","../src/debug-browser-adapter.ts","../src/graphql-client.ts","../src/gtm-browser-adapter.ts","../src/marketing.ts","../src/payments.ts","../src/products.ts","../src/shipping.ts","../src/store.ts","../src/client.ts","../src/commerce-descriptors.ts","../src/discover-site.ts"],"sourcesContent":["interface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport interface QueryCache {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttl: number): void;\n clear(): void;\n}\n\nexport function createQueryCache(): QueryCache {\n const cache = new Map<string, CacheEntry<unknown>>();\n\n return {\n get<T>(key: string): T | null {\n const entry = cache.get(key);\n if (!entry) return null;\n if (Date.now() > entry.expiresAt) {\n cache.delete(key);\n return null;\n }\n return entry.value as T;\n },\n\n set<T>(key: string, value: T, ttl: number): void {\n cache.set(key, {\n value,\n expiresAt: Date.now() + ttl,\n });\n },\n\n clear(): void {\n cache.clear();\n },\n };\n}\n","import type { StorageAdapter } from \"./types.ts\";\n\nconst SANDBOX_API_KEY_RE = /^(sfk|ssk)_sandbox_/;\n\nexport const CART_SESSION_KEY = \"ekomerc_cart_token\";\nexport const CUSTOMER_SESSION_KEY = \"ekomerc_customer_token\";\nexport const CONSENT_COOKIE_NAME = \"ekomerc_consent\";\nexport const CART_STORAGE_KEY = CART_SESSION_KEY;\nexport const CUSTOMER_STORAGE_KEY = CUSTOMER_SESSION_KEY;\nexport const CHECKOUT_LEAD_DISPATCH_PREFIX = \"ekomerc_checkout_lead_dispatched\";\n\nexport function getCheckoutLeadDispatchKey(cartToken: string): string {\n return `${CHECKOUT_LEAD_DISPATCH_PREFIX}:${cartToken}`;\n}\n\nexport function isSandboxApiKey(apiKey: string): boolean {\n return SANDBOX_API_KEY_RE.test(apiKey);\n}\n\n/** Wraps a StorageAdapter so every key is prefixed, isolating storage namespaces. */\nexport function createNamespacedAdapter(inner: StorageAdapter, prefix: string): StorageAdapter {\n return {\n get(key: string): string | null {\n return inner.get(prefix + key);\n },\n set(key: string, value: string): void {\n inner.set(prefix + key, value);\n },\n remove(key: string): void {\n inner.remove(prefix + key);\n },\n };\n}\n\n/** Returns the localStorage key for the active market slug, scoped to the API key (used before storeId is known). */\nexport function getMarketStorageKey(apiKey: string): string {\n return `ekomerc_market_${apiKey}`;\n}\n\n/** Returns the canonical localStorage key for the active market slug, scoped to the store ID. */\nexport function getMarketStorageKeyByStoreId(storeId: string): string {\n return `ekomerc_market_${storeId}`;\n}\n\n/**\n * localStorage adapter for browser environments\n */\nexport function createLocalStorageAdapter(): StorageAdapter {\n return {\n get(key: string): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n set(key: string, value: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n remove(key: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(key);\n },\n };\n}\n\n/**\n * In-memory adapter for SSR or testing\n */\nexport function createMemoryAdapter(): StorageAdapter {\n const store = new Map<string, string>();\n\n return {\n get(key: string): string | null {\n return store.get(key) ?? null;\n },\n set(key: string, value: string): void {\n store.set(key, value);\n },\n remove(key: string): void {\n store.delete(key);\n },\n };\n}\n\n/**\n * Detect environment and create appropriate default adapter\n */\nexport function createDefaultAdapter(): StorageAdapter {\n if (typeof window !== \"undefined\" && typeof localStorage !== \"undefined\") {\n return createLocalStorageAdapter();\n }\n return createMemoryAdapter();\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { AuthError, ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_SESSION_KEY } from \"./storage.ts\";\nimport type {\n Customer,\n CustomerAddress,\n CustomerAddressInput,\n CustomerAddressUpdateInput,\n CustomerOrder,\n CustomerUpdateInput,\n Money,\n PaginatedResult,\n StorageAdapter,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: Money;\n totalPrice: Money;\n}\n\ninterface OrderNodeData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n subtotal: Money;\n total: Money;\n note: string | null;\n items: OrderItemData[];\n createdAt: string;\n}\n\ninterface AddressData {\n id: string;\n label: string | null;\n firstName: string | null;\n lastName: string | null;\n addressLine1: string;\n addressLine2: string | null;\n city: string;\n zip: string | null;\n phone: string | null;\n isDefault: boolean;\n createdAt: string;\n}\n\ninterface CustomerData {\n id: string;\n name: string | null;\n email: string;\n emailVerified: boolean;\n}\n\ninterface CustomerOrdersResponse {\n customerOrders: {\n edges: Array<{ node: OrderNodeData; cursor: string }>;\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n };\n}\n\ninterface CustomerAddressesResponse {\n customerAddresses: AddressData[];\n}\n\ninterface CustomerAddressCreateResponse {\n customerAddressCreate: {\n address: AddressData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerAddressUpdateResponse {\n customerAddressUpdate: {\n address: AddressData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerAddressDeleteResponse {\n customerAddressDelete: {\n deletedAddressId: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerUpdateResponse {\n customerUpdate: {\n customer: CustomerData | null;\n userErrors: UserError[];\n };\n}\n\nconst ORDER_ITEM_FRAGMENT = `\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice { amount currency }\n totalPrice { amount currency }\n`;\n\nconst CUSTOMER_ORDERS_QUERY = `\nquery CustomerOrders($first: Int, $after: String, $last: Int, $before: String) {\n customerOrders(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n orderNumber\n status\n customerEmail\n customerPhone\n subtotal { amount currency }\n total { amount currency }\n note\n items { ${ORDER_ITEM_FRAGMENT} }\n createdAt\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst ADDRESS_FRAGMENT = `\n id\n label\n firstName\n lastName\n addressLine1\n addressLine2\n city\n zip\n phone\n isDefault\n createdAt\n`;\n\nconst CUSTOMER_ADDRESSES_QUERY = `\nquery CustomerAddresses {\n customerAddresses { ${ADDRESS_FRAGMENT} }\n}\n`;\n\nconst CUSTOMER_ADDRESS_CREATE_MUTATION = `\nmutation CustomerAddressCreate($input: CustomerAddressCreateInput!) {\n customerAddressCreate(input: $input) {\n address { ${ADDRESS_FRAGMENT} }\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_ADDRESS_UPDATE_MUTATION = `\nmutation CustomerAddressUpdate($addressId: ID!, $input: CustomerAddressUpdateInput!) {\n customerAddressUpdate(addressId: $addressId, input: $input) {\n address { ${ADDRESS_FRAGMENT} }\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_ADDRESS_DELETE_MUTATION = `\nmutation CustomerAddressDelete($addressId: ID!) {\n customerAddressDelete(addressId: $addressId) {\n deletedAddressId\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_UPDATE_MUTATION = `\nmutation CustomerUpdate($input: CustomerUpdateInput!) {\n customerUpdate(input: $input) {\n customer {\n id\n name\n email\n emailVerified\n }\n userErrors { field message code }\n }\n}\n`;\n\nfunction mapOrderNode(data: OrderNodeData): CustomerOrder {\n return {\n id: data.id,\n orderNumber: data.orderNumber,\n status: data.status,\n email: data.customerEmail,\n phone: data.customerPhone,\n subtotal: data.subtotal,\n total: data.total,\n note: data.note,\n items: data.items.map((item) => ({\n id: item.id,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n sku: item.sku,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.totalPrice,\n })),\n createdAt: data.createdAt,\n };\n}\n\nfunction mapAddressData(data: AddressData): CustomerAddress {\n return {\n id: data.id,\n label: data.label,\n firstName: data.firstName,\n lastName: data.lastName,\n addressLine1: data.addressLine1,\n addressLine2: data.addressLine2,\n city: data.city,\n zip: data.zip,\n phone: data.phone,\n isDefault: data.isDefault,\n createdAt: data.createdAt,\n };\n}\n\nfunction mapUserErrors(userErrors: UserError[]): ValidationError | null {\n if (userErrors.length === 0) return null;\n const messages = userErrors.map((e) => e.message).join(\"; \");\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\n\nexport interface AccountOperations {\n /**\n * Fetch paginated orders for the authenticated customer.\n *\n * @param args - Forward or backward pagination options.\n * @returns Paginated customer orders.\n */\n orders(args?: {\n first?: number;\n after?: string;\n last?: number;\n before?: string;\n }): Promise<Result<PaginatedResult<CustomerOrder>, StorefrontError>>;\n /**\n * Fetch saved addresses for the authenticated customer.\n *\n * @returns Customer addresses.\n */\n addresses(): Promise<Result<CustomerAddress[], StorefrontError>>;\n /**\n * Create a saved customer address.\n *\n * @param input - Address fields to create.\n * @returns The created address.\n */\n createAddress(input: CustomerAddressInput): Promise<Result<CustomerAddress, StorefrontError>>;\n /**\n * Update a saved customer address.\n *\n * @param addressId - Address identifier to update.\n * @param input - Address fields to change.\n * @returns The updated address.\n */\n updateAddress(\n addressId: string,\n input: CustomerAddressUpdateInput,\n ): Promise<Result<CustomerAddress, StorefrontError>>;\n /**\n * Delete a saved customer address.\n *\n * @param addressId - Address identifier to delete.\n * @returns The deleted address identifier.\n */\n deleteAddress(addressId: string): Promise<Result<string, StorefrontError>>;\n /**\n * Update the authenticated customer's profile fields.\n *\n * @param input - Customer fields to update.\n * @returns The updated customer profile.\n */\n update(input: CustomerUpdateInput): Promise<Result<Customer, StorefrontError>>;\n}\n\nexport function createAccountOperations(client: StorefrontClientContext, storage: StorageAdapter): AccountOperations {\n function requireAuth(): Result<void, AuthError> {\n if (!storage.get(CUSTOMER_SESSION_KEY)) {\n return err(new AuthError(\"Not authenticated. Call auth.login() or auth.register() first.\"));\n }\n return ok(undefined);\n }\n\n return {\n async orders(args) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const variables: Record<string, unknown> = {};\n if (args?.first !== undefined) variables.first = args.first;\n if (args?.after !== undefined) variables.after = args.after;\n if (args?.last !== undefined) variables.last = args.last;\n if (args?.before !== undefined) variables.before = args.before;\n if (!variables.first && !variables.last) variables.first = 20;\n\n const result = await client.query<CustomerOrdersResponse>(\n { query: CUSTOMER_ORDERS_QUERY, variables },\n { cache: false },\n );\n\n if (result.isErr()) return err(result.error);\n\n const { edges, pageInfo } = result.value.customerOrders;\n return ok({\n items: edges.map((edge) => mapOrderNode(edge.node)),\n pageInfo,\n });\n },\n\n async addresses() {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.query<CustomerAddressesResponse>(\n { query: CUSTOMER_ADDRESSES_QUERY },\n { cache: false },\n );\n\n if (result.isErr()) return err(result.error);\n\n return ok(result.value.customerAddresses.map(mapAddressData));\n },\n\n async createAddress(input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressCreateResponse>({\n query: CUSTOMER_ADDRESS_CREATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.address) {\n return err(new ValidationError(\"Failed to create address\", []));\n }\n\n return ok(mapAddressData(payload.address));\n },\n\n async updateAddress(addressId, input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressUpdateResponse>({\n query: CUSTOMER_ADDRESS_UPDATE_MUTATION,\n variables: { addressId, input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressUpdate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.address) {\n return err(new ValidationError(\"Failed to update address\", []));\n }\n\n return ok(mapAddressData(payload.address));\n },\n\n async deleteAddress(addressId) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressDeleteResponse>({\n query: CUSTOMER_ADDRESS_DELETE_MUTATION,\n variables: { addressId },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressDelete;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.deletedAddressId) {\n return err(new ValidationError(\"Failed to delete address\", []));\n }\n\n return ok(payload.deletedAddressId);\n },\n\n async update(input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerUpdateResponse>({\n query: CUSTOMER_UPDATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerUpdate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Failed to update profile\", []));\n }\n\n return ok({\n id: payload.customer.id,\n name: payload.customer.name,\n email: payload.customer.email,\n emailVerified: payload.customer.emailVerified,\n });\n },\n };\n}\n","export const TRACKING_POLICY_EVENT_TYPES = [\n \"analytics.page_view\",\n \"analytics.product_view\",\n \"analytics.collection_view\",\n \"analytics.search_performed\",\n \"analytics.lead_generated\",\n \"analytics.select_item\",\n \"analytics.add_to_cart\",\n \"analytics.remove_from_cart\",\n \"analytics.view_cart\",\n \"analytics.checkout_started\",\n \"analytics.checkout_step_completed\",\n \"analytics.checkout_completed\",\n \"analytics.custom\",\n] as const;\nexport type TrackingPolicyEventType = (typeof TRACKING_POLICY_EVENT_TYPES)[number];\n\nexport const TRACKING_PROVIDERS = [\"gtm\", \"meta\", \"tiktok\"] as const;\nexport type TrackingProvider = (typeof TRACKING_PROVIDERS)[number];\n\nexport const GTM_STANDARD_EVENTS = [\n \"page_view\",\n \"view_item\",\n \"view_item_list\",\n \"search\",\n \"generate_lead\",\n \"select_item\",\n \"add_to_cart\",\n \"remove_from_cart\",\n \"view_cart\",\n \"begin_checkout\",\n \"add_shipping_info\",\n \"add_payment_info\",\n \"purchase\",\n] as const;\nexport type GtmStandardEventName = (typeof GTM_STANDARD_EVENTS)[number];\n\nexport const META_STANDARD_EVENTS = [\n \"PageView\",\n \"ViewContent\",\n \"Search\",\n \"Lead\",\n \"AddToCart\",\n \"InitiateCheckout\",\n \"Purchase\",\n] as const;\nexport type MetaStandardEventName = (typeof META_STANDARD_EVENTS)[number];\n\nexport const TIKTOK_STANDARD_EVENTS = [\n \"PageView\",\n \"ViewContent\",\n \"Search\",\n \"AddToCart\",\n \"InitiateCheckout\",\n \"CompletePayment\",\n] as const;\nexport type TiktokStandardEventName = (typeof TIKTOK_STANDARD_EVENTS)[number];\n\nexport const GTM_EVENT_MAP = {\n \"analytics.page_view\": \"page_view\",\n \"analytics.product_view\": \"view_item\",\n \"analytics.collection_view\": \"view_item_list\",\n \"analytics.search_performed\": \"search\",\n \"analytics.lead_generated\": \"generate_lead\",\n \"analytics.select_item\": \"select_item\",\n \"analytics.add_to_cart\": \"add_to_cart\",\n \"analytics.remove_from_cart\": \"remove_from_cart\",\n \"analytics.view_cart\": \"view_cart\",\n \"analytics.checkout_started\": \"begin_checkout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"purchase\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, GtmStandardEventName | null>;\n\nexport const META_EVENT_MAP = {\n \"analytics.page_view\": \"PageView\",\n \"analytics.product_view\": \"ViewContent\",\n \"analytics.collection_view\": \"ViewContent\",\n \"analytics.search_performed\": \"Search\",\n \"analytics.lead_generated\": \"Lead\",\n \"analytics.select_item\": null,\n \"analytics.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_cart\": null,\n \"analytics.view_cart\": null,\n \"analytics.checkout_started\": \"InitiateCheckout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"Purchase\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, MetaStandardEventName | null>;\n\nexport const TIKTOK_EVENT_MAP = {\n \"analytics.page_view\": \"PageView\",\n \"analytics.product_view\": \"ViewContent\",\n \"analytics.collection_view\": \"ViewContent\",\n \"analytics.search_performed\": \"Search\",\n \"analytics.lead_generated\": null,\n \"analytics.select_item\": null,\n \"analytics.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_cart\": null,\n \"analytics.view_cart\": null,\n \"analytics.checkout_started\": \"InitiateCheckout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"CompletePayment\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, TiktokStandardEventName | null>;\n\nexport type TrackingProviderEventNameMap = {\n gtm: GtmStandardEventName;\n meta: MetaStandardEventName;\n tiktok: TiktokStandardEventName;\n};\n\nexport type TrackingProviderEventMap = {\n [Provider in TrackingProvider]: Record<TrackingPolicyEventType, TrackingProviderEventNameMap[Provider] | null>;\n};\n\nexport const TRACKING_PROVIDER_EVENT_MAPS = {\n gtm: GTM_EVENT_MAP,\n meta: META_EVENT_MAP,\n tiktok: TIKTOK_EVENT_MAP,\n} as const satisfies TrackingProviderEventMap;\n\nexport interface TrackingProviderSupportRule {\n supportsBrowserDispatch: boolean;\n supportsServerDispatch: boolean;\n requiresConsentBridge: boolean;\n supportedEventTypes: TrackingPolicyEventType[];\n}\n\nfunction collectSupportedEventTypes<Provider extends TrackingProvider>(\n provider: Provider,\n): TrackingProviderSupportRule[\"supportedEventTypes\"] {\n const eventMap = TRACKING_PROVIDER_EVENT_MAPS[provider];\n return TRACKING_POLICY_EVENT_TYPES.filter((eventType) => eventMap[eventType] !== null);\n}\n\nexport const TRACKING_PROVIDER_SUPPORT_RULES = {\n gtm: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: false,\n requiresConsentBridge: true,\n supportedEventTypes: collectSupportedEventTypes(\"gtm\"),\n },\n meta: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: true,\n requiresConsentBridge: false,\n supportedEventTypes: collectSupportedEventTypes(\"meta\"),\n },\n tiktok: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: true,\n requiresConsentBridge: false,\n supportedEventTypes: collectSupportedEventTypes(\"tiktok\"),\n },\n} as const satisfies Record<TrackingProvider, TrackingProviderSupportRule>;\n\nexport interface TrackingProviderDedupeConvention {\n canonicalEventIdField: \"eventId\";\n providerEventIdField: \"event_id\";\n confirmedPurchaseSource: \"order.id\";\n}\n\nconst SHARED_DEDUPE_CONVENTION: TrackingProviderDedupeConvention = {\n canonicalEventIdField: \"eventId\",\n providerEventIdField: \"event_id\",\n confirmedPurchaseSource: \"order.id\",\n};\n\nexport const TRACKING_PROVIDER_DEDUPE_FIELDS = {\n gtm: SHARED_DEDUPE_CONVENTION,\n meta: SHARED_DEDUPE_CONVENTION,\n tiktok: SHARED_DEDUPE_CONVENTION,\n} as const satisfies Record<TrackingProvider, TrackingProviderDedupeConvention>;\n\nexport function getTrackingProviderEventName(\n provider: \"gtm\",\n eventType: TrackingPolicyEventType,\n): GtmStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: \"meta\",\n eventType: TrackingPolicyEventType,\n): MetaStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: \"tiktok\",\n eventType: TrackingPolicyEventType,\n): TiktokStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: TrackingProvider,\n eventType: TrackingPolicyEventType,\n): string | null {\n return TRACKING_PROVIDER_EVENT_MAPS[provider][eventType];\n}\n\nexport function providerSupportsTrackingEvent(provider: TrackingProvider, eventType: TrackingPolicyEventType): boolean {\n return TRACKING_PROVIDER_EVENT_MAPS[provider][eventType] !== null;\n}\n\nexport function getTrackingProviderSupportRule(provider: TrackingProvider): TrackingProviderSupportRule {\n return TRACKING_PROVIDER_SUPPORT_RULES[provider];\n}\n\nexport function getTrackingProviderDedupeConvention(provider: TrackingProvider): TrackingProviderDedupeConvention {\n return TRACKING_PROVIDER_DEDUPE_FIELDS[provider];\n}\n\nexport const CONSENT_CATEGORIES = [\"analytics_storage\", \"ad_storage\", \"ad_user_data\", \"ad_personalization\"] as const;\nexport type ConsentCategory = (typeof CONSENT_CATEGORIES)[number];\n\nexport const TRACKING_PROVIDER_REQUIRED_CONSENT = {\n gtm: [\"analytics_storage\"],\n meta: [\"ad_storage\", \"ad_user_data\"],\n tiktok: [\"ad_storage\", \"ad_user_data\"],\n} as const satisfies Record<TrackingProvider, readonly ConsentCategory[]>;\n\nexport function getTrackingProviderRequiredConsent(provider: TrackingProvider): readonly ConsentCategory[] {\n return TRACKING_PROVIDER_REQUIRED_CONSENT[provider];\n}\n","import type { AnalyticsBrowserEvent, AnalyticsDiagnostic } from \"./tracking-runtime.ts\";\nimport type { StorageAdapter } from \"./types.ts\";\n\nconst ANALYTICS_QUEUE_KEY_PREFIX = \"ekomerc_aq_\";\nconst ANALYTICS_QUEUE_KEY_API_PREFIX_LENGTH = 12;\nconst ANALYTICS_QUEUE_MAX_EVENTS = 100;\nconst ANALYTICS_QUEUE_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport interface AnalyticsRetryQueueEntry {\n event: AnalyticsBrowserEvent;\n queuedAt: number;\n notBefore?: number;\n}\n\nexport interface AnalyticsRetryQueue {\n read(nowMs?: number): AnalyticsRetryQueueEntry[];\n enqueue(entry: AnalyticsRetryQueueEntry): AnalyticsRetryQueueEntry[];\n dequeue(count: number, nowMs?: number): AnalyticsRetryQueueEntry[];\n replace(entries: AnalyticsRetryQueueEntry[]): void;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isAnalyticsRetryQueueEntry(value: unknown): value is AnalyticsRetryQueueEntry {\n if (!isPlainObject(value)) {\n return false;\n }\n\n const event = value.event;\n return (\n isPlainObject(event) &&\n typeof event.eventId === \"string\" &&\n typeof value.queuedAt === \"number\" &&\n (value.notBefore === undefined || typeof value.notBefore === \"number\")\n );\n}\n\nexport function getAnalyticsRetryQueueKey(apiKey: string): string {\n return `${ANALYTICS_QUEUE_KEY_PREFIX}${apiKey.slice(0, ANALYTICS_QUEUE_KEY_API_PREFIX_LENGTH)}`;\n}\n\nexport function createAnalyticsRetryQueue(\n storage: StorageAdapter,\n apiKey: string,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n): AnalyticsRetryQueue {\n const queueKey = getAnalyticsRetryQueueKey(apiKey);\n\n function persist(entries: AnalyticsRetryQueueEntry[]): void {\n try {\n if (entries.length === 0) {\n storage.remove(queueKey);\n return;\n }\n\n storage.set(queueKey, JSON.stringify(entries));\n } catch {\n // Queue persistence is best-effort and must never affect callers.\n }\n }\n\n function read(nowMs = Date.now()): AnalyticsRetryQueueEntry[] {\n let raw: string | null;\n\n try {\n raw = storage.get(queueKey);\n } catch {\n return [];\n }\n\n if (!raw) {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n const entries = parsed.filter(isAnalyticsRetryQueueEntry);\n const activeEntries = entries.filter((entry) => {\n const isExpired = nowMs - entry.queuedAt >= ANALYTICS_QUEUE_TTL_MS;\n if (isExpired) {\n emitDiagnostic({\n target: \"queue\",\n status: \"evicted_expired\",\n eventId: entry.event.eventId,\n });\n }\n\n return !isExpired;\n });\n\n if (activeEntries.length !== entries.length) {\n persist(activeEntries);\n }\n\n return activeEntries;\n }\n\n function enqueue(entry: AnalyticsRetryQueueEntry): AnalyticsRetryQueueEntry[] {\n const entries = read(entry.queuedAt);\n const nextEntries = [...entries];\n\n while (nextEntries.length >= ANALYTICS_QUEUE_MAX_EVENTS) {\n const evicted = nextEntries.shift();\n if (evicted) {\n emitDiagnostic({\n target: \"queue\",\n status: \"evicted_full\",\n event: evicted.event,\n });\n }\n }\n\n nextEntries.push(entry);\n persist(nextEntries);\n emitDiagnostic({\n target: \"queue\",\n status: \"enqueued\",\n event: entry.event,\n });\n return nextEntries;\n }\n\n function dequeue(count: number, nowMs = Date.now()): AnalyticsRetryQueueEntry[] {\n const entries = read(nowMs);\n const dequeueCount = Math.max(0, Math.floor(count));\n const removedEntries = entries.slice(0, dequeueCount);\n persist(entries.slice(removedEntries.length));\n emitDiagnostic({\n target: \"queue\",\n status: \"flushed\",\n count: removedEntries.length,\n });\n return removedEntries;\n }\n\n function replace(entries: AnalyticsRetryQueueEntry[]): void {\n persist(entries);\n }\n\n return {\n read,\n enqueue,\n dequeue,\n replace,\n };\n}\n","const TRACKING_SCHEMA_VERSION = 1 as const;\nconst TRACKING_ATTRIBUTION_STORAGE_KEY = \"ekomerc_tracking_attribution\";\nexport const DEFAULT_TRACKING_ATTRIBUTION_TTL_MS = 30 * 24 * 60 * 60 * 1000;\nexport const TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n \"gclid\",\n \"gbraid\",\n \"wbraid\",\n \"ttclid\",\n \"fbclid\",\n] as const;\n\nexport interface TrackingAttributionSnapshot {\n schemaVersion: 1;\n capturedAt: string;\n utm: {\n schemaVersion: 1;\n source: string | null;\n medium: string | null;\n campaign: string | null;\n term: string | null;\n content: string | null;\n };\n clickIds: {\n schemaVersion: 1;\n capturedAt: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n ttclid: string | null;\n fbclid: string | null;\n };\n}\n\nexport interface TrackingAttributionOptions {\n ttlMs?: number;\n}\n\nfunction hasBrowserContext(): boolean {\n return typeof window !== \"undefined\";\n}\n\nfunction hasTrackingAttributionParams(search: string): boolean {\n const params = new URLSearchParams(search);\n return TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS.some((key) => {\n const value = params.get(key);\n return value !== null && value.trim().length > 0;\n });\n}\n\nfunction normalizeParam(value: string | null): string | null {\n if (value === null) return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction hasAttributionValue(snapshot: TrackingAttributionSnapshot): boolean {\n return [\n snapshot.utm.source,\n snapshot.utm.medium,\n snapshot.utm.campaign,\n snapshot.utm.term,\n snapshot.utm.content,\n snapshot.clickIds.gclid,\n snapshot.clickIds.gbraid,\n snapshot.clickIds.wbraid,\n snapshot.clickIds.ttclid,\n snapshot.clickIds.fbclid,\n ].some((value) => value !== null);\n}\n\nfunction resolveTrackingAttributionTtlMs(options?: TrackingAttributionOptions): number {\n const ttlMs = options?.ttlMs;\n if (typeof ttlMs !== \"number\" || !Number.isFinite(ttlMs) || ttlMs < 0) {\n return DEFAULT_TRACKING_ATTRIBUTION_TTL_MS;\n }\n\n return ttlMs;\n}\n\nfunction isSnapshotExpired(snapshot: TrackingAttributionSnapshot, ttlMs: number): boolean {\n const capturedAtMs = Date.parse(snapshot.capturedAt);\n if (Number.isNaN(capturedAtMs)) {\n return true;\n }\n\n return Date.now() - capturedAtMs > ttlMs;\n}\n\nfunction parseStoredSnapshot(raw: string | null): TrackingAttributionSnapshot | null {\n if (!raw) return null;\n\n try {\n const parsed = JSON.parse(raw) as Partial<TrackingAttributionSnapshot>;\n if (parsed.schemaVersion !== TRACKING_SCHEMA_VERSION || typeof parsed.capturedAt !== \"string\") {\n return null;\n }\n\n const utm = parsed.utm;\n const clickIds = parsed.clickIds;\n if (!utm || !clickIds) return null;\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: parsed.capturedAt,\n utm: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: typeof utm.source === \"string\" ? utm.source : null,\n medium: typeof utm.medium === \"string\" ? utm.medium : null,\n campaign: typeof utm.campaign === \"string\" ? utm.campaign : null,\n term: typeof utm.term === \"string\" ? utm.term : null,\n content: typeof utm.content === \"string\" ? utm.content : null,\n },\n clickIds: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: typeof clickIds.capturedAt === \"string\" ? clickIds.capturedAt : null,\n gclid: typeof clickIds.gclid === \"string\" ? clickIds.gclid : null,\n gbraid: typeof clickIds.gbraid === \"string\" ? clickIds.gbraid : null,\n wbraid: typeof clickIds.wbraid === \"string\" ? clickIds.wbraid : null,\n ttclid: typeof clickIds.ttclid === \"string\" ? clickIds.ttclid : null,\n fbclid: typeof clickIds.fbclid === \"string\" ? clickIds.fbclid : null,\n },\n };\n } catch {\n return null;\n }\n}\n\nfunction removeStoredSnapshot(): void {\n if (!hasBrowserContext()) return;\n\n try {\n window.localStorage.removeItem(TRACKING_ATTRIBUTION_STORAGE_KEY);\n } catch {\n // ignore storage failures\n }\n}\n\n/**\n * Reads the stored tracking attribution snapshot from localStorage.\n * Expired snapshots are removed from localStorage during the read — this is a destructive operation despite the read-only name.\n */\nfunction readStoredSnapshot(options?: TrackingAttributionOptions): TrackingAttributionSnapshot | null {\n if (!hasBrowserContext()) return null;\n\n try {\n const snapshot = parseStoredSnapshot(window.localStorage.getItem(TRACKING_ATTRIBUTION_STORAGE_KEY));\n if (!snapshot) {\n return null;\n }\n\n if (isSnapshotExpired(snapshot, resolveTrackingAttributionTtlMs(options))) {\n removeStoredSnapshot();\n return null;\n }\n\n return snapshot;\n } catch {\n return null;\n }\n}\n\nfunction writeStoredSnapshot(snapshot: TrackingAttributionSnapshot): void {\n if (!hasBrowserContext()) return;\n\n try {\n window.localStorage.setItem(TRACKING_ATTRIBUTION_STORAGE_KEY, JSON.stringify(snapshot));\n } catch {\n // ignore storage failures\n }\n}\n\nfunction buildSnapshotFromSearch(search: string): TrackingAttributionSnapshot {\n const params = new URLSearchParams(search);\n const capturedAt = new Date().toISOString();\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt,\n utm: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: normalizeParam(params.get(\"utm_source\")),\n medium: normalizeParam(params.get(\"utm_medium\")),\n campaign: normalizeParam(params.get(\"utm_campaign\")),\n term: normalizeParam(params.get(\"utm_term\")),\n content: normalizeParam(params.get(\"utm_content\")),\n },\n clickIds: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt,\n gclid: normalizeParam(params.get(\"gclid\")),\n gbraid: normalizeParam(params.get(\"gbraid\")),\n wbraid: normalizeParam(params.get(\"wbraid\")),\n ttclid: normalizeParam(params.get(\"ttclid\")),\n fbclid: normalizeParam(params.get(\"fbclid\")),\n },\n };\n}\n\nexport function captureLandingTrackingAttribution(\n options?: TrackingAttributionOptions,\n): TrackingAttributionSnapshot | null {\n if (!hasBrowserContext()) return null;\n\n const snapshot = buildSnapshotFromSearch(window.location.search);\n if (hasAttributionValue(snapshot)) {\n writeStoredSnapshot(snapshot);\n return snapshot;\n }\n\n return readStoredSnapshot(options);\n}\n\n/**\n * Returns the current tracking attribution snapshot, or null if none exists or it has expired.\n * Note: expired snapshots are deleted from localStorage as a side effect of this call.\n */\nexport function getTrackingAttributionSnapshot(\n options?: TrackingAttributionOptions,\n): TrackingAttributionSnapshot | null {\n return readStoredSnapshot(options);\n}\n\nexport function stripLandingTrackingAttributionFromUrl(): boolean {\n if (!hasBrowserContext()) return false;\n if (!hasTrackingAttributionParams(window.location.search)) return false;\n if (typeof window.history?.replaceState !== \"function\") return false;\n\n const params = new URLSearchParams(window.location.search);\n for (const key of TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS) {\n params.delete(key);\n }\n\n const search = params.toString();\n const hash = window.location.hash ?? \"\";\n const nextUrl = `${window.location.pathname}${search ? `?${search}` : \"\"}${hash}`;\n window.history.replaceState(window.history.state, \"\", nextUrl);\n return true;\n}\n","import {\n providerSupportsTrackingEvent,\n type TrackingPolicyEventType,\n type TrackingProvider,\n} from \"@ekomerc/tracking-policy\";\n\nexport const TRACKING_SCHEMA_VERSION = 1 as const;\nexport const INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY = \"__ga4CampaignOverrideActive\" as const;\n\n/**\n * Consent states emitted with browser-side analytics events.\n */\nexport type AnalyticsConsentState = \"granted\" | \"denied\" | \"unknown\";\n\n/**\n * UTM parameters captured for a visitor session.\n */\nexport interface AnalyticsUtm {\n schemaVersion: 1;\n source: string | null;\n medium: string | null;\n campaign: string | null;\n term: string | null;\n content: string | null;\n}\n\n/**\n * Click identifiers captured from ad platforms and passed through analytics events.\n */\nexport interface AnalyticsClickIds {\n schemaVersion: 1;\n capturedAt: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n ttclid: string | null;\n fbclid: string | null;\n}\n\n/**\n * Request context attached to each browser analytics event.\n */\nexport interface AnalyticsEventContextPayload {\n schemaVersion: 1;\n path: string;\n}\n\n/**\n * Primitive JSON values supported inside analytics properties.\n */\nexport type AnalyticsJsonPrimitive = string | number | boolean | null;\n\n/**\n * Recursive JSON value shape supported by analytics event properties.\n */\nexport type AnalyticsJsonValue = AnalyticsJsonPrimitive | AnalyticsJsonValue[] | { [key: string]: AnalyticsJsonValue };\n\n/**\n * Arbitrary analytics event properties sent to ingest and browser adapters.\n */\nexport interface AnalyticsProperties {\n [key: string]: AnalyticsJsonValue;\n}\n\n/**\n * Best-effort browser device fingerprint attached to an analytics event.\n */\nexport interface AnalyticsBrowserEventDevice {\n deviceType: string;\n deviceOs: string | null;\n deviceBrowser: string | null;\n}\n\n/**\n * Canonical browser analytics event shape used by the storefront SDK.\n */\nexport interface AnalyticsBrowserEvent {\n schemaVersion: 1;\n eventId: string;\n eventType: TrackingPolicyEventType;\n occurredAt: string;\n sessionId: string;\n visitorId: string;\n customerId: string | null;\n consentState: AnalyticsConsentState;\n context: AnalyticsEventContextPayload;\n referrer: string | null;\n utm: AnalyticsUtm;\n clickIds: AnalyticsClickIds;\n device: AnalyticsBrowserEventDevice;\n properties: AnalyticsProperties;\n}\n\n/**\n * Consent state payload passed to browser adapters and diagnostics.\n */\nexport interface AnalyticsConsentUpdate {\n consentState: AnalyticsConsentState;\n}\n\n/**\n * Input provided to a browser adapter when dispatching an analytics event.\n */\nexport interface AnalyticsAdapterDispatchInput {\n event: AnalyticsBrowserEvent;\n consent: AnalyticsConsentUpdate;\n}\n\n/**\n * Reasons a browser adapter may skip dispatch instead of throwing.\n */\nexport type AnalyticsAdapterSkipReason = \"unsupported_event\" | \"consent_blocked\" | \"runtime_unavailable\";\n\n/**\n * Structured result returned when a browser adapter intentionally skips dispatch.\n */\nexport interface AnalyticsAdapterOperationSkippedResult {\n status: \"skipped\";\n reason: \"runtime_unavailable\";\n}\n\n/**\n * Result returned by browser adapter dispatch and consent-update hooks.\n */\nexport type AnalyticsAdapterOperationResult =\n | undefined\n | { status: \"success\" }\n | AnalyticsAdapterOperationSkippedResult;\n\n/**\n * Browser-side analytics adapter contract for GTM, Meta, TikTok, or custom integrations.\n */\nexport interface AnalyticsBrowserAdapter {\n provider: TrackingProvider;\n dispatch(\n input: AnalyticsAdapterDispatchInput,\n ): AnalyticsAdapterOperationResult | Promise<AnalyticsAdapterOperationResult>;\n updateConsent?(\n input: AnalyticsConsentUpdate,\n ): AnalyticsAdapterOperationResult | Promise<AnalyticsAdapterOperationResult>;\n}\n\n/**\n * Diagnostic events emitted by the analytics runtime for ingest and adapter activity.\n */\nexport type AnalyticsDiagnostic =\n | {\n target: \"ingest\";\n status: \"success\";\n event: AnalyticsBrowserEvent;\n response: {\n acceptedCount: number;\n duplicateCount: number;\n rejectedCount: number;\n };\n }\n | {\n target: \"ingest\";\n status: \"error\";\n event: AnalyticsBrowserEvent;\n error: Error;\n }\n | {\n target: \"ingest\";\n status: \"accepted_unknown\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"enqueued\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"flushed\";\n count: number;\n }\n | {\n target: \"queue\";\n status: \"evicted_full\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"evicted_expired\";\n eventId: string;\n }\n | {\n target: \"adapter\";\n status: \"success\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"adapter\";\n status: \"skipped\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n reason: AnalyticsAdapterSkipReason;\n }\n | {\n target: \"adapter\";\n status: \"error\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n error: Error;\n }\n | {\n target: \"consent_bridge\";\n status: \"success\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n }\n | {\n target: \"consent_bridge\";\n status: \"skipped\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n reason: \"runtime_unavailable\";\n }\n | {\n target: \"consent_bridge\";\n status: \"error\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n error: Error;\n }\n | {\n target: \"consent\";\n status: \"error\";\n error: Error;\n };\n\n/**\n * Optional browser analytics runtime hooks passed to `createStorefrontClient()`.\n */\nexport interface StorefrontTrackingRuntimeConfig {\n resolveConsentState?: () => AnalyticsConsentState | Promise<AnalyticsConsentState>;\n adapters?: AnalyticsBrowserAdapter[];\n onDiagnostic?: (diagnostic: AnalyticsDiagnostic) => void;\n}\n\n/**\n * Returns whether the current consent state allows browser-side event dispatch.\n * Unknown consent always blocks — events should be buffered by the consent manager.\n */\nexport function shouldDispatchForTrackingConsent(consentState: AnalyticsConsentState): boolean {\n return consentState === \"granted\";\n}\n\n/**\n * Returns whether a provider can receive the requested event under the current consent state.\n */\nexport function shouldDispatchBrowserAdapter(\n provider: TrackingProvider,\n eventType: TrackingPolicyEventType,\n consentState: AnalyticsConsentState,\n): { allowed: true } | { allowed: false; reason: \"unsupported_event\" | \"consent_blocked\" } {\n if (!providerSupportsTrackingEvent(provider, eventType)) {\n return { allowed: false, reason: \"unsupported_event\" };\n }\n\n if (!shouldDispatchForTrackingConsent(consentState)) {\n return { allowed: false, reason: \"consent_blocked\" };\n }\n\n return { allowed: true };\n}\n","import { TRACKING_PROVIDERS, type TrackingPolicyEventType } from \"@ekomerc/tracking-policy\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport {\n type AnalyticsRetryQueue,\n type AnalyticsRetryQueueEntry,\n createAnalyticsRetryQueue,\n} from \"./analytics-retry-queue.ts\";\nimport type { ConsentManager, ConsentOperations } from \"./consent.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NetworkError } from \"./errors.ts\";\nimport {\n captureLandingTrackingAttribution,\n getTrackingAttributionSnapshot,\n stripLandingTrackingAttributionFromUrl,\n} from \"./tracking-attribution.ts\";\nimport {\n type AnalyticsBrowserAdapter,\n type AnalyticsBrowserEvent,\n type AnalyticsClickIds,\n type AnalyticsConsentState,\n type AnalyticsConsentUpdate,\n type AnalyticsDiagnostic,\n type AnalyticsProperties,\n type AnalyticsUtm,\n INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY,\n shouldDispatchBrowserAdapter,\n TRACKING_SCHEMA_VERSION,\n} from \"./tracking-runtime.ts\";\nimport type {\n ResolvedStorefrontAnalyticsConfig,\n StorageAdapter,\n StorefrontAnalyticsInitConfig,\n StorefrontClientContext,\n} from \"./types.ts\";\n\nexport {\n type AnalyticsRetryQueue,\n type AnalyticsRetryQueueEntry,\n createAnalyticsRetryQueue,\n getAnalyticsRetryQueueKey,\n} from \"./analytics-retry-queue.ts\";\n\nexport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsAdapterOperationSkippedResult,\n AnalyticsAdapterSkipReason,\n AnalyticsBrowserAdapter,\n AnalyticsBrowserEvent,\n AnalyticsBrowserEventDevice,\n AnalyticsClickIds,\n AnalyticsConsentState,\n AnalyticsConsentUpdate,\n AnalyticsDiagnostic,\n AnalyticsEventContextPayload,\n AnalyticsJsonPrimitive,\n AnalyticsJsonValue,\n AnalyticsProperties,\n AnalyticsUtm,\n StorefrontTrackingRuntimeConfig,\n} from \"./tracking-runtime.ts\";\n\nexport interface AnalyticsInitOptions {\n stripUrl?: boolean;\n}\n\nconst ANALYTICS_PATH = \"/analytics/ingest\";\nconst VISITOR_COOKIE_NAME = \"ekomerc_vid\";\nconst SESSION_STORAGE_KEY = \"ekomerc_sid\";\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\nconst KEEPALIVE_MAX_BODY_BYTES = 60 * 1024;\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst LANDING_GA4_CAMPAIGN_QUERY_PARAM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\nconst ACCEPTED_UNKNOWN_RESPONSE: AnalyticsIngestResponse = {\n acceptedCount: 0,\n duplicateCount: 0,\n rejectedCount: 0,\n errors: [],\n};\n\n/**\n * Checkout step identifiers for `checkout_step_completed` analytics events.\n */\nexport type CheckoutStep = \"contact\" | \"shipping\" | \"payment\" | \"review\";\n\n/**\n * Canonical analytics event type values accepted by the storefront ingest endpoint.\n */\nexport type AnalyticsEventType = TrackingPolicyEventType;\n\n/**\n * Supported preset event names accepted by `track()`.\n */\nexport type AnalyticsPresetEventName =\n | \"page_view\"\n | \"product_view\"\n | \"collection_view\"\n | \"search_performed\"\n | \"lead_generated\"\n | \"select_item\"\n | \"add_to_cart\"\n | \"remove_from_cart\"\n | \"view_cart\"\n | \"checkout_started\"\n | \"checkout_step_completed\";\n\nconst ANALYTICS_PRESET_EVENT_MAP = {\n page_view: \"analytics.page_view\",\n product_view: \"analytics.product_view\",\n collection_view: \"analytics.collection_view\",\n search_performed: \"analytics.search_performed\",\n lead_generated: \"analytics.lead_generated\",\n select_item: \"analytics.select_item\",\n add_to_cart: \"analytics.add_to_cart\",\n remove_from_cart: \"analytics.remove_from_cart\",\n view_cart: \"analytics.view_cart\",\n checkout_started: \"analytics.checkout_started\",\n checkout_step_completed: \"analytics.checkout_step_completed\",\n} as const satisfies Record<AnalyticsPresetEventName, AnalyticsEventType>;\n\n/**\n * Event name accepted by `track()`.\n * Preset names (e.g. `product_view`) are normalized to `analytics.*` types.\n * Unknown names are sent as `analytics.custom` with `{ eventName: <name> }`.\n */\nexport type AnalyticsTrackEventName = AnalyticsPresetEventName | AnalyticsEventType;\n\ntype PresetEventProperties = {\n page_view: Record<string, never>;\n product_view: {\n productId: string;\n variantId?: string | null;\n itemId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n currency?: string;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n collection_view: {\n collectionId: string;\n listId?: string;\n listName?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n search_performed: {\n query: string;\n resultsCount: number;\n };\n lead_generated: {\n leadType: string;\n source?: string;\n placement?: string;\n value?: number;\n currency?: string;\n signupOfferId?: string;\n promotionId?: string;\n };\n select_item: {\n productId: string;\n variantId?: string;\n itemId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n currency?: string;\n listId?: string;\n listName?: string;\n index?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n add_to_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n currency: string;\n itemId?: string;\n productId?: string;\n variantId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n remove_from_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n currency: string;\n itemId?: string;\n productId?: string;\n variantId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n view_cart: {\n cartId: string;\n cartValue: number;\n currency: string;\n itemsCount: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n checkout_started: {\n cartId: string;\n cartValue: number;\n currency: string;\n itemsCount: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n checkout_step_completed: {\n cartId: string;\n step: CheckoutStep;\n cartValue?: number;\n currency?: string;\n itemsCount?: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n};\n\nexport interface AnalyticsLineItemInput {\n itemId?: string;\n productId?: string | null;\n variantId?: string | null;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n quantity?: number;\n unitPrice?: number;\n price?: number;\n lineTotal?: number;\n itemListId?: string;\n listId?: string;\n itemListName?: string;\n listName?: string;\n index?: number;\n itemCategory?: string;\n}\n\ntype PresetPropertiesByName<T extends AnalyticsPresetEventName> = PresetEventProperties[T];\n\ninterface NormalizedPresetEvent {\n eventType: AnalyticsEventType;\n customEventName?: string;\n}\n\n/**\n * Optional context overrides for a tracking call.\n */\nexport interface AnalyticsContext {\n path?: string;\n referrer?: string | null;\n occurredAt?: Date | string;\n sessionId?: string;\n visitorId?: string;\n customerId?: string | null;\n utmSource?: string | null;\n utmMedium?: string | null;\n utmCampaign?: string | null;\n utmTerm?: string | null;\n utmContent?: string | null;\n consentState?: AnalyticsConsentState;\n clickIds?: Partial<Omit<AnalyticsClickIds, \"schemaVersion\">>;\n deviceType?: string;\n deviceOs?: string | null;\n deviceBrowser?: string | null;\n}\n\n/**\n * Error detail for a single ingest payload item.\n */\nexport interface AnalyticsErrorItem {\n /**\n * Index of the event in the request `events` array.\n */\n index: number;\n\n /**\n * Server-assigned identifier for the event, if available.\n */\n eventId: string | null;\n\n /**\n * Validation or processing error code.\n */\n code: string;\n\n /**\n * Human-readable description of the failure.\n */\n message: string;\n}\n\n/**\n * Response summary from the analytics ingest endpoint.\n */\nexport interface AnalyticsIngestResponse {\n /**\n * Number of events accepted and persisted.\n */\n acceptedCount: number;\n\n /**\n * Number of events recognized as duplicates.\n */\n duplicateCount: number;\n\n /**\n * Number of events rejected by validation or storage.\n */\n rejectedCount: number;\n\n /**\n * Per-item errors, aligned by event index.\n */\n errors: AnalyticsErrorItem[];\n}\n\ninterface AnalyticsIngestPayload {\n events: AnalyticsBrowserEvent[];\n}\n\ninterface SessionState {\n id: string;\n startedAt: number;\n lastSeenAt: number;\n}\n\ninterface DeviceInfo {\n deviceType: string;\n deviceOs: string | null;\n deviceBrowser: string | null;\n}\n\nexport interface ConfirmedPurchaseTrackingLineItem {\n contentId: string;\n productId: string | null;\n variantId: string | null;\n sku: string | null;\n productTitle: string;\n variantTitle: string | null;\n quantity: number;\n unitPrice: { amount: number };\n lineTotal: { amount: number };\n}\n\nexport interface ConfirmedPurchaseTrackingPayload {\n eventId: string;\n orderId: string;\n cartId: string;\n total: { amount: number };\n currency: string;\n numItems: number;\n lineItems: ConfirmedPurchaseTrackingLineItem[];\n}\n\ninterface AnalyticsIngestErrorResponse {\n error?: string;\n details?: { message?: string }[];\n}\n\nexport interface AnalyticsFlushSendOutcome {\n result: Result<AnalyticsIngestResponse, StorefrontError>;\n retryDisposition: {\n retryable: boolean;\n notBefore?: number;\n };\n}\n\nfunction hasBrowserContext(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction getDocument(): Document | null {\n return hasBrowserContext() ? document : null;\n}\n\nfunction getWindow(): Window | null {\n return hasBrowserContext() ? window : null;\n}\n\nfunction isUuid(value: string): boolean {\n return UUID_REGEX.test(value);\n}\n\nfunction randomUuid(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n const template = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\";\n return template.replace(/[xy]/g, (character) => {\n const random = Math.floor(Math.random() * 16);\n const value = character === \"x\" ? random : (random & 0x3) | 0x8;\n return value.toString(16);\n });\n}\n\nfunction getOrCreateVisitorId(): string {\n const doc = getDocument();\n if (doc) {\n const raw = doc.cookie;\n for (const pair of raw.split(\";\")) {\n const [name, ...valueParts] = pair.trim().split(\"=\");\n if (name === VISITOR_COOKIE_NAME) {\n return valueParts.join(\"=\") ? decodeURIComponent(valueParts.join(\"=\")) : randomUuid();\n }\n }\n }\n\n const value = randomUuid();\n if (doc) {\n const maxAge = 60 * 60 * 24 * 365 * 2;\n doc.cookie = `${VISITOR_COOKIE_NAME}=${encodeURIComponent(value)}; Max-Age=${maxAge}; Path=/; SameSite=Lax`;\n }\n\n return value;\n}\n\nlet fallbackSessionState: SessionState | null = null;\n\nfunction getSessionStorageState(): SessionState | null {\n const win = getWindow();\n if (!win) return fallbackSessionState;\n\n try {\n const raw = win.localStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) return fallbackSessionState;\n\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n\n const id = parsed.id;\n const startedAt = parsed.startedAt;\n const lastSeenAt = parsed.lastSeenAt;\n if (typeof id !== \"string\" || !id) return null;\n if (typeof startedAt !== \"number\" || typeof lastSeenAt !== \"number\") return null;\n\n return { id, startedAt, lastSeenAt };\n } catch {\n return fallbackSessionState;\n }\n}\n\nfunction setSessionStorageState(state: SessionState): void {\n fallbackSessionState = state;\n const win = getWindow();\n if (!win) return;\n\n try {\n win.localStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(state));\n } catch {\n // ignore localStorage failures\n }\n}\n\nfunction resolveSessionState(existing: SessionState | null, nowMs: number): SessionState {\n if (!existing) {\n return { id: randomUuid(), startedAt: nowMs, lastSeenAt: nowMs };\n }\n\n if (nowMs - existing.lastSeenAt > SESSION_TIMEOUT_MS) {\n return { id: randomUuid(), startedAt: nowMs, lastSeenAt: nowMs };\n }\n\n return { id: existing.id, startedAt: existing.startedAt, lastSeenAt: nowMs };\n}\n\nfunction resolveSessionId(nowMs: number): string {\n const existing = getSessionStorageState();\n const state = resolveSessionState(existing, nowMs);\n setSessionStorageState(state);\n return state.id;\n}\n\nfunction base64UrlDecode(value: string): string {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = normalized.length % 4;\n const padded = padding === 0 ? normalized : normalized + \"=\".repeat(4 - padding);\n return atob(padded);\n}\n\nfunction parseJWT(payload: string): Record<string, unknown> | null {\n try {\n const decoded = base64UrlDecode(payload);\n const parsed = JSON.parse(decoded);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n}\n\nfunction parseCustomerIdFromToken(token: string | null): string | null {\n if (!token) return null;\n\n const payload = token.split(\".\");\n const encodedPayload = payload[1];\n if (!encodedPayload) return null;\n\n const parsed = parseJWT(encodedPayload);\n if (!parsed) return null;\n\n const customerId = parsed.customerId;\n return typeof customerId === \"string\" && isUuid(customerId) ? customerId : null;\n}\n\nfunction decodeAnalyticsEntityId(value: string | null | undefined): string | null {\n if (!value) return null;\n return isUuid(value) ? value : null;\n}\n\nfunction normalizePositiveQuantity(value: number | null | undefined): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction normalizeOptionalNumber(value: number | null | undefined): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction normalizeOptionalString(value: string | null | undefined): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction normalizeOptionalNullableString(value: string | null | undefined): string | null | undefined {\n if (value === null) {\n return null;\n }\n\n return normalizeOptionalString(value);\n}\n\nfunction buildAnalyticsLineItem(input: AnalyticsLineItemInput): AnalyticsProperties {\n const productId = decodeAnalyticsEntityId(input.productId);\n const variantId = decodeAnalyticsEntityId(input.variantId);\n const sku = normalizeOptionalNullableString(input.sku);\n const quantity = normalizePositiveQuantity(input.quantity);\n const unitPrice = normalizeOptionalNumber(input.unitPrice ?? input.price);\n const lineTotal =\n normalizeOptionalNumber(input.lineTotal) ?? (unitPrice !== undefined ? unitPrice * quantity : undefined);\n const itemName = normalizeOptionalString(input.itemName ?? input.productTitle);\n const itemVariant = normalizeOptionalNullableString(input.itemVariant ?? input.variantTitle);\n const itemId = normalizeOptionalString(input.itemId) ?? variantId ?? sku ?? productId ?? undefined;\n const itemListId = normalizeOptionalString(input.itemListId ?? input.listId);\n const itemListName = normalizeOptionalString(input.itemListName ?? input.listName);\n const index =\n typeof input.index === \"number\" && Number.isFinite(input.index) ? Math.max(0, Math.floor(input.index)) : undefined;\n const itemCategory = normalizeOptionalString(input.itemCategory);\n\n const item: AnalyticsProperties = {\n quantity,\n };\n\n if (itemId) item.itemId = itemId;\n if (productId) item.productId = productId;\n if (variantId) item.variantId = variantId;\n if (sku !== undefined) item.sku = sku;\n if (itemName) {\n item.itemName = itemName;\n item.productTitle = itemName;\n }\n if (itemVariant !== undefined) {\n item.itemVariant = itemVariant;\n item.variantTitle = itemVariant;\n }\n if (unitPrice !== undefined) {\n item.unitPrice = unitPrice;\n item.price = unitPrice;\n }\n if (lineTotal !== undefined) item.lineTotal = lineTotal;\n if (itemListId) {\n item.itemListId = itemListId;\n item.listId = itemListId;\n }\n if (itemListName) {\n item.itemListName = itemListName;\n item.listName = itemListName;\n }\n if (index !== undefined) item.index = index;\n if (itemCategory) item.itemCategory = itemCategory;\n\n return item;\n}\n\nfunction buildLineItems(input: AnalyticsLineItemInput[] | undefined): AnalyticsProperties[\"lineItems\"] | undefined {\n if (!input || input.length === 0) {\n return undefined;\n }\n\n return input.map((item) => buildAnalyticsLineItem(item));\n}\n\nfunction applyLineItemToProperties(properties: AnalyticsProperties, lineItem: AnalyticsProperties): void {\n const itemId = lineItem.itemId;\n if (typeof itemId === \"string\") {\n properties.itemId = itemId;\n }\n\n const productId = lineItem.productId;\n if (typeof productId === \"string\") {\n properties.productId = productId;\n }\n\n const variantId = lineItem.variantId;\n if (typeof variantId === \"string\") {\n properties.variantId = variantId;\n }\n\n const sku = lineItem.sku;\n if (typeof sku === \"string\" || sku === null) {\n properties.sku = sku;\n }\n\n const itemName = lineItem.itemName;\n if (typeof itemName === \"string\") {\n properties.itemName = itemName;\n properties.productTitle = itemName;\n }\n\n const itemVariant = lineItem.itemVariant;\n if (typeof itemVariant === \"string\" || itemVariant === null) {\n properties.itemVariant = itemVariant;\n properties.variantTitle = itemVariant;\n }\n\n const unitPrice = lineItem.unitPrice;\n if (typeof unitPrice === \"number\") {\n properties.unitPrice = unitPrice;\n properties.price = unitPrice;\n }\n\n const lineTotal = lineItem.lineTotal;\n if (typeof lineTotal === \"number\") {\n properties.lineTotal = lineTotal;\n }\n\n const quantity = lineItem.quantity;\n if (typeof quantity === \"number\") {\n properties.quantity = quantity;\n }\n\n const itemListId = lineItem.itemListId;\n if (typeof itemListId === \"string\") {\n properties.itemListId = itemListId;\n properties.listId = itemListId;\n }\n\n const itemListName = lineItem.itemListName;\n if (typeof itemListName === \"string\") {\n properties.itemListName = itemListName;\n properties.listName = itemListName;\n }\n\n const index = lineItem.index;\n if (typeof index === \"number\") {\n properties.index = index;\n }\n\n const itemCategory = lineItem.itemCategory;\n if (typeof itemCategory === \"string\") {\n properties.itemCategory = itemCategory;\n }\n}\n\nfunction resolveDeviceInfo(): DeviceInfo {\n const win = getWindow();\n if (!win) {\n return { deviceType: \"server\", deviceOs: null, deviceBrowser: null };\n }\n\n const ua = win.navigator.userAgent.toLowerCase();\n\n const deviceType = /ipad|tablet|playbook|silk/.test(ua)\n ? \"tablet\"\n : /mobi|android|iphone|ipod|windows phone/.test(ua)\n ? \"mobile\"\n : \"desktop\";\n\n let deviceOs: string | null = null;\n if (ua.includes(\"windows\")) {\n deviceOs = \"Windows\";\n } else if (ua.includes(\"mac os\") || ua.includes(\"macintosh\")) {\n deviceOs = \"macOS\";\n } else if (ua.includes(\"android\")) {\n deviceOs = \"Android\";\n } else if (ua.includes(\"iphone\") || ua.includes(\"ipad\") || ua.includes(\"ios\")) {\n deviceOs = \"iOS\";\n } else if (ua.includes(\"linux\")) {\n deviceOs = \"Linux\";\n }\n\n let deviceBrowser: string | null = null;\n if (ua.includes(\"edg/\")) {\n deviceBrowser = \"Edge\";\n } else if (ua.includes(\"firefox/\")) {\n deviceBrowser = \"Firefox\";\n } else if (ua.includes(\"chrome/\") && !ua.includes(\"edg/\")) {\n deviceBrowser = \"Chrome\";\n } else if (ua.includes(\"safari/\") && !ua.includes(\"chrome/\")) {\n deviceBrowser = \"Safari\";\n }\n\n return { deviceType, deviceOs, deviceBrowser };\n}\n\nfunction normalizePath(pathname: string): string {\n return pathname.trim().length > 0 ? pathname : \"/\";\n}\n\nfunction toIsoTimestamp(value: Date | string | number | null | undefined): string | null {\n if (value == null) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n}\n\nfunction buildUtmPayload(context: AnalyticsContext, trackingAttributionTtlMs?: number): AnalyticsUtm {\n const persisted = getTrackingAttributionSnapshot({ ttlMs: trackingAttributionTtlMs });\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: context.utmSource ?? persisted?.utm.source ?? null,\n medium: context.utmMedium ?? persisted?.utm.medium ?? null,\n campaign: context.utmCampaign ?? persisted?.utm.campaign ?? null,\n term: context.utmTerm ?? persisted?.utm.term ?? null,\n content: context.utmContent ?? persisted?.utm.content ?? null,\n };\n}\n\nfunction buildClickIdsPayload(context: AnalyticsContext, trackingAttributionTtlMs?: number): AnalyticsClickIds {\n const persisted = getTrackingAttributionSnapshot({ ttlMs: trackingAttributionTtlMs });\n const clickIds = context.clickIds;\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: toIsoTimestamp(clickIds?.capturedAt) ?? persisted?.clickIds.capturedAt ?? null,\n gclid: clickIds?.gclid ?? persisted?.clickIds.gclid ?? null,\n gbraid: clickIds?.gbraid ?? persisted?.clickIds.gbraid ?? null,\n wbraid: clickIds?.wbraid ?? persisted?.clickIds.wbraid ?? null,\n ttclid: clickIds?.ttclid ?? persisted?.clickIds.ttclid ?? null,\n fbclid: clickIds?.fbclid ?? persisted?.clickIds.fbclid ?? null,\n };\n}\n\nfunction buildDefaultContext(): AnalyticsContext {\n const context: AnalyticsContext = {};\n const device = resolveDeviceInfo();\n\n const win = getWindow();\n if (win) {\n const { pathname, search } = win.location;\n context.path = pathname + search;\n context.referrer = win.document.referrer.length > 0 ? win.document.referrer : null;\n const params = new URLSearchParams(win.location.search);\n context.utmSource = params.get(\"utm_source\");\n context.utmMedium = params.get(\"utm_medium\");\n context.utmCampaign = params.get(\"utm_campaign\");\n context.utmTerm = params.get(\"utm_term\");\n context.utmContent = params.get(\"utm_content\");\n context.deviceType = device.deviceType;\n context.deviceOs = device.deviceOs;\n context.deviceBrowser = device.deviceBrowser;\n }\n\n if (!context.deviceType) {\n context.deviceType = \"unknown\";\n }\n\n context.deviceOs ??= null;\n context.deviceBrowser ??= null;\n\n return context;\n}\n\nfunction normalizeEventContext(context: AnalyticsContext | undefined): AnalyticsContext {\n const defaults = buildDefaultContext();\n return { ...defaults, ...context };\n}\n\nfunction hasCurrentLandingGa4CampaignParams(): boolean {\n const win = getWindow();\n if (!win) {\n return false;\n }\n\n const params = new URLSearchParams(win.location.search);\n return LANDING_GA4_CAMPAIGN_QUERY_PARAM_KEYS.some((key) => {\n const value = params.get(key);\n return value !== null && value.trim().length > 0;\n });\n}\n\nfunction isIngestResponse(value: unknown): value is AnalyticsIngestResponse {\n if (typeof value !== \"object\" || value === null) return false;\n\n const response = value as Record<string, unknown>;\n\n return (\n typeof response.acceptedCount === \"number\" &&\n typeof response.duplicateCount === \"number\" &&\n typeof response.rejectedCount === \"number\" &&\n Array.isArray(response.errors)\n );\n}\n\nfunction extractErrorMessage(response: Response): Promise<string> {\n return response\n .json()\n .then((payload: AnalyticsIngestErrorResponse) => {\n if (typeof payload.error === \"string\" && payload.error.length > 0) {\n return payload.error;\n }\n\n const firstMessage = Array.isArray(payload.details)\n ? payload.details\n .map((error) => (typeof error?.message === \"string\" ? error.message : null))\n .find((message) => message !== null)\n : null;\n\n if (firstMessage) {\n return firstMessage;\n }\n\n return `Analytics ingest failed with status ${response.status}`;\n })\n .catch(() => `Analytics ingest failed with status ${response.status}`);\n}\n\nfunction parseRetryAfterHeader(response: Response, nowMs: number): number | null {\n const retryAfter = response.headers.get(\"retry-after\");\n if (!retryAfter) {\n return null;\n }\n\n const trimmed = retryAfter.trim();\n if (!/^\\d+$/.test(trimmed)) {\n return null;\n }\n\n const seconds = Number.parseInt(trimmed, 10);\n if (!Number.isFinite(seconds) || seconds <= 0) {\n return null;\n }\n\n return nowMs + seconds * 1000;\n}\n\nfunction toError(error: unknown, message: string): Error {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(message);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport async function flushAnalyticsRetryQueue(\n retryQueue: AnalyticsRetryQueue,\n sendEventOutcome: (event: AnalyticsBrowserEvent) => Promise<AnalyticsFlushSendOutcome>,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n nowMs = Date.now(),\n): Promise<number> {\n const queuedEntries = retryQueue.read(nowMs);\n const nextEntries: AnalyticsRetryQueueEntry[] = [];\n let sentCount = 0;\n\n for (const entry of queuedEntries) {\n if (entry.notBefore !== undefined && entry.notBefore > nowMs) {\n nextEntries.push(entry);\n continue;\n }\n\n const outcome = await sendEventOutcome(entry.event);\n if (outcome.result.isOk()) {\n sentCount += 1;\n continue;\n }\n\n if (!outcome.retryDisposition.retryable) {\n continue;\n }\n\n nextEntries.push({\n event: entry.event,\n queuedAt: entry.queuedAt,\n ...(outcome.retryDisposition.notBefore !== undefined ? { notBefore: outcome.retryDisposition.notBefore } : {}),\n });\n }\n\n retryQueue.replace(nextEntries);\n emitDiagnostic({\n target: \"queue\",\n status: \"flushed\",\n count: sentCount,\n });\n\n return sentCount;\n}\n\nfunction resolveTrackEvent(eventName: AnalyticsTrackEventName): NormalizedPresetEvent {\n const normalized = eventName.startsWith(\"analytics.\") ? eventName.slice(\"analytics.\".length) : eventName;\n if (normalized in ANALYTICS_PRESET_EVENT_MAP) {\n return { eventType: ANALYTICS_PRESET_EVENT_MAP[normalized as AnalyticsPresetEventName] };\n }\n\n return {\n eventType: \"analytics.custom\",\n customEventName: eventName,\n };\n}\n\nfunction dispatchEventToBrowserRuntime(\n runtime:\n | {\n adapters?: AnalyticsBrowserAdapter[];\n }\n | null\n | undefined,\n event: AnalyticsBrowserEvent,\n resolvedAnalytics: ResolvedStorefrontAnalyticsConfig,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n scheduleBestEffort: (task: () => void | Promise<void>) => void,\n consentManager: ConsentManager | null,\n debug = false,\n onDispatchSuccess?: (provider: AnalyticsBrowserAdapter[\"provider\"]) => void,\n): void {\n const adapters = (runtime?.adapters ?? []).filter(\n (adapter) => adapter.provider !== \"gtm\" || resolvedAnalytics.gtm.enabled,\n );\n if (adapters.length === 0) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] browser dispatch: no adapters available for\", event.eventType);\n }\n return;\n }\n\n const consent: AnalyticsConsentUpdate = {\n consentState: event.consentState,\n };\n\n scheduleBestEffort(async () => {\n for (const adapter of adapters) {\n if (adapter.updateConsent) {\n try {\n const result = await adapter.updateConsent(consent);\n if (result?.status === \"skipped\") {\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"skipped\",\n provider: adapter.provider,\n consent,\n reason: result.reason,\n });\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: result.reason,\n });\n continue;\n }\n\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"success\",\n provider: adapter.provider,\n consent,\n });\n } catch (error) {\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"error\",\n provider: adapter.provider,\n consent,\n error: toError(error, `Failed to update ${adapter.provider} consent bridge`),\n });\n emitDiagnostic({\n target: \"adapter\",\n status: \"error\",\n provider: adapter.provider,\n event,\n error: toError(error, `Skipped ${adapter.provider} browser tracking event due to consent bridge failure`),\n });\n continue;\n }\n }\n\n const dispatchInput = { event, consent };\n\n if (consentManager) {\n if (consentManager.shouldBuffer(adapter.provider)) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\n `[ekomerc:analytics] adapter ${adapter.provider} buffered (consent pending)`,\n event.eventType,\n );\n }\n consentManager.bufferDispatch({ adapter, input: dispatchInput });\n continue;\n }\n if (consentManager.shouldDiscard(adapter.provider)) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\n `[ekomerc:analytics] adapter ${adapter.provider} discarded (consent denied)`,\n event.eventType,\n );\n }\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: \"consent_blocked\",\n });\n continue;\n }\n } else if ((TRACKING_PROVIDERS as readonly string[]).includes(adapter.provider)) {\n const dispatchDecision = shouldDispatchBrowserAdapter(adapter.provider, event.eventType, event.consentState);\n if (!dispatchDecision.allowed) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(`[ekomerc:analytics] adapter ${adapter.provider} skipped:`, dispatchDecision.reason);\n }\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: dispatchDecision.reason,\n });\n continue;\n }\n }\n\n try {\n const result = await adapter.dispatch(dispatchInput);\n if (result?.status === \"skipped\") {\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: result.reason,\n });\n continue;\n }\n\n emitDiagnostic({\n target: \"adapter\",\n status: \"success\",\n provider: adapter.provider,\n event,\n });\n onDispatchSuccess?.(adapter.provider);\n } catch (error) {\n emitDiagnostic({\n target: \"adapter\",\n status: \"error\",\n provider: adapter.provider,\n event,\n error: toError(error, `Failed to dispatch ${adapter.provider} browser tracking event`),\n });\n }\n }\n });\n}\n\n/**\n * Fire-and-forget emit function used internally by SDK modules for auto-tracking.\n */\nexport type AnalyticsEmitFn = (\n eventType: AnalyticsEventType,\n properties: AnalyticsProperties,\n context?: AnalyticsContext,\n) => void;\n\n/**\n * Minimal product shape accepted by analytics helper methods.\n */\nexport interface AnalyticsProductLike {\n id: string;\n title?: string;\n productType?: string | null;\n primaryCategory?: { name?: string | null } | null;\n variants?: AnalyticsProductVariantLike[];\n}\n\nexport interface AnalyticsProductVariantLike {\n id: string;\n title?: string | null;\n sku?: string | null;\n price?: { amount: number; currency: string };\n}\n\n/**\n * Minimal collection shape accepted by analytics helper methods.\n */\nexport interface AnalyticsCollectionLike {\n id: string;\n title?: string;\n}\n\n/**\n * Minimal cart shape accepted by analytics helper methods.\n */\nexport interface AnalyticsCartLike {\n id: string;\n totalItems: number;\n total: { amount: number; currency: string };\n items?: Array<{\n variantId: string;\n quantity: number;\n effectiveUnitPrice: { amount: number; currency: string };\n lineTotal: { amount: number; currency: string };\n variant?: {\n productId?: string;\n productTitle?: string | null;\n title?: string | null;\n sku?: string | null;\n } | null;\n }>;\n}\n\ntype TrackResult = Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n\n/**\n * Ergonomic helper methods for built-in analytics events.\n */\nexport interface AnalyticsTrackHelpers {\n pageView(context?: AnalyticsContext): TrackResult;\n productView(\n product: AnalyticsProductLike,\n options?: { variant?: AnalyticsProductVariantLike | null },\n context?: AnalyticsContext,\n ): TrackResult;\n collectionView(collection: AnalyticsCollectionLike, context?: AnalyticsContext): TrackResult;\n viewCart(cart: AnalyticsCartLike, context?: AnalyticsContext): TrackResult;\n selectItem(\n product: AnalyticsProductLike,\n options?: {\n variant?: AnalyticsProductVariantLike | null;\n listId?: string;\n listName?: string;\n index?: number;\n },\n context?: AnalyticsContext,\n ): TrackResult;\n custom(eventName: string, properties?: AnalyticsProperties, context?: AnalyticsContext): TrackResult;\n}\n\n/**\n * Combined track function: callable with preset/custom event names, plus helper methods.\n */\nexport interface AnalyticsTrackFn extends AnalyticsTrackHelpers {\n (eventName: \"page_view\", context?: AnalyticsContext): TrackResult;\n (eventName: \"product_view\", input: PresetPropertiesByName<\"product_view\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"collection_view\",\n input: PresetPropertiesByName<\"collection_view\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"search_performed\",\n input: PresetPropertiesByName<\"search_performed\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"lead_generated\",\n input: PresetPropertiesByName<\"lead_generated\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: \"select_item\", input: PresetPropertiesByName<\"select_item\">, context?: AnalyticsContext): TrackResult;\n (eventName: \"add_to_cart\", input: PresetPropertiesByName<\"add_to_cart\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"remove_from_cart\",\n input: PresetPropertiesByName<\"remove_from_cart\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: \"view_cart\", input: PresetPropertiesByName<\"view_cart\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"checkout_started\",\n input: PresetPropertiesByName<\"checkout_started\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"checkout_step_completed\",\n input: PresetPropertiesByName<\"checkout_step_completed\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: string, properties: AnalyticsProperties, context?: AnalyticsContext): TrackResult;\n}\n\nexport interface AnalyticsOperations {\n readonly consent: ConsentOperations | null;\n readonly track: AnalyticsTrackFn;\n}\n\ninterface AnalyticsController extends AnalyticsOperations {\n init(input?: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions): void;\n}\n\nexport interface AnalyticsOperationsResult {\n operations: AnalyticsController;\n emit: AnalyticsEmitFn;\n}\n\ninterface AnalyticsRuntimeClient extends StorefrontClientContext {\n _analyticsRuntimeConfig: StorefrontAnalyticsInitConfig | null;\n _resolvedInitConfig: { analytics: ResolvedStorefrontAnalyticsConfig } | null;\n}\n\nfunction isResolvedAnalyticsConfig(\n input: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions | undefined,\n): input is ResolvedStorefrontAnalyticsConfig {\n return Boolean(input && typeof input === \"object\" && \"enabled\" in input && \"gtm\" in input);\n}\n\nfunction buildDefaultResolvedAnalyticsConfig(\n runtime: StorefrontAnalyticsInitConfig | null,\n): ResolvedStorefrontAnalyticsConfig {\n const hasGtmAdapter = runtime?.adapters?.some((adapter) => adapter.provider === \"gtm\") ?? false;\n\n return {\n enabled: true,\n firstPartyEnabled: true,\n gtm: {\n enabled: hasGtmAdapter,\n containerId: null,\n },\n };\n}\n\n/**\n * Builds the storefront analytics controller around the resolved client config, retry queue, and\n * browser lifecycle hooks.\n *\n * Initialization and event dispatch are intentionally decoupled here, so callers can queue\n * tracking work before `client.init()` has finished without reading stale runtime config.\n */\nexport function createAnalyticsOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n consentManager: ConsentManager | null = null,\n): AnalyticsOperationsResult {\n const trackingAttributionTtlMs = client.config.trackingAttributionTTL;\n const debug = client.config.debug === true;\n const runtimeClient = client as AnalyticsRuntimeClient;\n let lifecycleFlushListenersRegistered = false;\n let pendingGa4CampaignOverride = false;\n\n const endpoint = (() => {\n try {\n const parsedEndpoint = new URL(client.config.endpoint);\n return `${parsedEndpoint.origin}${ANALYTICS_PATH}`;\n } catch {\n return null;\n }\n })();\n\n const apiKey = client.config.apiKey;\n\n function getTrackingRuntime(): StorefrontAnalyticsInitConfig | null {\n return runtimeClient._analyticsRuntimeConfig ?? client.config.tracking ?? null;\n }\n\n function getResolvedAnalyticsConfig(): ResolvedStorefrontAnalyticsConfig | null {\n return runtimeClient._resolvedInitConfig?.analytics ?? null;\n }\n\n function hasEnabledGtmAdapter(\n runtime: StorefrontAnalyticsInitConfig | null,\n resolved: ResolvedStorefrontAnalyticsConfig,\n ): boolean {\n return resolved.gtm.enabled && (runtime?.adapters?.some((adapter) => adapter.provider === \"gtm\") ?? false);\n }\n\n function emitDiagnostic(diagnostic: AnalyticsDiagnostic): void {\n try {\n getTrackingRuntime()?.onDiagnostic?.(diagnostic);\n } catch {\n // Diagnostics are observer-only and must never affect storefront flows.\n }\n }\n\n const retryQueue = createAnalyticsRetryQueue(storage, apiKey, emitDiagnostic);\n\n async function resolveConsentState(explicitConsentState?: AnalyticsConsentState): Promise<AnalyticsConsentState> {\n if (explicitConsentState) {\n return explicitConsentState;\n }\n\n const trackingRuntime = getTrackingRuntime();\n if (!trackingRuntime?.resolveConsentState) {\n return consentManager ? consentManager.resolveConsentState() : \"unknown\";\n }\n\n try {\n return await trackingRuntime.resolveConsentState();\n } catch (error) {\n emitDiagnostic({\n target: \"consent\",\n status: \"error\",\n error: toError(error, \"Failed to resolve tracking consent state\"),\n });\n return \"unknown\";\n }\n }\n\n function scheduleBestEffort(task: () => void | Promise<void>): void {\n Promise.resolve()\n .then(task)\n .catch(() => {\n // Best-effort background tasks must not surface to callers.\n });\n }\n\n function flushRetryQueueInBackground(): void {\n const resolved = getResolvedAnalyticsConfig();\n if (resolved && !resolved.firstPartyEnabled) return;\n scheduleBestEffort(async () => {\n await flushAnalyticsRetryQueue(retryQueue, sendEventOutcome, emitDiagnostic);\n });\n }\n\n function registerLifecycleFlushListeners(): void {\n if (!hasBrowserContext() || lifecycleFlushListenersRegistered) {\n return;\n }\n\n const win = getWindow();\n const doc = getDocument();\n if (!win || !doc) {\n return;\n }\n\n win.addEventListener(\"online\", () => {\n flushRetryQueueInBackground();\n });\n\n doc.addEventListener(\"visibilitychange\", () => {\n if (doc.visibilityState === \"hidden\") {\n flushRetryQueueInBackground();\n }\n });\n\n lifecycleFlushListenersRegistered = true;\n }\n\n function init(input?: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions): void {\n if (isResolvedAnalyticsConfig(input)) {\n runtimeClient._resolvedInitConfig = { analytics: input };\n } else {\n runtimeClient._analyticsRuntimeConfig = {\n ...(getTrackingRuntime() ?? {}),\n ...(input ?? {}),\n };\n runtimeClient._resolvedInitConfig ??= {\n analytics: buildDefaultResolvedAnalyticsConfig(getTrackingRuntime()),\n };\n }\n\n pendingGa4CampaignOverride = hasCurrentLandingGa4CampaignParams();\n captureLandingTrackingAttribution({ ttlMs: trackingAttributionTtlMs });\n if (getTrackingRuntime()?.stripUrl !== false) {\n stripLandingTrackingAttributionFromUrl();\n }\n\n if (debug) {\n const resolved = getResolvedAnalyticsConfig();\n const runtime = getTrackingRuntime();\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] init:\", {\n enabled: resolved?.enabled ?? null,\n gtm: resolved?.gtm ?? null,\n adapterCount: runtime?.adapters?.length ?? 0,\n adapters: runtime?.adapters?.map((a) => a.provider) ?? [],\n });\n }\n\n registerLifecycleFlushListeners();\n flushRetryQueueInBackground();\n }\n\n function buildCanonicalEvent(\n eventType: AnalyticsEventType,\n properties: AnalyticsProperties,\n eventContext: AnalyticsContext,\n consentState: AnalyticsConsentState,\n ): AnalyticsBrowserEvent {\n const now = new Date(eventContext.occurredAt ?? Date.now());\n const nowIso = Number.isNaN(now.getTime()) ? new Date().toISOString() : now.toISOString();\n\n const customerId =\n eventContext.customerId === undefined\n ? parseCustomerIdFromToken(client.getCustomerToken())\n : eventContext.customerId;\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n eventId: randomUuid(),\n eventType,\n occurredAt: nowIso,\n sessionId: eventContext.sessionId ?? resolveSessionId(now.getTime()),\n visitorId: eventContext.visitorId ?? getOrCreateVisitorId(),\n customerId: customerId ?? null,\n consentState,\n context: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n path: normalizePath(eventContext.path ?? \"/\"),\n },\n referrer: eventContext.referrer ?? null,\n utm: buildUtmPayload(eventContext, trackingAttributionTtlMs),\n clickIds: buildClickIdsPayload(eventContext, trackingAttributionTtlMs),\n device: {\n deviceType: eventContext.deviceType ?? \"unknown\",\n deviceOs: eventContext.deviceOs ?? null,\n deviceBrowser: eventContext.deviceBrowser ?? null,\n },\n properties,\n };\n }\n\n async function sendEventOutcome(event: AnalyticsBrowserEvent): Promise<AnalyticsFlushSendOutcome> {\n if (!endpoint) {\n return {\n result: err(new NetworkError(\"Invalid storefront endpoint\")),\n retryDisposition: { retryable: true },\n };\n }\n\n const payload: AnalyticsIngestPayload = {\n events: [event],\n };\n const body = JSON.stringify(payload);\n const keepalive = new Blob([body]).size <= KEEPALIVE_MAX_BODY_BYTES;\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-storefront-key\": apiKey,\n },\n body,\n ...(keepalive ? { keepalive: true } : {}),\n });\n\n if (!response.ok) {\n const message = response.headers.get(\"content-type\")?.includes(\"application/json\")\n ? await extractErrorMessage(response)\n : `Analytics ingest failed with status ${response.status}`;\n const networkError = new NetworkError(message);\n const nowMs = Date.now();\n const retryDisposition =\n response.status === 429\n ? (() => {\n const notBefore = parseRetryAfterHeader(response, nowMs);\n return notBefore ? { retryable: true, notBefore } : { retryable: false };\n })()\n : response.status >= 500\n ? { retryable: true }\n : { retryable: false };\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition,\n };\n }\n\n let parsed: unknown;\n try {\n parsed = await response.json();\n } catch {\n emitDiagnostic({\n target: \"ingest\",\n status: \"accepted_unknown\",\n event,\n });\n return {\n result: ok(ACCEPTED_UNKNOWN_RESPONSE),\n retryDisposition: { retryable: false },\n };\n }\n\n if (!isIngestResponse(parsed)) {\n const networkError = new NetworkError(\"Analytics response shape is invalid\");\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition: { retryable: false },\n };\n }\n\n emitDiagnostic({\n target: \"ingest\",\n status: \"success\",\n event,\n response: {\n acceptedCount: parsed.acceptedCount,\n duplicateCount: parsed.duplicateCount,\n rejectedCount: parsed.rejectedCount,\n },\n });\n return {\n result: ok(parsed),\n retryDisposition: { retryable: false },\n };\n } catch (error) {\n const networkError = new NetworkError(\"Failed to send analytics event\", {\n cause: error instanceof Error ? error : undefined,\n });\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition: { retryable: true },\n };\n }\n }\n\n type NormalizeResult = Result<{ eventType: AnalyticsEventType; properties: AnalyticsProperties }, StorefrontError>;\n\n function normalizePageView(\n payload: unknown,\n context: AnalyticsContext | undefined,\n ): { result: NormalizeResult; context: AnalyticsContext | undefined } {\n return {\n result: ok({ eventType: \"analytics.page_view\", properties: {} }),\n context: context ?? (isPlainObject(payload) ? (payload as AnalyticsContext) : undefined),\n };\n }\n\n function normalizeProductView(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"productId is required\"));\n const p = payload as PresetPropertiesByName<\"product_view\">;\n const productId = decodeAnalyticsEntityId(p.productId);\n if (!productId) return err(new NetworkError(\"Invalid productId\"));\n const variantId = decodeAnalyticsEntityId(p.variantId);\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId,\n variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: 1,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n\n const properties: AnalyticsProperties = {\n productId,\n lineItems,\n };\n if (variantId) properties.variantId = variantId;\n if (p.currency) properties.currency = p.currency;\n applyLineItemToProperties(properties, lineItem);\n\n return ok({\n eventType: \"analytics.product_view\",\n properties,\n });\n }\n\n function normalizeCollectionView(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"collectionId is required\"));\n const p = payload as PresetPropertiesByName<\"collection_view\">;\n const collectionId = decodeAnalyticsEntityId(p.collectionId);\n if (!collectionId) return err(new NetworkError(\"Invalid collectionId\"));\n const properties: AnalyticsProperties = { collectionId };\n if (p.listId) {\n properties.listId = p.listId;\n properties.itemListId = p.listId;\n }\n if (p.listName) {\n properties.listName = p.listName;\n properties.itemListName = p.listName;\n }\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) {\n properties.lineItems = lineItems;\n }\n\n return ok({ eventType: \"analytics.collection_view\", properties });\n }\n\n function normalizeSearchPerformed(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"query is required\"));\n const p = payload as PresetPropertiesByName<\"search_performed\">;\n const trimmed = p.query.trim();\n if (!trimmed) return err(new NetworkError(\"query is required\"));\n return ok({\n eventType: \"analytics.search_performed\",\n properties: { query: trimmed, resultsCount: Math.max(0, Math.floor(p.resultsCount)) },\n });\n }\n\n function normalizeLeadGenerated(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"leadType is required\"));\n const p = payload as PresetPropertiesByName<\"lead_generated\">;\n const leadType = typeof p.leadType === \"string\" ? p.leadType.trim() : \"\";\n if (!leadType) return err(new NetworkError(\"leadType is required\"));\n if (typeof p.value === \"number\" && Number.isFinite(p.value) && !p.currency) {\n return err(new NetworkError(\"currency is required when value is set\"));\n }\n\n const properties: AnalyticsProperties = { leadType };\n if (p.source) {\n properties.source = p.source;\n }\n if (p.placement) {\n properties.placement = p.placement;\n }\n if (typeof p.value === \"number\" && Number.isFinite(p.value)) {\n properties.value = p.value;\n }\n if (p.currency) {\n properties.currency = p.currency;\n }\n if (p.signupOfferId) {\n properties.signupOfferId = p.signupOfferId;\n }\n if (p.promotionId) {\n properties.promotionId = p.promotionId;\n }\n\n return ok({\n eventType: \"analytics.lead_generated\",\n properties,\n });\n }\n\n function normalizeSelectItem(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"productId is required\"));\n const p = payload as PresetPropertiesByName<\"select_item\">;\n const productId = decodeAnalyticsEntityId(p.productId);\n if (!productId) return err(new NetworkError(\"Invalid productId\"));\n const variantId = decodeAnalyticsEntityId(p.variantId);\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId,\n variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: 1,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n itemListId: p.listId,\n listId: p.listId,\n itemListName: p.listName,\n listName: p.listName,\n index: p.index,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n const props: AnalyticsProperties = { productId, lineItems };\n if (variantId) props.variantId = variantId;\n if (p.currency) props.currency = p.currency;\n applyLineItemToProperties(props, lineItem);\n return ok({ eventType: \"analytics.select_item\", properties: props });\n }\n\n function normalizeCartMutationEvent(\n eventType: \"analytics.add_to_cart\" | \"analytics.remove_from_cart\",\n payload: unknown,\n ): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"add_to_cart\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const props: AnalyticsProperties = {\n cartId,\n quantity: Math.max(1, Math.floor(p.quantity)),\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n cartValue: p.cartValue,\n currency: p.currency,\n };\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId: p.productId,\n variantId: p.variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: p.quantity,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n lineTotal:\n p.unitPrice !== undefined\n ? p.unitPrice * Math.max(1, Math.floor(p.quantity))\n : p.price !== undefined\n ? p.price * Math.max(1, Math.floor(p.quantity))\n : undefined,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n props.lineItems = lineItems;\n applyLineItemToProperties(props, lineItem);\n return ok({ eventType, properties: props });\n }\n\n function normalizeViewCart(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"view_cart\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const lineItems = buildLineItems(p.lineItems);\n return ok({\n eventType: \"analytics.view_cart\",\n properties: {\n cartId,\n cartValue: p.cartValue,\n currency: p.currency,\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n ...(lineItems ? { lineItems } : {}),\n },\n });\n }\n\n function normalizeCheckoutStarted(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"checkout_started\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const props: AnalyticsProperties = {\n cartId,\n cartValue: p.cartValue,\n currency: p.currency,\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n };\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) props.lineItems = lineItems;\n return ok({ eventType: \"analytics.checkout_started\", properties: props });\n }\n\n function normalizeCheckoutStepCompleted(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"checkout_step_completed\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const properties: AnalyticsProperties = { cartId, step: p.step };\n if (typeof p.cartValue === \"number\" && Number.isFinite(p.cartValue)) {\n properties.cartValue = p.cartValue;\n }\n if (p.currency) {\n properties.currency = p.currency;\n }\n if (typeof p.itemsCount === \"number\" && Number.isFinite(p.itemsCount)) {\n properties.itemsCount = Math.max(0, Math.floor(p.itemsCount));\n }\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) properties.lineItems = lineItems;\n return ok({ eventType: \"analytics.checkout_step_completed\", properties });\n }\n\n async function track(\n eventName: AnalyticsTrackEventName,\n eventPayload?: AnalyticsProperties | PresetPropertiesByName<AnalyticsPresetEventName> | AnalyticsContext,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>> {\n let eventContext: AnalyticsContext | undefined = context;\n const normalized = resolveTrackEvent(eventName);\n let eventType: AnalyticsEventType;\n let properties: AnalyticsProperties;\n\n if (normalized.eventType !== \"analytics.custom\") {\n let normalizeResult: NormalizeResult;\n switch (normalized.eventType) {\n case \"analytics.page_view\": {\n const { result, context: ctx } = normalizePageView(eventPayload, eventContext);\n normalizeResult = result;\n eventContext = ctx;\n break;\n }\n case \"analytics.product_view\":\n normalizeResult = normalizeProductView(eventPayload);\n break;\n case \"analytics.collection_view\":\n normalizeResult = normalizeCollectionView(eventPayload);\n break;\n case \"analytics.search_performed\":\n normalizeResult = normalizeSearchPerformed(eventPayload);\n break;\n case \"analytics.lead_generated\":\n normalizeResult = normalizeLeadGenerated(eventPayload);\n break;\n case \"analytics.select_item\":\n normalizeResult = normalizeSelectItem(eventPayload);\n break;\n case \"analytics.add_to_cart\":\n normalizeResult = normalizeCartMutationEvent(\"analytics.add_to_cart\", eventPayload);\n break;\n case \"analytics.remove_from_cart\":\n normalizeResult = normalizeCartMutationEvent(\"analytics.remove_from_cart\", eventPayload);\n break;\n case \"analytics.view_cart\":\n normalizeResult = normalizeViewCart(eventPayload);\n break;\n case \"analytics.checkout_started\":\n normalizeResult = normalizeCheckoutStarted(eventPayload);\n break;\n case \"analytics.checkout_step_completed\":\n normalizeResult = normalizeCheckoutStepCompleted(eventPayload);\n break;\n default:\n return err(new NetworkError(`Unsupported event type: ${normalized.eventType}`));\n }\n if (normalizeResult.isErr()) {\n return err(normalizeResult.error);\n }\n ({ eventType, properties } = normalizeResult.value);\n } else {\n eventType = \"analytics.custom\";\n properties = {\n ...(isPlainObject(eventPayload) ? (eventPayload as AnalyticsProperties) : {}),\n eventName: normalized.customEventName ?? eventName,\n };\n }\n\n const normalizedContext = normalizeEventContext(eventContext);\n const resolvedAnalytics = getResolvedAnalyticsConfig() ?? buildDefaultResolvedAnalyticsConfig(getTrackingRuntime());\n if (!resolvedAnalytics.enabled) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track: analytics disabled, skipping\", eventType);\n }\n return ok(ACCEPTED_UNKNOWN_RESPONSE);\n }\n\n const trackingRuntime = getTrackingRuntime();\n const consentState = await resolveConsentState(normalizedContext.consentState);\n const event = buildCanonicalEvent(eventType, properties, normalizedContext, consentState);\n const shouldApplyGa4CampaignOverride = pendingGa4CampaignOverride && eventType === \"analytics.page_view\";\n const browserEvent = shouldApplyGa4CampaignOverride\n ? {\n ...event,\n properties: {\n ...event.properties,\n [INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY]: true,\n },\n }\n : event;\n\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track:\", {\n eventName,\n eventType,\n consentState,\n });\n }\n\n dispatchEventToBrowserRuntime(\n trackingRuntime,\n browserEvent,\n resolvedAnalytics,\n emitDiagnostic,\n scheduleBestEffort,\n consentManager,\n debug,\n (provider) => {\n if (shouldApplyGa4CampaignOverride && provider === \"gtm\") {\n pendingGa4CampaignOverride = false;\n }\n },\n );\n if (shouldApplyGa4CampaignOverride && !hasEnabledGtmAdapter(trackingRuntime, resolvedAnalytics)) {\n pendingGa4CampaignOverride = false;\n }\n\n if (!resolvedAnalytics.firstPartyEnabled) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track: first-party disabled, skipping ingest\", eventType);\n }\n return ok(ACCEPTED_UNKNOWN_RESPONSE);\n }\n\n const outcome = await sendEventOutcome(event);\n if (outcome.result.isErr() && outcome.retryDisposition.retryable) {\n retryQueue.enqueue({\n event,\n queuedAt: Date.now(),\n ...(outcome.retryDisposition.notBefore !== undefined ? { notBefore: outcome.retryDisposition.notBefore } : {}),\n });\n }\n\n if (outcome.result.isOk() && retryQueue.read().length > 0) {\n flushRetryQueueInBackground();\n }\n\n return outcome.result;\n }\n\n const trackFn = Object.assign(track, {\n pageView(context?: AnalyticsContext) {\n return track(\"page_view\", context);\n },\n productView(\n product: AnalyticsProductLike,\n options?: { variant?: AnalyticsProductVariantLike | null },\n context?: AnalyticsContext,\n ) {\n const variant =\n product.variants?.find((entry) => entry.id === options?.variant?.id) ??\n options?.variant ??\n product.variants?.[0];\n const itemCategory = product.primaryCategory?.name ?? product.productType ?? undefined;\n const variantId = variant?.id;\n const props: PresetPropertiesByName<\"product_view\"> = {\n productId: product.id,\n ...(variantId ? { variantId } : {}),\n ...(product.title ? { productTitle: product.title, itemName: product.title } : {}),\n ...(variant?.title ? { variantTitle: variant.title, itemVariant: variant.title } : {}),\n ...(variant?.sku !== undefined ? { sku: variant.sku } : {}),\n ...(variant?.price\n ? { unitPrice: variant.price.amount, price: variant.price.amount, currency: variant.price.currency }\n : {}),\n ...(itemCategory ? { itemCategory } : {}),\n };\n return track(\"product_view\", props, context);\n },\n collectionView(collection: AnalyticsCollectionLike, context?: AnalyticsContext) {\n return track(\n \"collection_view\",\n {\n collectionId: collection.id,\n ...(collection.id ? { listId: collection.id } : {}),\n ...(collection.title ? { listName: collection.title } : {}),\n },\n context,\n );\n },\n viewCart(cart: AnalyticsCartLike, context?: AnalyticsContext) {\n return track(\n \"view_cart\",\n {\n cartId: cart.id,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n ...(cart.items\n ? {\n lineItems: cart.items.map((item) => ({\n itemId: item.variantId,\n ...(item.variant?.productId ? { productId: item.variant.productId } : {}),\n variantId: item.variantId,\n ...(item.variant?.sku !== undefined ? { sku: item.variant.sku } : {}),\n ...((item.variant?.productTitle ?? item.variant?.title)\n ? {\n itemName: item.variant?.productTitle ?? item.variant?.title ?? null,\n productTitle: item.variant?.productTitle ?? item.variant?.title ?? null,\n }\n : {}),\n ...(item.variant?.title ? { itemVariant: item.variant.title, variantTitle: item.variant.title } : {}),\n quantity: item.quantity,\n unitPrice: item.effectiveUnitPrice.amount,\n price: item.effectiveUnitPrice.amount,\n lineTotal: item.lineTotal.amount,\n })),\n }\n : {}),\n },\n context,\n );\n },\n selectItem(\n product: AnalyticsProductLike,\n options?: {\n variant?: AnalyticsProductVariantLike | null;\n listId?: string;\n listName?: string;\n index?: number;\n },\n context?: AnalyticsContext,\n ) {\n const props: AnalyticsProperties = { productId: product.id };\n const variant =\n product.variants?.find((entry) => entry.id === options?.variant?.id) ??\n options?.variant ??\n product.variants?.[0];\n const variantId = variant?.id;\n if (variantId) props.variantId = variantId;\n if (product.title) {\n props.productTitle = product.title;\n props.itemName = product.title;\n }\n if (variant?.title) {\n props.variantTitle = variant.title;\n props.itemVariant = variant.title;\n }\n if (variant?.sku !== undefined) props.sku = variant.sku;\n if (variant?.price) {\n props.unitPrice = variant.price.amount;\n props.price = variant.price.amount;\n props.currency = variant.price.currency;\n }\n if (options?.listId) props.listId = options.listId;\n if (options?.listName) props.listName = options.listName;\n if (options?.index !== undefined) props.index = options.index;\n const itemCategory = product.primaryCategory?.name ?? product.productType ?? undefined;\n if (itemCategory) props.itemCategory = itemCategory;\n return track(\"select_item\", props, context);\n },\n custom(eventName: string, properties?: AnalyticsProperties, context?: AnalyticsContext) {\n return track(eventName as AnalyticsTrackEventName, properties ?? {}, context);\n },\n } satisfies AnalyticsTrackHelpers) as AnalyticsTrackFn;\n\n const emit: AnalyticsEmitFn = (eventType, properties, context) => {\n void track(eventType as AnalyticsTrackEventName, properties, context);\n };\n\n return {\n operations: {\n consent: consentManager,\n init,\n track: trackFn,\n },\n emit,\n };\n}\n\n/**\n * Builds the canonical `analytics.checkout_completed` event properties from a confirmed purchase payload.\n * This is the single source of truth for how purchase data maps to event property keys.\n */\nexport function buildConfirmedPurchaseEventProperties(purchaseTracking: ConfirmedPurchaseTrackingPayload): {\n orderId: string;\n cartId: string;\n orderTotal: number;\n currency: string;\n numItems: number;\n lineItems: Array<{\n contentId: string;\n itemId: string;\n variantId: string | null;\n productId: string | null;\n sku: string | null;\n productTitle: string;\n variantTitle: string | null;\n quantity: number;\n unitPrice: number;\n lineTotal: number;\n }>;\n} {\n return {\n orderId: purchaseTracking.orderId,\n cartId: purchaseTracking.cartId,\n orderTotal: purchaseTracking.total.amount,\n currency: purchaseTracking.currency,\n numItems: purchaseTracking.numItems,\n lineItems: purchaseTracking.lineItems.map((item) => ({\n contentId: item.contentId,\n itemId: item.contentId,\n variantId: item.variantId,\n productId: item.productId,\n sku: item.sku,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n quantity: item.quantity,\n unitPrice: item.unitPrice.amount,\n lineTotal: item.lineTotal.amount,\n })),\n };\n}\n\nexport function dispatchConfirmedPurchaseBrowserEvent(\n client: StorefrontClientContext,\n purchaseTracking: ConfirmedPurchaseTrackingPayload,\n consentMgr: ConsentManager | null = null,\n): void {\n const trackingAttributionTtlMs = client.config.trackingAttributionTTL;\n const runtimeClient = client as AnalyticsRuntimeClient;\n const trackingRuntime = runtimeClient._analyticsRuntimeConfig ?? client.config.tracking ?? null;\n const resolvedAnalytics =\n runtimeClient._resolvedInitConfig?.analytics ?? buildDefaultResolvedAnalyticsConfig(trackingRuntime);\n if (!trackingRuntime || !resolvedAnalytics.enabled || (trackingRuntime.adapters?.length ?? 0) === 0) {\n return;\n }\n const runtime = trackingRuntime;\n\n function emitDiagnostic(diagnostic: AnalyticsDiagnostic): void {\n try {\n runtime.onDiagnostic?.(diagnostic);\n } catch {\n // Diagnostics are observer-only and must never affect storefront flows.\n }\n }\n\n function scheduleBestEffort(task: () => void | Promise<void>): void {\n Promise.resolve()\n .then(task)\n .catch(() => {\n // Best-effort background tasks must not surface to callers.\n });\n }\n\n async function resolveConsentState(): Promise<AnalyticsConsentState> {\n if (!runtime.resolveConsentState) {\n return consentMgr ? consentMgr.resolveConsentState() : \"unknown\";\n }\n\n try {\n return await runtime.resolveConsentState();\n } catch (error) {\n emitDiagnostic({\n target: \"consent\",\n status: \"error\",\n error: toError(error, \"Failed to resolve tracking consent state\"),\n });\n return \"unknown\";\n }\n }\n\n scheduleBestEffort(async () => {\n const normalizedContext = normalizeEventContext(undefined);\n const consentState = await resolveConsentState();\n const now = new Date();\n const event: AnalyticsBrowserEvent = {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n eventId: purchaseTracking.eventId,\n eventType: \"analytics.checkout_completed\",\n occurredAt: now.toISOString(),\n sessionId: resolveSessionId(now.getTime()),\n visitorId: getOrCreateVisitorId(),\n customerId: parseCustomerIdFromToken(client.getCustomerToken()),\n consentState,\n context: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n path: normalizePath(normalizedContext.path ?? \"/\"),\n },\n referrer: normalizedContext.referrer ?? null,\n utm: buildUtmPayload(normalizedContext, trackingAttributionTtlMs),\n clickIds: buildClickIdsPayload(normalizedContext, trackingAttributionTtlMs),\n device: {\n deviceType: normalizedContext.deviceType ?? \"unknown\",\n deviceOs: normalizedContext.deviceOs ?? null,\n deviceBrowser: normalizedContext.deviceBrowser ?? null,\n },\n properties: buildConfirmedPurchaseEventProperties(purchaseTracking),\n };\n\n dispatchEventToBrowserRuntime(\n runtime,\n event,\n resolvedAnalytics,\n emitDiagnostic,\n scheduleBestEffort,\n consentMgr,\n client.config.debug === true,\n );\n });\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_SESSION_KEY } from \"./storage.ts\";\nimport type { Customer, StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface CustomerData {\n id: string;\n name: string | null;\n email: string;\n emailVerified: boolean;\n}\n\ninterface CustomerRegisterResponse {\n customerRegister: {\n customer: CustomerData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerLoginResponse {\n customerLogin: {\n customer: CustomerData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerPasswordResetRequestResponse {\n customerPasswordResetRequest: {\n success: boolean;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerPasswordResetResponse {\n customerPasswordReset: {\n success: boolean;\n userErrors: UserError[];\n };\n}\n\ninterface MeResponse {\n me: CustomerData | null;\n}\n\nconst CUSTOMER_FRAGMENT = `\n id\n name\n email\n emailVerified\n`;\n\nconst CUSTOMER_REGISTER_MUTATION = `\nmutation CustomerRegister($input: CustomerRegisterInput!) {\n customerRegister(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\n token\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_LOGIN_MUTATION = `\nmutation CustomerLogin($input: CustomerLoginInput!) {\n customerLogin(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\n token\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_PASSWORD_RESET_REQUEST_MUTATION = `\nmutation CustomerPasswordResetRequest($input: CustomerPasswordResetRequestInput!) {\n customerPasswordResetRequest(input: $input) {\n success\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_PASSWORD_RESET_MUTATION = `\nmutation CustomerPasswordReset($input: CustomerPasswordResetInput!) {\n customerPasswordReset(input: $input) {\n success\n userErrors { field message code }\n }\n}\n`;\n\nconst ME_QUERY = `\nquery Me {\n me { ${CUSTOMER_FRAGMENT} }\n}\n`;\n\nfunction mapCustomerData(data: CustomerData): Customer {\n return {\n id: data.id,\n name: data.name,\n email: data.email,\n emailVerified: data.emailVerified,\n };\n}\n\nfunction mapUserErrors(userErrors: UserError[]): ValidationError | null {\n if (userErrors.length === 0) return null;\n const messages = userErrors.map((e) => e.message).join(\"; \");\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\n\n/**\n * Customer auth operations. Note: `logout` and `isLoggedIn` are synchronous\n * (local token storage only) while all other operations are async and return\n * `Promise<Result<...>>`.\n */\nexport interface AuthOperations {\n /**\n * Register a customer account and store the returned auth token when the API returns one.\n *\n * @param input - Registration credentials and optional name.\n * @returns The registered customer and nullable token.\n */\n register(input: {\n email: string;\n password: string;\n name?: string;\n }): Promise<Result<{ customer: Customer; token: string | null }, StorefrontError>>;\n /**\n * Log in an existing customer and store the returned auth token.\n *\n * @param input - Customer login credentials.\n * @returns The authenticated customer and token.\n */\n login(input: {\n email: string;\n password: string;\n }): Promise<Result<{ customer: Customer; token: string }, StorefrontError>>;\n /**\n * Remove the stored customer auth token. Synchronous — no server-side session\n * invalidation occurs; only the local token is cleared.\n */\n logout(): void;\n /**\n * Request a password reset email for a customer account.\n *\n * @param email - Customer email address.\n * @returns Reset request success state.\n */\n requestPasswordReset(email: string): Promise<Result<{ success: boolean }, StorefrontError>>;\n /**\n * Reset a customer password with a reset token.\n *\n * @param input - Reset token and new password.\n * @returns Reset success state.\n */\n resetPassword(input: { token: string; newPassword: string }): Promise<Result<{ success: boolean }, StorefrontError>>;\n /**\n * Fetch the currently authenticated customer.\n *\n * @returns The signed-in customer, or `null` when unauthenticated.\n */\n me(): Promise<Result<Customer | null, StorefrontError>>;\n /**\n * Check whether a customer token is currently stored.\n *\n * @returns `true` when a customer session exists.\n */\n isLoggedIn(): boolean;\n}\n\nexport function createAuthOperations(client: StorefrontClientContext, storage: StorageAdapter): AuthOperations {\n return {\n async register(input) {\n const result = await client.mutate<CustomerRegisterResponse>({\n query: CUSTOMER_REGISTER_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerRegister;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Registration failed\", []));\n }\n\n if (payload.token) {\n storage.set(CUSTOMER_SESSION_KEY, payload.token);\n }\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n async login(input) {\n const result = await client.mutate<CustomerLoginResponse>({\n query: CUSTOMER_LOGIN_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerLogin;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer || !payload.token) {\n return err(new ValidationError(\"Login failed\", []));\n }\n\n storage.set(CUSTOMER_SESSION_KEY, payload.token);\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n logout() {\n storage.remove(CUSTOMER_SESSION_KEY);\n },\n\n async requestPasswordReset(email) {\n const result = await client.mutate<CustomerPasswordResetRequestResponse>({\n query: CUSTOMER_PASSWORD_RESET_REQUEST_MUTATION,\n variables: { input: { email } },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerPasswordResetRequest;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async resetPassword(input) {\n const result = await client.mutate<CustomerPasswordResetResponse>({\n query: CUSTOMER_PASSWORD_RESET_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerPasswordReset;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async me() {\n if (!storage.get(CUSTOMER_SESSION_KEY)) return ok(null);\n\n const result = await client.query<MeResponse>({ query: ME_QUERY }, { cache: false });\n if (result.isErr()) return err(result.error);\n\n return ok(result.value.me ? mapCustomerData(result.value.me) : null);\n },\n\n isLoggedIn() {\n return storage.get(CUSTOMER_SESSION_KEY) !== null;\n },\n };\n}\n","export const CART_ERROR_CODES = {\n required: \"CART_REQUIRED\",\n notFound: \"CART_NOT_FOUND\",\n marketInvalidated: \"CART_MARKET_INVALIDATED\",\n} as const;\n\nexport type CartErrorCode = (typeof CART_ERROR_CODES)[keyof typeof CART_ERROR_CODES];\n\nexport const CART_GONE_ERROR_CODES = [\n CART_ERROR_CODES.required,\n CART_ERROR_CODES.notFound,\n CART_ERROR_CODES.marketInvalidated,\n] as const;\n\nexport type CartGoneErrorCode = (typeof CART_GONE_ERROR_CODES)[number];\n\nexport function isCartGoneErrorCode(code: string | null | undefined): code is CartGoneErrorCode {\n return code != null && (CART_GONE_ERROR_CODES as readonly string[]).includes(code);\n}\n","import type { Collection, Product } from \"./types.ts\";\n\nfunction isAbsoluteUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value);\n}\n\nfunction toOrigin(endpoint: string): string | null {\n try {\n return new URL(endpoint).origin;\n } catch {\n return null;\n }\n}\n\nexport function resolveAssetUrl(url: string, endpoint: string): string {\n if (!url) {\n return url;\n }\n\n if (isAbsoluteUrl(url)) {\n return url;\n }\n\n const origin = toOrigin(endpoint);\n if (!origin) {\n return url;\n }\n\n try {\n return new URL(url, origin).toString();\n } catch {\n return url;\n }\n}\n\nexport function normalizeProductAssetUrls(product: Product, endpoint: string): Product {\n return {\n ...product,\n media: product.media.map((media) => ({\n ...media,\n url: resolveAssetUrl(media.url, endpoint),\n previewUrl: resolveAssetUrl(media.previewUrl, endpoint),\n })),\n variants: product.variants.map((variant) => ({\n ...variant,\n image: variant.image\n ? {\n ...variant.image,\n url: resolveAssetUrl(variant.image.url, endpoint),\n previewUrl: resolveAssetUrl(variant.image.previewUrl, endpoint),\n }\n : null,\n })),\n };\n}\n\nexport function normalizeCollectionAssetUrls(collection: Collection, endpoint: string): Collection {\n return {\n ...collection,\n imageAsset: collection.imageAsset\n ? {\n ...collection.imageAsset,\n url: resolveAssetUrl(collection.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(collection.imageAsset.previewUrl, endpoint),\n }\n : null,\n };\n}\n","import { CART_GONE_ERROR_CODES, isCartGoneErrorCode } from \"@ekomerc/cart-contract\";\nimport { StateError, ValidationError } from \"./errors.ts\";\nimport type { Address, Cart, CartStatus, Money, ProductVariant } from \"./types.ts\";\nimport { resolveAssetUrl } from \"./url.ts\";\n\nexport interface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\nexport interface CartItemData {\n id: string;\n variantId: string;\n quantity: number;\n priceAtAdd: Money;\n effectiveUnitPrice: Money;\n lineTotal: Money;\n taxAmount: Money;\n variant:\n | (Pick<\n ProductVariant,\n | \"id\"\n | \"productId\"\n | \"productTitle\"\n | \"title\"\n | \"sku\"\n | \"price\"\n | \"compareAtPrice\"\n | \"weight\"\n | \"weightUnit\"\n | \"requiresShipping\"\n | \"availableForSale\"\n | \"backInStockSubscriptionAvailable\"\n | \"quantity\"\n | \"selectedOptions\"\n | \"image\"\n | \"isOnSale\"\n | \"quantityPricing\"\n > & {})\n | null;\n}\n\nexport interface AppliedPromoCodeData {\n code: string;\n discountType: string;\n discountAmount: Money;\n description: string;\n}\n\nexport interface AppliedDiscountData {\n promotionId: string;\n discountClass: string;\n discountType: string;\n discountAmount: Money;\n description: string;\n isAutomatic: boolean;\n}\n\nexport interface CartMarketData {\n id: string;\n slug: string;\n currency: string;\n}\n\nexport interface CartData {\n id: string;\n token: string;\n status: CartStatus;\n items: CartItemData[];\n totalItems: number;\n totalPrice: Money;\n taxTotal: Money;\n shippingTotal: Money;\n total: Money;\n discountTotal: Money;\n appliedPromoCode: AppliedPromoCodeData | null;\n appliedDiscounts: AppliedDiscountData[];\n customerEmail: string | null;\n customerPhone: string | null;\n shippingAddress: Address | null;\n billingAddress: Address | null;\n paymentMethod: string | null;\n shippingRateId: string | null;\n notes: string | null;\n checkoutStartedAt?: string | null;\n checkoutExpiresAt?: string | null;\n createdAt: string;\n updatedAt: string;\n market?: CartMarketData | null;\n}\n\nexport const CART_FRAGMENT = `\n id\n token\n status\n items {\n id\n variantId\n quantity\n priceAtAdd { amount currency }\n effectiveUnitPrice { amount currency }\n lineTotal { amount currency }\n taxAmount { amount currency }\n variant {\n id\n productId\n productTitle\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions { id value position }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing { minQuantity price { amount currency } }\n }\n }\n totalItems\n totalPrice { amount currency }\n taxTotal { amount currency }\n shippingTotal { amount currency }\n total { amount currency }\n discountTotal { amount currency }\n appliedPromoCode {\n code\n discountType\n discountAmount { amount currency }\n description\n }\n appliedDiscounts {\n promotionId\n discountClass\n discountType\n discountAmount { amount currency }\n description\n isAutomatic\n }\n customerEmail\n customerPhone\n shippingAddress\n billingAddress\n paymentMethod\n shippingRateId\n notes\n checkoutStartedAt\n checkoutExpiresAt\n createdAt\n updatedAt\n market {\n id\n slug\n currency\n }\n`;\n\nexport function mapCartData(data: CartData, endpoint: string): Cart {\n return {\n id: data.id,\n token: data.token,\n status: data.status,\n items: data.items.map((item) => ({\n id: item.id,\n variantId: item.variantId,\n quantity: item.quantity,\n priceAtAdd: item.priceAtAdd,\n effectiveUnitPrice: item.effectiveUnitPrice,\n lineTotal: item.lineTotal,\n taxAmount: item.taxAmount,\n variant: item.variant\n ? {\n ...item.variant,\n image: item.variant.image\n ? {\n ...item.variant.image,\n url: resolveAssetUrl(item.variant.image.url, endpoint),\n previewUrl: resolveAssetUrl(item.variant.image.previewUrl, endpoint),\n }\n : null,\n }\n : null,\n })),\n totalItems: data.totalItems,\n totalPrice: data.totalPrice,\n taxTotal: data.taxTotal,\n shippingTotal: data.shippingTotal,\n total: data.total,\n discountTotal: data.discountTotal,\n appliedPromoCode: data.appliedPromoCode,\n appliedDiscounts: data.appliedDiscounts,\n customerEmail: data.customerEmail,\n customerPhone: data.customerPhone,\n shippingAddress: data.shippingAddress,\n billingAddress: data.billingAddress,\n paymentMethod: data.paymentMethod,\n shippingRateId: data.shippingRateId,\n notes: data.notes,\n checkoutStartedAt: data.checkoutStartedAt ?? null,\n checkoutExpiresAt: data.checkoutExpiresAt ?? null,\n createdAt: data.createdAt,\n updatedAt: data.updatedAt,\n market: data.market ?? null,\n };\n}\n\nexport function mapUserErrors(\n userErrors: UserError[],\n stateErrorCodes: string[] = [],\n cartStatus: CartStatus | null = null,\n): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n const stateErrorCodeSet = new Set(stateErrorCodes);\n const stateError = userErrors.find((e) => e.code !== null && stateErrorCodeSet.has(e.code));\n\n if (stateError) {\n return new StateError(messages, cartStatus ?? \"\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message, code: e.code })),\n );\n}\n\nexport const CART_GONE_CODES = CART_GONE_ERROR_CODES;\n\n/**\n * True when an error indicates the current cart is gone and should be discarded so the\n * caller can start fresh. Keys off the machine-readable userError code, never message text.\n */\nexport function isCartGoneError(error: unknown): boolean {\n return error instanceof ValidationError && error.userErrors.some((e) => isCartGoneErrorCode(e.code));\n}\n\nexport interface CartQueryResponse {\n cart: CartData | null;\n}\n\nexport const CART_QUERY = `\nquery Cart {\n cart {\n ${CART_FRAGMENT}\n }\n}\n`;\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type CartData, isCartGoneError, mapCartData, mapUserErrors, type UserError } from \"./cart-shared.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Cart, CartStatus, StorefrontClientContext } from \"./types.ts\";\n\ninterface CartMutationPayload {\n cart: CartData | null;\n userErrors: UserError[];\n}\n\ninterface CartMutationRunnerOptions {\n client: StorefrontClientContext;\n cache: CartSnapshotCache;\n}\n\ninterface RunCartMutationOptions {\n execute(): Promise<Result<CartMutationPayload, StorefrontError>>;\n missingCartMessage: string;\n stateErrorCodes?: string[];\n}\n\ninterface RunRecoveringAddMutationOptions extends RunCartMutationOptions {\n hasCartToken(): boolean;\n createCart(): Promise<Result<Cart, StorefrontError>>;\n}\n\ntype CartMutationOutcome =\n | { status: \"ok\"; cart: Cart }\n | { status: \"gone\"; error: StorefrontError }\n | { status: \"error\"; error: StorefrontError };\n\nexport interface CartMutationRunner {\n discardCart(): void;\n clearIfGone(error: StorefrontError): boolean;\n runCartMutation(options: RunCartMutationOptions): Promise<Result<Cart, StorefrontError>>;\n runRecoveringAddMutation(options: RunRecoveringAddMutationOptions): Promise<Result<Cart, StorefrontError>>;\n mapUserError(\n userErrors: UserError[],\n stateErrorCodes?: string[],\n cartStatus?: CartStatus | null,\n ): StorefrontError | null;\n}\n\nexport function createCartMutationRunner({ client, cache }: CartMutationRunnerOptions): CartMutationRunner {\n function discardCart(): void {\n client.clearCartToken();\n cache.clear();\n }\n\n function mapUserError(\n userErrors: UserError[],\n stateErrorCodes: string[] = [],\n cartStatus: CartStatus | null = null,\n ): StorefrontError | null {\n return mapUserErrors(userErrors, stateErrorCodes, cartStatus);\n }\n\n function clearIfGone(error: StorefrontError): boolean {\n if (!isCartGoneError(error)) {\n return false;\n }\n discardCart();\n return true;\n }\n\n async function executeCartMutation(options: RunCartMutationOptions): Promise<CartMutationOutcome> {\n const result = await options.execute();\n if (result.isErr()) {\n return { status: \"error\", error: result.error };\n }\n\n const payload = result.value;\n const userError = mapUserError(payload.userErrors, options.stateErrorCodes, payload.cart?.status ?? null);\n if (userError) {\n if (isCartGoneError(userError)) {\n return { status: \"gone\", error: userError };\n }\n return { status: \"error\", error: userError };\n }\n\n if (!payload.cart) {\n return { status: \"error\", error: new NotFoundError(options.missingCartMessage) };\n }\n\n return { status: \"ok\", cart: cache.set(mapCartData(payload.cart, client.config.endpoint)) };\n }\n\n async function runCartMutation(options: RunCartMutationOptions): Promise<Result<Cart, StorefrontError>> {\n const outcome = await executeCartMutation(options);\n if (outcome.status === \"ok\") {\n return ok(outcome.cart);\n }\n if (outcome.status === \"gone\") {\n clearIfGone(outcome.error);\n }\n return err(outcome.error);\n }\n\n async function runRecoveringAddMutation(\n options: RunRecoveringAddMutationOptions,\n ): Promise<Result<Cart, StorefrontError>> {\n if (options.hasCartToken()) {\n const existing = await executeCartMutation(options);\n if (existing.status === \"ok\") {\n return ok(existing.cart);\n }\n if (existing.status === \"error\") {\n return err(existing.error);\n }\n }\n\n discardCart();\n const created = await options.createCart();\n if (created.isErr()) {\n return err(created.error);\n }\n\n const retry = await executeCartMutation(options);\n if (retry.status === \"ok\") {\n return ok(retry.cart);\n }\n if (retry.status === \"gone\") {\n clearIfGone(retry.error);\n }\n return err(retry.error);\n }\n\n return {\n discardCart,\n clearIfGone,\n runCartMutation,\n runRecoveringAddMutation,\n mapUserError,\n };\n}\n","import { CART_QUERY, type CartQueryResponse, mapCartData } from \"./cart-shared.ts\";\nimport { CART_SESSION_KEY } from \"./storage.ts\";\nimport type { Cart, StorefrontClientContext } from \"./types.ts\";\n\nexport interface CartSnapshotCache {\n get(): Cart | null;\n set(cart: Cart): Cart;\n clear(): void;\n loadSnapshot(): Promise<Cart | null>;\n}\n\nexport function createCartSnapshotCache(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null },\n): CartSnapshotCache {\n let lastKnownCart: Cart | null = null;\n\n return {\n get() {\n return lastKnownCart;\n },\n set(cart: Cart): Cart {\n lastKnownCart = cart;\n return cart;\n },\n clear() {\n lastKnownCart = null;\n },\n async loadSnapshot(): Promise<Cart | null> {\n if (lastKnownCart) return lastKnownCart;\n\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n lastKnownCart = null;\n return null;\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n if (result.isErr()) return null;\n if (!result.value.cart) {\n lastKnownCart = null;\n return null;\n }\n\n lastKnownCart = mapCartData(result.value.cart, client.config.endpoint);\n return lastKnownCart;\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport {\n CART_FRAGMENT,\n CART_QUERY,\n type CartData,\n type CartQueryResponse,\n mapCartData,\n mapUserErrors,\n type UserError,\n} from \"./cart-shared.ts\";\nimport { createCartMutationRunner } from \"./cart-mutation-runner.ts\";\nimport { createCartSnapshotCache, type CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { CART_SESSION_KEY } from \"./storage.ts\";\nimport { captureLandingTrackingAttribution } from \"./tracking-attribution.ts\";\nimport type { AnalyticsProperties } from \"./tracking-runtime.ts\";\nimport type { Cart, CartItem, StorefrontClientContext } from \"./types.ts\";\n\ninterface CartCreateResponse {\n cartCreate: {\n cart: CartData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemAddResponse {\n cartItemAdd: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemUpdateResponse {\n cartItemUpdate: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemRemoveResponse {\n cartItemRemove: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartClearResponse {\n cartClear: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nconst CART_CREATE_MUTATION = `\nmutation CartCreate {\n cartCreate {\n cart {\n ${CART_FRAGMENT}\n }\n token\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_ADD_MUTATION = `\nmutation CartItemAdd($input: CartItemAddInput!) {\n cartItemAdd(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_UPDATE_MUTATION = `\nmutation CartItemUpdate($input: CartItemUpdateInput!) {\n cartItemUpdate(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_REMOVE_MUTATION = `\nmutation CartItemRemove($input: CartItemRemoveInput!) {\n cartItemRemove(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_CLEAR_MUTATION = `\nmutation CartClear {\n cartClear {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_PROMO_CODE_APPLY_MUTATION = `\nmutation CartPromoCodeApply($input: CartPromoCodeApplyInput!) {\n cartPromoCodeApply(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_PROMO_CODE_REMOVE_MUTATION = `\nmutation CartPromoCodeRemove {\n cartPromoCodeRemove {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\ninterface CartPromoCodeApplyResponse {\n cartPromoCodeApply: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartPromoCodeRemoveResponse {\n cartPromoCodeRemove: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nexport interface CartOperations {\n /**\n * Load the current cart from the stored cart token.\n *\n * @returns The current cart, or `null` when no cart exists.\n */\n get(): Promise<Result<Cart | null, StorefrontError>>;\n /**\n * Create a new active cart and persist its token.\n *\n * @returns The newly created cart.\n */\n create(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Add a product variant to the active cart.\n *\n * @param variantId - Product variant UUID.\n * @param quantity - Quantity to add.\n * @returns The updated cart.\n */\n addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n /**\n * Update the quantity of an existing cart item.\n *\n * @param variantId - Product variant UUID.\n * @param quantity - New quantity for the item.\n * @returns The updated cart.\n */\n updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove a product variant from the cart.\n *\n * @param variantId - Product variant UUID.\n * @returns The updated cart.\n */\n removeItem(variantId: string): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove all items from the active cart.\n *\n * @returns The emptied cart.\n */\n clear(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Apply a promo code to the active cart.\n *\n * @param code - Promo code to validate and apply.\n * @returns The updated cart with discount data.\n */\n applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove the currently applied promo code from the cart.\n *\n * @returns The updated cart.\n */\n removePromoCode(): Promise<Result<Cart, StorefrontError>>;\n}\n\nfunction buildCartItemProps(cart: Cart, item: CartItem | undefined, quantity: number): AnalyticsProperties {\n const props: AnalyticsProperties = {\n cartId: cart.id,\n quantity,\n itemsCount: cart.totalItems,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n };\n if (item) {\n const itemName =\n (item.variant as (typeof item.variant & { productTitle?: string | null }) | null)?.productTitle ??\n item.variant?.title ??\n undefined;\n const itemVariant = item.variant?.title ?? undefined;\n const unitPrice = item.effectiveUnitPrice.amount;\n const lineTotal = unitPrice * quantity;\n const lineItem: AnalyticsProperties = {\n itemId: item.variantId,\n variantId: item.variantId,\n quantity,\n unitPrice,\n price: unitPrice,\n lineTotal,\n };\n\n props.variantId = item.variantId;\n if (item.variant?.productId) {\n props.productId = item.variant.productId;\n lineItem.productId = item.variant.productId;\n }\n if (item.variant) {\n if (itemVariant !== undefined) {\n props.itemVariant = itemVariant;\n props.variantTitle = itemVariant;\n }\n props.sku = item.variant.sku;\n props.unitPrice = unitPrice;\n props.price = unitPrice;\n if (item.variant.sku !== undefined) {\n lineItem.sku = item.variant.sku;\n }\n if (itemVariant !== undefined) {\n lineItem.itemVariant = itemVariant;\n lineItem.variantTitle = itemVariant;\n }\n }\n if (itemName) {\n props.itemName = itemName;\n props.productTitle = itemName;\n lineItem.itemName = itemName;\n lineItem.productTitle = itemName;\n }\n props.itemId = item.variantId;\n props.lineTotal = lineTotal;\n props.lineItems = [lineItem];\n }\n return props;\n}\n\nexport function createCartOperations(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n emit?: AnalyticsEmitFn,\n snapshotCache?: CartSnapshotCache,\n): CartOperations {\n const cache = snapshotCache ?? createCartSnapshotCache(client, storage);\n const runner = createCartMutationRunner({ client, cache });\n\n function getTrackingAttribution() {\n return (\n captureLandingTrackingAttribution({\n ttlMs: client.config.trackingAttributionTTL,\n }) ?? undefined\n );\n }\n\n const operations: CartOperations = {\n async get(): Promise<Result<Cart | null, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n cache.clear();\n return ok(null);\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n if (result.isErr()) return err(result.error);\n if (!result.value.cart) {\n runner.discardCart();\n return ok(null);\n }\n return ok(cache.set(mapCartData(result.value.cart, client.config.endpoint)));\n },\n\n async create(): Promise<Result<Cart, StorefrontError>> {\n const result = await client.mutate<CartCreateResponse>({\n query: CART_CREATE_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart || !payload.token) {\n return err(new NotFoundError(\"Failed to create cart\"));\n }\n\n storage.set(CART_SESSION_KEY, payload.token);\n return ok(cache.set(mapCartData(payload.cart, client.config.endpoint)));\n },\n\n async addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const result = await runner.runRecoveringAddMutation({\n hasCartToken: () => storage.get(CART_SESSION_KEY) !== null,\n createCart: () => operations.create(),\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemAddResponse>({\n query: CART_ITEM_ADD_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemAdd);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit) {\n const item = cart.items.find((i) => i.variantId === variantId);\n emit(\"analytics.add_to_cart\", buildCartItemProps(cart, item, quantity));\n }\n return ok(cart);\n },\n\n async updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n const previousItem = previousCart?.items.find((i) => i.variantId === variantId);\n const previousQuantity = previousItem?.quantity;\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemUpdateResponse>({\n query: CART_ITEM_UPDATE_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemUpdate);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit && previousQuantity !== undefined) {\n const delta = quantity - previousQuantity;\n if (delta > 0) {\n const item = cart.items.find((i) => i.variantId === variantId);\n emit(\"analytics.add_to_cart\", buildCartItemProps(cart, item, delta));\n } else if (delta < 0) {\n const item = cart.items.find((i) => i.variantId === variantId) ?? previousItem;\n emit(\"analytics.remove_from_cart\", buildCartItemProps(cart, item, Math.abs(delta)));\n }\n }\n return ok(cart);\n },\n\n async removeItem(variantId: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n const previousItem = previousCart?.items.find((i) => i.variantId === variantId);\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemRemoveResponse>({\n query: CART_ITEM_REMOVE_MUTATION,\n variables: {\n input: {\n variantId,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemRemove);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit && previousItem) {\n emit(\"analytics.remove_from_cart\", buildCartItemProps(cart, previousItem, previousItem.quantity));\n }\n return ok(cart);\n },\n\n async clear(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartClearResponse>({\n query: CART_CLEAR_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartClear);\n },\n });\n\n return result;\n },\n\n async applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartPromoCodeApplyResponse>({\n query: CART_PROMO_CODE_APPLY_MUTATION,\n variables: { input: { code } },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartPromoCodeApply);\n },\n });\n\n return result;\n },\n\n async removePromoCode(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartPromoCodeRemoveResponse>({\n query: CART_PROMO_CODE_REMOVE_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartPromoCodeRemove);\n },\n });\n\n return result;\n },\n };\n\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Category, FlatCategory, PaginatedResult, Product, StorefrontClientContext } from \"./types.ts\";\nimport { normalizeProductAssetUrls, resolveAssetUrl } from \"./url.ts\";\n\nexport interface CategoryProductsOptions {\n first?: number;\n after?: string;\n includeDescendants?: boolean;\n}\n\ninterface CategoryImage {\n url: string;\n previewUrl: string;\n altText: string | null;\n width: number | null;\n height: number | null;\n}\n\ninterface RawCategory {\n id: string;\n name: string;\n handle: string;\n description: string | null;\n metaTitle: string | null;\n metaDescription: string | null;\n imageAsset: CategoryImage | null;\n parent: RawCategory | null;\n children: RawCategory[];\n ancestors: RawCategory[];\n productCount: number;\n}\n\ninterface CategoriesTreeQueryResponse {\n storefrontCategories: RawCategory[];\n}\n\ninterface CategoryQueryResponse {\n storefrontCategory: RawCategory | null;\n}\n\ninterface ProductEdge {\n node: Product;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CategoryWithProducts {\n id: string;\n products: ProductConnection;\n}\n\ninterface CategoryProductsQueryResponse {\n storefrontCategory: CategoryWithProducts | null;\n}\n\nconst CATEGORY_FIELDS = `\n id\n name\n handle\n description\n metaTitle\n metaDescription\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n productCount\n`;\n\nconst CATEGORIES_TREE_QUERY = `\nquery CategoriesTree {\n storefrontCategories {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n }\n }\n }\n }\n }\n}\n`;\n\nconst CATEGORY_BY_ID_QUERY = `\nquery CategoryById($id: ID!) {\n storefrontCategory(id: $id) {\n ${CATEGORY_FIELDS}\n parent {\n ${CATEGORY_FIELDS}\n }\n children {\n ${CATEGORY_FIELDS}\n }\n ancestors {\n ${CATEGORY_FIELDS}\n }\n }\n}\n`;\n\nconst CATEGORY_BY_HANDLE_QUERY = `\nquery CategoryByHandle($handle: String!) {\n storefrontCategory(handle: $handle) {\n ${CATEGORY_FIELDS}\n parent {\n ${CATEGORY_FIELDS}\n }\n children {\n ${CATEGORY_FIELDS}\n }\n ancestors {\n ${CATEGORY_FIELDS}\n }\n }\n}\n`;\n\nconst CATEGORY_PRODUCTS_BY_ID_QUERY = `\nquery CategoryProductsById($id: ID!, $first: Int, $after: String, $includeDescendants: Boolean) {\n storefrontCategory(id: $id) {\n id\n products(first: $first, after: $after, includeDescendants: $includeDescendants) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nconst CATEGORY_PRODUCTS_BY_HANDLE_QUERY = `\nquery CategoryProductsByHandle($handle: String!, $first: Int, $after: String, $includeDescendants: Boolean) {\n storefrontCategory(handle: $handle) {\n id\n products(first: $first, after: $after, includeDescendants: $includeDescendants) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nfunction mapRawCategory(raw: RawCategory, endpoint: string): Category {\n return {\n id: raw.id,\n name: raw.name,\n handle: raw.handle,\n description: raw.description,\n metaTitle: raw.metaTitle,\n metaDescription: raw.metaDescription,\n imageAsset: raw.imageAsset\n ? {\n url: resolveAssetUrl(raw.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(raw.imageAsset.previewUrl, endpoint),\n altText: raw.imageAsset.altText,\n width: raw.imageAsset.width,\n height: raw.imageAsset.height,\n }\n : null,\n parent: raw.parent ? mapRawCategory(raw.parent, endpoint) : null,\n children: raw.children?.map((child) => mapRawCategory(child, endpoint)) ?? [],\n ancestors: raw.ancestors?.map((ancestor) => mapRawCategory(ancestor, endpoint)) ?? [],\n productCount: raw.productCount,\n };\n}\n\nfunction flattenTree(categories: Category[], parentId: string | null, depth: number): FlatCategory[] {\n const result: FlatCategory[] = [];\n for (const cat of categories) {\n result.push({\n id: cat.id,\n name: cat.name,\n handle: cat.handle,\n description: cat.description,\n metaTitle: cat.metaTitle,\n metaDescription: cat.metaDescription,\n imageUrl: cat.imageAsset?.url ?? null,\n parentId,\n depth,\n hasChildren: cat.children.length > 0,\n productCount: cat.productCount,\n });\n result.push(...flattenTree(cat.children, cat.id, depth + 1));\n }\n return result;\n}\n\nexport interface CategoriesOperations {\n listAll(): Promise<Result<FlatCategory[], StorefrontError>>;\n /**\n * Fetch the nested storefront category tree.\n *\n * @returns Categories with their child hierarchy.\n */\n tree(): Promise<Result<Category[], StorefrontError>>;\n /**\n * Fetch categories flattened into a parent-aware list.\n *\n * @returns Flat categories with depth and parent metadata.\n */\n flat(): Promise<Result<FlatCategory[], StorefrontError>>;\n /**\n * Fetch a single category by UUID.\n *\n * @param id - Category UUID.\n * @returns The matching category.\n */\n byId(id: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch a single category by handle.\n *\n * @param handle - Category handle.\n * @returns The matching category.\n */\n byHandle(handle: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch a single category by handle.\n *\n * @param handle - Category handle.\n * @returns The matching category.\n */\n get(handle: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch products assigned to a category.\n *\n * @param id - Category UUID.\n * @param options - Pagination and descendant-inclusion options.\n * @returns Paginated products for the category.\n */\n getProductsById(\n id: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n getProductsByHandle(\n handle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCategoriesOperations(client: StorefrontClientContext): CategoriesOperations {\n const operations: CategoriesOperations = {\n listAll: () => operations.flat(),\n async tree(): Promise<Result<Category[], StorefrontError>> {\n const result = await client.query<CategoriesTreeQueryResponse>({\n query: CATEGORIES_TREE_QUERY,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(result.value.storefrontCategories.map((category) => mapRawCategory(category, client.config.endpoint)));\n },\n\n async flat(): Promise<Result<FlatCategory[], StorefrontError>> {\n const result = await client.query<CategoriesTreeQueryResponse>({\n query: CATEGORIES_TREE_QUERY,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const tree = result.value.storefrontCategories.map((category) =>\n mapRawCategory(category, client.config.endpoint),\n );\n return ok(flattenTree(tree, null, 0));\n },\n\n async byId(id: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${id}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async getProductsById(\n id: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CategoryProductsQueryResponse>({\n query: CATEGORY_PRODUCTS_BY_ID_QUERY,\n variables: {\n id,\n first: options?.first,\n after: options?.after,\n ...(options?.includeDescendants !== undefined && { includeDescendants: options.includeDescendants }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${id}`));\n }\n\n const connection = result.value.storefrontCategory.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async getProductsByHandle(\n handle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CategoryProductsQueryResponse>({\n query: CATEGORY_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n handle,\n first: options?.first,\n after: options?.after,\n ...(options?.includeDescendants !== undefined && { includeDescendants: options.includeDescendants }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n const connection = result.value.storefrontCategory.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n };\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type ConfirmedPurchaseTrackingPayload, dispatchConfirmedPurchaseBrowserEvent } from \"./analytics.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport { NotFoundError, StorefrontError } from \"./errors.ts\";\nimport { CART_SESSION_KEY, getCheckoutLeadDispatchKey } from \"./storage.ts\";\nimport type { StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\nconst CHECKOUT_PURCHASE_DISPATCH_IDS_KEY = \"ekomerc_checkout_purchase_dispatch_ids\";\nconst PAYMENT_RETURN_STORAGE_KEY = \"ekomerc_checkout_payment_return\";\nconst MAX_STORED_PURCHASE_DISPATCH_IDS = 20;\nexport const PAYMENT_RETURN_TTL_MS = 24 * 60 * 60 * 1000;\n\nconst PAYMENT_REF_PATTERN = /^[23456789ABCDEFGHJKMNPQRSTUVWXYZ]{8}$/;\nconst PAYMENT_RETURN_PHASES = [\"redirecting\", \"session_unavailable\", \"checking\", \"pending\", \"failed\"] as const;\n\nexport type PaymentReturnPhase = (typeof PAYMENT_RETURN_PHASES)[number];\n\nexport interface PaymentRecoveryRecord {\n storeId: string;\n paymentRef: string;\n orderNumber: string | null;\n convertedCartToken: string | null;\n tracking: ConfirmedPurchaseTrackingPayload | null;\n phase: PaymentReturnPhase;\n createdAt: number;\n}\n\ninterface PaymentLifecycleContext {\n client: StorefrontClientContext;\n storage: StorageAdapter;\n cache: CartSnapshotCache;\n consentManager: ConsentManager | null;\n}\n\ninterface StoreIdentityResponse {\n store: { id: string } | null;\n}\n\nconst STORE_IDENTITY_QUERY = `\nquery PaymentLifecycleStoreIdentity {\n store { id }\n}\n`;\n\nexport function isPaymentRef(value: string): boolean {\n return PAYMENT_REF_PATTERN.test(value);\n}\n\nexport async function resolvePaymentStoreId(\n client: StorefrontClientContext,\n signal?: AbortSignal,\n): Promise<Result<string, StorefrontError>> {\n const result = await client.query<StoreIdentityResponse>({ query: STORE_IDENTITY_QUERY }, { cache: true, signal });\n if (result.isErr()) return err(result.error);\n if (!result.value.store?.id) return err(new NotFoundError(\"Store not found\"));\n return ok(result.value.store.id);\n}\n\nfunction isTrackingPayload(value: unknown): value is ConfirmedPurchaseTrackingPayload {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<ConfirmedPurchaseTrackingPayload>;\n return typeof candidate.orderId === \"string\" && candidate.orderId.length > 0;\n}\n\nfunction parseRecoveryRecord(raw: string): PaymentRecoveryRecord | null {\n try {\n const value: unknown = JSON.parse(raw);\n if (!value || typeof value !== \"object\") return null;\n const candidate = value as Partial<PaymentRecoveryRecord>;\n if (\n typeof candidate.storeId !== \"string\" ||\n typeof candidate.paymentRef !== \"string\" ||\n !isPaymentRef(candidate.paymentRef) ||\n (candidate.orderNumber !== null && typeof candidate.orderNumber !== \"string\") ||\n (candidate.convertedCartToken !== null && typeof candidate.convertedCartToken !== \"string\") ||\n (candidate.tracking !== null && !isTrackingPayload(candidate.tracking)) ||\n !PAYMENT_RETURN_PHASES.includes(candidate.phase as PaymentReturnPhase) ||\n typeof candidate.createdAt !== \"number\" ||\n !Number.isFinite(candidate.createdAt)\n ) {\n return null;\n }\n return candidate as PaymentRecoveryRecord;\n } catch {\n return null;\n }\n}\n\nfunction storageError(action: string, cause: unknown): StorefrontError {\n return new StorefrontError(`Could not ${action} payment recovery state`, \"STORAGE_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n });\n}\n\n/** Keeps pending attempts recoverable; a new cart supersedes a terminal failed attempt. */\nexport function readPaymentRecovery(\n storage: StorageAdapter,\n storeId: string,\n now = Date.now(),\n): Result<PaymentRecoveryRecord | null, StorefrontError> {\n let raw: string | null;\n let activeCartToken: string | null;\n try {\n raw = storage.get(PAYMENT_RETURN_STORAGE_KEY);\n activeCartToken = storage.get(CART_SESSION_KEY);\n } catch (cause) {\n return err(storageError(\"read\", cause));\n }\n if (!raw) return ok(null);\n\n const record = parseRecoveryRecord(raw);\n if (!record || now - record.createdAt > PAYMENT_RETURN_TTL_MS || record.createdAt > now) {\n clearPaymentRecovery(storage);\n return ok(null);\n }\n if (record.storeId !== storeId) return ok(null);\n if (record.phase === \"failed\" && activeCartToken && activeCartToken !== record.convertedCartToken) {\n clearPaymentRecovery(storage);\n return ok(null);\n }\n return ok(record);\n}\n\nexport function paymentRecoveryExists(storage: StorageAdapter): Result<boolean, StorefrontError> {\n try {\n return ok(storage.get(PAYMENT_RETURN_STORAGE_KEY) !== null);\n } catch (cause) {\n return err(storageError(\"read\", cause));\n }\n}\n\nexport function persistPaymentRecovery(\n storage: StorageAdapter,\n record: PaymentRecoveryRecord,\n): Result<void, StorefrontError> {\n const serialized = JSON.stringify(record);\n try {\n storage.set(PAYMENT_RETURN_STORAGE_KEY, serialized);\n if (storage.get(PAYMENT_RETURN_STORAGE_KEY) !== serialized) {\n return err(storageError(\"persist\", undefined));\n }\n } catch (cause) {\n return err(storageError(\"persist\", cause));\n }\n return ok(undefined);\n}\n\nexport function clearPaymentRecovery(storage: StorageAdapter): void {\n try {\n storage.remove(PAYMENT_RETURN_STORAGE_KEY);\n } catch {\n // Dismissal is intentionally best-effort because the public API is synchronous.\n }\n}\n\nfunction readHandledPurchaseDispatchIds(storage: StorageAdapter): string[] {\n const raw = storage.get(CHECKOUT_PURCHASE_DISPATCH_IDS_KEY);\n if (!raw) return [];\n\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed)\n ? parsed.filter((value): value is string => typeof value === \"string\" && value.length > 0)\n : [];\n } catch {\n return [];\n }\n}\n\nfunction dispatchPurchase(\n context: PaymentLifecycleContext,\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null,\n): void {\n if (!purchaseTracking) return;\n\n const tracking = { ...purchaseTracking, eventId: purchaseTracking.orderId };\n const handledIds = readHandledPurchaseDispatchIds(context.storage);\n if (handledIds.includes(tracking.eventId)) return;\n\n context.storage.set(\n CHECKOUT_PURCHASE_DISPATCH_IDS_KEY,\n JSON.stringify(\n [tracking.eventId, ...handledIds.filter((id) => id !== tracking.eventId)].slice(\n 0,\n MAX_STORED_PURCHASE_DISPATCH_IDS,\n ),\n ),\n );\n dispatchConfirmedPurchaseBrowserEvent(context.client, tracking, context.consentManager);\n}\n\nfunction clearConvertedCart(context: PaymentLifecycleContext, convertedCartToken: string | null): void {\n if (!convertedCartToken) return;\n context.storage.remove(getCheckoutLeadDispatchKey(convertedCartToken));\n if (context.storage.get(CART_SESSION_KEY) !== convertedCartToken) return;\n context.storage.remove(CART_SESSION_KEY);\n context.cache.clear();\n}\n\nexport function finalizeNonRedirectPayment(\n context: PaymentLifecycleContext,\n convertedCartToken: string,\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null,\n): void {\n clearConvertedCart(context, convertedCartToken);\n dispatchPurchase(context, purchaseTracking);\n}\n\nexport function finalizeRedirectPayment(context: PaymentLifecycleContext, record: PaymentRecoveryRecord): void {\n clearConvertedCart(context, record.convertedCartToken);\n dispatchPurchase(context, record.tracking);\n clearPaymentRecovery(context.storage);\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type {\n AnalyticsEmitFn,\n AnalyticsProperties,\n CheckoutStep,\n ConfirmedPurchaseTrackingPayload,\n} from \"./analytics.ts\";\nimport { createCartMutationRunner } from \"./cart-mutation-runner.ts\";\nimport { CART_FRAGMENT, type CartData, type UserError } from \"./cart-shared.ts\";\nimport { type CartSnapshotCache, createCartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport { NotFoundError, StateError, StorefrontError } from \"./errors.ts\";\nimport { finalizeNonRedirectPayment, persistPaymentRecovery, resolvePaymentStoreId } from \"./payment-lifecycle.ts\";\nimport { CART_SESSION_KEY, getCheckoutLeadDispatchKey } from \"./storage.ts\";\nimport type {\n Address,\n Cart,\n CartStatus,\n CheckoutCompletion,\n CheckoutData,\n CheckoutQuote,\n Money,\n Order,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ntype PaymentAction =\n | { kind: \"none\"; redirectUrl: null; paymentRef: null }\n | { kind: \"instructions\"; redirectUrl: null; paymentRef: null }\n | { kind: \"redirect\"; redirectUrl: string; paymentRef: string }\n | { kind: \"redirect_pending\"; redirectUrl: null; paymentRef: string };\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: Money;\n totalPrice: Money;\n taxAmount: Money;\n}\n\ninterface OrderData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n shippingAddress: unknown;\n billingAddress: unknown;\n subtotal: Money;\n shippingTotal: Money;\n shippingTaxAmount: Money;\n discountTotal: Money;\n taxTotal: Money;\n total: Money;\n note: string | null;\n items: OrderItemData[];\n createdAt: string;\n}\n\ninterface CheckoutStartResponse {\n checkoutStart: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CheckoutUpdateResponse {\n checkoutUpdate: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface PaymentInstructionsData {\n bankAccount: string;\n recipientName: string;\n referenceNumber: string;\n ipsQrCodeBase64: string;\n expiresAt: string;\n}\n\ninterface CheckoutConvertResponse {\n checkoutConvert: {\n order: OrderData | null;\n paymentAction: PaymentAction;\n paymentInstructions: PaymentInstructionsData | null;\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null;\n userErrors: UserError[];\n };\n}\n\ninterface CheckoutAbandonResponse {\n checkoutAbandon: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nfunction buildCheckoutLineItems(cart: Cart): AnalyticsProperties[\"lineItems\"] {\n return cart.items.map((item) => {\n const itemName =\n (item.variant as (typeof item.variant & { productTitle?: string | null }) | null)?.productTitle ??\n item.variant?.title ??\n undefined;\n const itemVariant = item.variant?.title ?? undefined;\n return {\n itemId: item.variantId,\n ...(item.variant?.productId ? { productId: item.variant.productId } : {}),\n variantId: item.variantId,\n ...(item.variant?.sku !== undefined ? { sku: item.variant.sku } : {}),\n ...(itemName ? { itemName, productTitle: itemName } : {}),\n ...(itemVariant ? { itemVariant, variantTitle: itemVariant } : {}),\n quantity: item.quantity,\n unitPrice: item.effectiveUnitPrice.amount,\n price: item.effectiveUnitPrice.amount,\n lineTotal: item.lineTotal.amount,\n };\n });\n}\n\nconst CHECKOUT_START_MUTATION = `\nmutation CheckoutStart {\n checkoutStart {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_UPDATE_MUTATION = `\nmutation CheckoutUpdate($input: CheckoutUpdateInput!) {\n checkoutUpdate(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_CONVERT_MUTATION = `\nmutation CheckoutConvert {\n checkoutConvert {\n order {\n id\n orderNumber\n status\n customerEmail\n customerPhone\n shippingAddress\n billingAddress\n subtotal { amount currency }\n shippingTotal { amount currency }\n shippingTaxAmount { amount currency }\n discountTotal { amount currency }\n taxTotal { amount currency }\n total { amount currency }\n note\n items {\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice { amount currency }\n totalPrice { amount currency }\n taxAmount { amount currency }\n }\n createdAt\n }\n paymentInstructions {\n bankAccount\n recipientName\n referenceNumber\n ipsQrCodeBase64\n expiresAt\n }\n paymentAction {\n kind\n redirectUrl\n paymentRef\n }\n purchaseTracking {\n eventId\n orderId\n cartId\n total { amount currency }\n currency\n numItems\n lineItems {\n contentId\n productId\n variantId\n sku\n productTitle\n variantTitle\n quantity\n unitPrice { amount currency }\n lineTotal { amount currency }\n }\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_QUOTE_QUERY = `\nquery CheckoutQuote($shippingRateId: ID, $paymentMethod: PaymentMethod) {\n checkoutQuote(shippingRateId: $shippingRateId, paymentMethod: $paymentMethod) {\n subtotal { amount currency }\n discountTotal { amount currency }\n shippingTotal { amount currency }\n paymentFee { amount currency }\n taxTotal { amount currency }\n total { amount currency }\n }\n}\n`;\n\nconst CHECKOUT_ABANDON_MUTATION = `\nmutation CheckoutAbandon {\n checkoutAbandon {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nfunction mapOrderData(data: OrderData, paymentInstructions: PaymentInstructionsData | null): Order {\n return {\n id: data.id,\n orderNumber: data.orderNumber,\n email: data.customerEmail,\n phone: data.customerPhone,\n status: data.status,\n shippingAddress: data.shippingAddress as Address | null,\n subtotal: data.subtotal,\n shippingTotal: data.shippingTotal,\n shippingTaxAmount: data.shippingTaxAmount,\n discountTotal: data.discountTotal,\n taxTotal: data.taxTotal,\n total: data.total,\n note: data.note,\n items: data.items.map((item) => ({\n id: item.id,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n sku: item.sku,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.totalPrice,\n taxAmount: item.taxAmount,\n })),\n paymentInstructions: paymentInstructions ?? null,\n createdAt: data.createdAt,\n };\n}\n\nconst CHECKOUT_STATE_ERROR_CODES = [\"CART_NOT_IN_CHECKOUT\", \"CHECKOUT_START_ERROR\", \"CHECKOUT_ABANDON_ERROR\"];\n\nfunction checkCartIsInCheckout(status: CartStatus): Result<void, StateError> {\n if (status !== \"checkout\") {\n return err(\n new StateError(`Cart must be in 'checkout' state for this operation. Current state: '${status}'.`, status),\n );\n }\n return ok(undefined);\n}\n\nfunction hasHandledCheckoutLeadDispatch(storage: { get(key: string): string | null }, cartToken: string): boolean {\n return storage.get(getCheckoutLeadDispatchKey(cartToken)) === \"1\";\n}\n\nfunction markCheckoutLeadDispatchHandled(storage: { set(key: string, value: string): void }, cartToken: string): void {\n storage.set(getCheckoutLeadDispatchKey(cartToken), \"1\");\n}\n\nexport interface CheckoutOperations {\n /**\n * Start checkout for the current active cart.\n *\n * @returns The cart in checkout state.\n */\n start(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Update checkout customer, shipping, and payment details.\n *\n * @param data - Checkout fields to update.\n * @returns The updated checkout cart.\n */\n update(data: CheckoutData): Promise<Result<Cart, StorefrontError>>;\n /**\n * Complete checkout and convert the cart into an order.\n *\n * Redirect payments retain the converted cart as a recovery handle until status confirms payment.\n *\n * @returns The created order and the next payment action.\n */\n complete(options?: { navigate?: (url: string) => void }): Promise<Result<CheckoutCompletion, StorefrontError>>;\n /**\n * Abandon checkout and return the cart to an active state.\n *\n * @returns The reactivated cart.\n */\n abandon(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Price the current cart as checkout would charge it, without saving the selection.\n * Omitted options fall back to the cart's saved shipping rate and payment method.\n *\n * @returns The quote, or `null` when there is no cart.\n */\n quote(selection?: {\n shippingRateId?: string;\n paymentMethod?: string;\n }): Promise<Result<CheckoutQuote | null, StorefrontError>>;\n}\n\nfunction isContactStepComplete(cart: Cart): boolean {\n return Boolean(cart.customerEmail && cart.shippingAddress);\n}\n\nfunction detectCheckoutStepAdvances(previousCart: Cart, nextCart: Cart, data: CheckoutData): CheckoutStep[] {\n const steps: CheckoutStep[] = [];\n if (\n (data.email !== undefined || data.phone !== undefined || data.shippingAddress !== undefined) &&\n !isContactStepComplete(previousCart) &&\n isContactStepComplete(nextCart)\n ) {\n steps.push(\"contact\");\n }\n if (data.shippingRateId !== undefined && previousCart.shippingRateId === null && nextCart.shippingRateId !== null) {\n steps.push(\"shipping\");\n }\n if (data.paymentMethod !== undefined && previousCart.paymentMethod === null && nextCart.paymentMethod !== null) {\n steps.push(\"payment\");\n }\n return steps;\n}\n\nexport function createCheckoutOperations(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n emit?: AnalyticsEmitFn,\n snapshotCache?: CartSnapshotCache,\n consentMgr: ConsentManager | null = null,\n): CheckoutOperations {\n const cache = snapshotCache ?? createCartSnapshotCache(client, storage);\n const runner = createCartMutationRunner({ client, cache });\n\n return {\n async start(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutStartResponse>({\n query: CHECKOUT_START_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutStart);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit) {\n emit(\"analytics.checkout_started\", {\n cartId: cart.id,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n lineItems: buildCheckoutLineItems(cart),\n });\n }\n return ok(cart);\n },\n\n async update(data: CheckoutData): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n\n const input: Record<string, unknown> = {};\n if (data.email !== undefined) input.customerEmail = data.email;\n if (data.phone !== undefined) input.customerPhone = data.phone;\n if (data.shippingAddress !== undefined) input.shippingAddress = data.shippingAddress;\n if (data.billingAddress !== undefined) input.billingAddress = data.billingAddress;\n if (data.notes !== undefined) input.notes = data.notes;\n if (data.emailMarketingConsent !== undefined) input.emailMarketingConsent = data.emailMarketingConsent;\n if (data.paymentMethod !== undefined) input.paymentMethod = data.paymentMethod;\n if (data.shippingRateId !== undefined) input.shippingRateId = data.shippingRateId;\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutUpdateResponse>({\n query: CHECKOUT_UPDATE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutUpdate);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n const stateCheck = checkCartIsInCheckout(cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n if (emit && previousCart) {\n const steps = detectCheckoutStepAdvances(previousCart, cart, data);\n for (const step of steps) {\n emit(\"analytics.checkout_step_completed\", {\n cartId: cart.id,\n step,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n lineItems: buildCheckoutLineItems(cart),\n });\n }\n\n if (\n !isContactStepComplete(previousCart) &&\n isContactStepComplete(cart) &&\n !hasHandledCheckoutLeadDispatch(storage, cart.token)\n ) {\n emit(\"analytics.lead_generated\", {\n leadType: \"checkout_lead\",\n source: \"checkout\",\n placement: \"checkout\",\n value: cart.total.amount,\n currency: cart.total.currency,\n });\n markCheckoutLeadDispatchHandled(storage, cart.token);\n }\n }\n return ok(cart);\n },\n\n async complete(options?: {\n navigate?: (url: string) => void;\n }): Promise<Result<CheckoutCompletion, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutConvertResponse>({\n query: CHECKOUT_CONVERT_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutConvert;\n const userError = runner.mapUserError(payload.userErrors, CHECKOUT_STATE_ERROR_CODES);\n if (userError && payload.paymentAction?.kind !== \"redirect_pending\") {\n runner.clearIfGone(userError);\n return err(userError);\n }\n\n if (!payload.order) {\n return err(new NotFoundError(\"Order not found\"));\n }\n\n const order = mapOrderData(payload.order, payload.paymentInstructions);\n if (payload.paymentAction.kind === \"none\") {\n finalizeNonRedirectPayment(\n { client, storage, cache, consentManager: consentMgr },\n token,\n payload.purchaseTracking,\n );\n return ok({ kind: \"placed\", order });\n }\n if (payload.paymentAction.kind === \"instructions\") {\n if (!order.paymentInstructions) return err(new NotFoundError(\"Payment instructions not found\"));\n finalizeNonRedirectPayment(\n { client, storage, cache, consentManager: consentMgr },\n token,\n payload.purchaseTracking,\n );\n return ok({ kind: \"instructions\", order, instructions: order.paymentInstructions });\n }\n\n const storeIdResult = await resolvePaymentStoreId(client);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const paymentRef = payload.paymentAction.paymentRef;\n const recoveryResult = persistPaymentRecovery(storage, {\n storeId: storeIdResult.value,\n paymentRef,\n orderNumber: order.orderNumber,\n convertedCartToken: token,\n tracking: payload.purchaseTracking\n ? { ...payload.purchaseTracking, eventId: payload.purchaseTracking.orderId }\n : null,\n phase: payload.paymentAction.kind === \"redirect\" ? \"redirecting\" : \"session_unavailable\",\n createdAt: Date.now(),\n });\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n\n if (payload.paymentAction.kind === \"redirect_pending\") {\n return ok({ kind: \"session_unavailable\", order, paymentRef });\n }\n\n try {\n if (options?.navigate) options.navigate(payload.paymentAction.redirectUrl);\n else if (typeof window !== \"undefined\") window.location.assign(payload.paymentAction.redirectUrl);\n } catch (cause) {\n return err(\n new StorefrontError(\"Could not navigate to the payment provider\", \"NAVIGATION_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n }),\n );\n }\n return ok({ kind: \"redirecting\", order, paymentRef });\n },\n\n async abandon(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutAbandonResponse>({\n query: CHECKOUT_ABANDON_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutAbandon);\n },\n });\n\n return result;\n },\n\n async quote(selection = {}): Promise<Result<CheckoutQuote | null, StorefrontError>> {\n if (!storage.get(CART_SESSION_KEY)) return ok(null);\n const result = await client.query<{ checkoutQuote: CheckoutQuote | null }>(\n {\n query: CHECKOUT_QUOTE_QUERY,\n variables: {\n shippingRateId: selection.shippingRateId ?? null,\n paymentMethod: selection.paymentMethod ?? null,\n },\n },\n { cache: false },\n );\n return result.map((value) => value.checkoutQuote);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NetworkError, RateLimitError, type StorefrontError } from \"./errors.ts\";\nimport type { PaginatedResult } from \"./types.ts\";\n\n/** Sequentially collects bounded pages and honours Retry-After, with at most three throttle retries per page. */\nexport async function collectAllPages<T>(\n list: (options: { first: number; after?: string }) => Promise<Result<PaginatedResult<T>, StorefrontError>>,\n first = 100,\n): Promise<Result<T[], StorefrontError>> {\n const items: T[] = [];\n let after: string | undefined;\n for (;;) {\n let result = await list({ first, after });\n for (let retry = 0; result.isErr() && result.error instanceof RateLimitError && retry < 3; retry++) {\n const delay = result.error.retryAfterMs;\n await new Promise((resolve) => setTimeout(resolve, delay));\n result = await list({ first, after });\n }\n if (result.isErr()) return err(result.error);\n items.push(...result.value.items);\n if (!result.value.pageInfo.hasNextPage) return ok(items);\n const next = result.value.pageInfo.endCursor;\n if (!next || next === after) return err(new NetworkError(\"Pagination did not advance\"));\n after = next;\n }\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type { Collection, PaginatedResult, Product, StorefrontClientContext } from \"./types.ts\";\nimport { normalizeCollectionAssetUrls, normalizeProductAssetUrls, resolveAssetUrl } from \"./url.ts\";\n\nexport interface CollectionsListOptions {\n first?: number;\n after?: string;\n search?: string;\n}\n\nexport type CollectionProductSort = \"manual\" | \"best_selling\" | \"newest\" | \"price_asc\" | \"price_desc\";\n\nexport interface CollectionProductsOptions {\n first?: number;\n after?: string;\n sort?: CollectionProductSort;\n}\n\ninterface CollectionImage {\n url: string;\n previewUrl: string;\n altText: string | null;\n width: number | null;\n height: number | null;\n}\n\ninterface RawCollection {\n id: string;\n handle: string;\n title: string;\n description: string | null;\n type: string;\n sortOrder: string;\n metaTitle: string | null;\n metaDescription: string | null;\n productCount: number;\n imageAsset: CollectionImage | null;\n}\n\ninterface CollectionEdge {\n node: RawCollection;\n cursor: string;\n}\n\ninterface CollectionConnection {\n edges: CollectionEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CollectionsQueryResponse {\n collections: CollectionConnection;\n}\n\ninterface CollectionQueryResponse {\n collection: RawCollection | null;\n}\n\nfunction mapRawCollection(raw: RawCollection, endpoint: string): Collection {\n return {\n id: raw.id,\n handle: raw.handle,\n title: raw.title,\n description: raw.description,\n type: raw.type as Collection[\"type\"],\n sortOrder: raw.sortOrder as Collection[\"sortOrder\"],\n metaTitle: raw.metaTitle,\n metaDescription: raw.metaDescription,\n productCount: raw.productCount,\n imageAsset: raw.imageAsset\n ? {\n url: resolveAssetUrl(raw.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(raw.imageAsset.previewUrl, endpoint),\n altText: raw.imageAsset.altText,\n width: raw.imageAsset.width,\n height: raw.imageAsset.height,\n }\n : null,\n };\n}\n\ninterface ProductEdge {\n node: Product;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CollectionWithProducts {\n id: string;\n products: ProductConnection;\n}\n\ninterface CollectionProductsQueryResponse {\n collection: CollectionWithProducts | null;\n}\n\nconst COLLECTIONS_QUERY = `\nquery Collections($first: Int, $after: String, $search: String) {\n collections(first: $first, after: $after, search: $search) {\n edges {\n node {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst COLLECTION_BY_ID_QUERY = `\nquery CollectionById($id: ID!) {\n collection(id: $id) {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n}\n`;\n\nconst COLLECTION_BY_HANDLE_QUERY = `\nquery CollectionByHandle($handle: String!) {\n collection(handle: $handle) {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n}\n`;\n\nconst COLLECTION_PRODUCTS_BY_ID_QUERY = `\nquery CollectionProductsById($id: ID!, $first: Int, $after: String, $sort: CollectionSortOrder) {\n collection(id: $id) {\n id\n products(first: $first, after: $after, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nconst COLLECTION_PRODUCTS_BY_HANDLE_QUERY = `\nquery CollectionProductsByHandle($handle: String!, $first: Int, $after: String, $sort: CollectionSortOrder) {\n collection(handle: $handle) {\n id\n products(first: $first, after: $after, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nexport interface CollectionsOperations {\n listAll(filter?: Pick<CollectionsListOptions, \"search\">): Promise<Result<Collection[], StorefrontError>>;\n /**\n * List collections with cursor pagination and optional search.\n *\n * @param options - Pagination and search options.\n * @returns Paginated storefront collections.\n */\n list(options?: CollectionsListOptions): Promise<Result<PaginatedResult<Collection>, StorefrontError>>;\n /**\n * Fetch a single collection by UUID.\n *\n * @param id - Collection UUID.\n * @returns The matching collection.\n */\n byId(id: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch a single collection by handle.\n *\n * @param handle - Collection handle.\n * @returns The matching collection.\n */\n byHandle(handle: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch a single collection by handle.\n *\n * @param handle - Collection handle.\n * @returns The matching collection.\n */\n get(handle: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch products that belong to a collection.\n *\n * @param id - Collection UUID.\n * @param options - Pagination and collection product options.\n * @returns Paginated products for the collection.\n */\n getProductsById(\n id: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n /**\n * Fetch products that belong to a collection by handle.\n *\n * @param handle - Collection handle.\n * @param options - Pagination and collection product options.\n * @returns Paginated products for the collection.\n */\n getProductsByHandle(\n handle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCollectionsOperations(client: StorefrontClientContext): CollectionsOperations {\n const operations: CollectionsOperations = {\n listAll: (filter) => collectAllPages((options) => operations.list({ ...options, ...filter })),\n async list(options?: CollectionsListOptions): Promise<Result<PaginatedResult<Collection>, StorefrontError>> {\n const result = await client.query<CollectionsQueryResponse>({\n query: COLLECTIONS_QUERY,\n variables: {\n first: options?.first,\n after: options?.after,\n search: options?.search,\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const connection = result.value.collections;\n return ok({\n items: connection.edges.map((edge) => mapRawCollection(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async byId(id: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${id}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async getProductsById(\n id: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CollectionProductsQueryResponse>({\n query: COLLECTION_PRODUCTS_BY_ID_QUERY,\n variables: {\n id,\n first: options?.first,\n after: options?.after,\n ...(options?.sort !== undefined && { sort: options.sort }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${id}`));\n }\n\n const connection = result.value.collection.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async getProductsByHandle(\n handle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CollectionProductsQueryResponse>({\n query: COLLECTION_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n handle,\n first: options?.first,\n after: options?.after,\n ...(options?.sort !== undefined && { sort: options.sort }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const connection = result.value.collection.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n };\n return operations;\n}\n","import {\n CONSENT_CATEGORIES,\n type ConsentCategory,\n getTrackingProviderRequiredConsent,\n TRACKING_PROVIDER_REQUIRED_CONSENT,\n type TrackingProvider,\n} from \"@ekomerc/tracking-policy\";\nimport { CONSENT_COOKIE_NAME } from \"./storage.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsBrowserAdapter,\n AnalyticsConsentState,\n} from \"./tracking-runtime.ts\";\n\nconst CONSENT_COOKIE_MAX_AGE = 365 * 24 * 60 * 60;\nconst CONSENT_BUFFER_MAX = 100;\n\nexport interface ConsentCategoryState {\n analytics_storage: AnalyticsConsentState;\n ad_storage: AnalyticsConsentState;\n ad_user_data: AnalyticsConsentState;\n ad_personalization: AnalyticsConsentState;\n}\n\nexport type { ConsentCategory };\n\nexport interface ConsentOperations {\n getState(): AnalyticsConsentState;\n getCategories(): ConsentCategoryState;\n grantAll(): void;\n denyAll(): void;\n grant(categories: ConsentCategory[]): void;\n deny(categories: ConsentCategory[]): void;\n update(state: Partial<ConsentCategoryState>): void;\n reset(): void;\n onChange(callback: (state: ConsentCategoryState) => void): () => void;\n}\n\nexport interface ConsentBufferEntry {\n adapter: AnalyticsBrowserAdapter;\n input: AnalyticsAdapterDispatchInput;\n}\n\nexport interface ConsentManager extends ConsentOperations {\n resolveConsentState(): AnalyticsConsentState;\n bufferDispatch(entry: ConsentBufferEntry): void;\n shouldBuffer(provider: TrackingProvider): boolean;\n shouldDispatch(provider: TrackingProvider): boolean;\n shouldDiscard(provider: TrackingProvider): boolean;\n}\n\ntype ConsentChangeCallback = (state: ConsentCategoryState) => void;\ntype ConsentBufferFlushCallback = (entries: ConsentBufferEntry[]) => void;\n\nconst COOKIE_KEY_MAP: Record<ConsentCategory, string> = {\n analytics_storage: \"as\",\n ad_storage: \"ads\",\n ad_user_data: \"aud\",\n ad_personalization: \"ap\",\n};\n\nconst COOKIE_KEY_REVERSE: Record<string, ConsentCategory> = {\n as: \"analytics_storage\",\n ads: \"ad_storage\",\n aud: \"ad_user_data\",\n ap: \"ad_personalization\",\n};\n\nconst COOKIE_VALUE_MAP: Record<AnalyticsConsentState, string> = {\n granted: \"g\",\n denied: \"d\",\n unknown: \"u\",\n};\n\nconst COOKIE_VALUE_REVERSE: Record<string, AnalyticsConsentState> = {\n g: \"granted\",\n d: \"denied\",\n u: \"unknown\",\n};\n\nfunction defaultCategoryState(): ConsentCategoryState {\n return {\n analytics_storage: \"unknown\",\n ad_storage: \"unknown\",\n ad_user_data: \"unknown\",\n ad_personalization: \"unknown\",\n };\n}\n\nfunction hasBrowserCookies(): boolean {\n return typeof document !== \"undefined\" && typeof document.cookie === \"string\";\n}\n\nfunction readConsentCookie(): ConsentCategoryState | null {\n if (!hasBrowserCookies()) return null;\n\n for (const pair of document.cookie.split(\";\")) {\n const [name, ...valueParts] = pair.trim().split(\"=\");\n if (name !== CONSENT_COOKIE_NAME) continue;\n\n const raw = valueParts.join(\"=\");\n if (!raw) return null;\n\n try {\n const decoded = decodeURIComponent(raw);\n const parsed = JSON.parse(decoded);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n\n const state = defaultCategoryState();\n for (const [shortKey, shortValue] of Object.entries(parsed)) {\n const category = COOKIE_KEY_REVERSE[shortKey];\n const consentValue = typeof shortValue === \"string\" ? COOKIE_VALUE_REVERSE[shortValue] : undefined;\n if (category && consentValue) {\n state[category] = consentValue;\n }\n }\n return state;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\nfunction writeConsentCookie(state: ConsentCategoryState): void {\n if (!hasBrowserCookies()) return;\n\n const compact: Record<string, string> = {};\n for (const category of CONSENT_CATEGORIES) {\n compact[COOKIE_KEY_MAP[category]] = COOKIE_VALUE_MAP[state[category]];\n }\n\n const value = encodeURIComponent(JSON.stringify(compact));\n // biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API not universally available\n document.cookie = `${CONSENT_COOKIE_NAME}=${value}; Max-Age=${CONSENT_COOKIE_MAX_AGE}; Path=/; SameSite=Lax`;\n}\n\nfunction clearConsentCookie(): void {\n if (!hasBrowserCookies()) return;\n // biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API not universally available\n document.cookie = `${CONSENT_COOKIE_NAME}=; Max-Age=0; Path=/; SameSite=Lax`;\n}\n\nexport function deriveOverallConsentState(state: ConsentCategoryState): AnalyticsConsentState {\n let hasUnknown = false;\n for (const category of CONSENT_CATEGORIES) {\n if (state[category] === \"denied\") return \"denied\";\n if (state[category] === \"unknown\") hasUnknown = true;\n }\n return hasUnknown ? \"unknown\" : \"granted\";\n}\n\n/**\n * Checks whether all required consent categories for a provider are granted.\n */\nexport function providerConsentGranted(provider: TrackingProvider, state: ConsentCategoryState): boolean {\n if (!(provider in TRACKING_PROVIDER_REQUIRED_CONSENT)) return true;\n const required = getTrackingProviderRequiredConsent(provider);\n return required.every((category) => state[category] === \"granted\");\n}\n\n/**\n * Checks whether any required consent category for a provider is denied.\n */\nexport function providerConsentDenied(provider: TrackingProvider, state: ConsentCategoryState): boolean {\n if (!(provider in TRACKING_PROVIDER_REQUIRED_CONSENT)) return false;\n const required = getTrackingProviderRequiredConsent(provider);\n return required.some((category) => state[category] === \"denied\");\n}\n\nexport interface ConsentManagerOptions {\n debug?: boolean;\n onBufferFlush?: ConsentBufferFlushCallback;\n}\n\n/**\n * Creates a consent manager that tracks per-category consent state, persists to a cookie,\n * and buffers adapter dispatch entries until consent is resolved.\n */\nexport function createConsentManager(options: ConsentManagerOptions = {}): ConsentManager {\n const debug = options.debug === true;\n let state: ConsentCategoryState = readConsentCookie() ?? defaultCategoryState();\n const listeners: Set<ConsentChangeCallback> = new Set();\n const buffer: ConsentBufferEntry[] = [];\n\n function debugLog(message: string, data?: unknown): void {\n if (!debug) return;\n // biome-ignore lint/suspicious/noConsole: debug logging\n if (data !== undefined) console.debug(`[ekomerc:consent] ${message}`, data);\n // biome-ignore lint/suspicious/noConsole: debug logging\n else console.debug(`[ekomerc:consent] ${message}`);\n }\n\n function notifyListeners(): void {\n const snapshot = { ...state };\n for (const listener of listeners) {\n try {\n listener(snapshot);\n } catch {\n // Listeners must not affect consent operations.\n }\n }\n }\n\n function processBuffer(): void {\n const toFlush: ConsentBufferEntry[] = [];\n const remaining: ConsentBufferEntry[] = [];\n\n for (const entry of buffer) {\n if (providerConsentGranted(entry.adapter.provider, state)) {\n toFlush.push(entry);\n debugLog(`buffer: flushing entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n } else if (providerConsentDenied(entry.adapter.provider, state)) {\n debugLog(`buffer: discarding entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n } else {\n remaining.push(entry);\n }\n }\n\n buffer.length = 0;\n buffer.push(...remaining);\n\n if (toFlush.length > 0 && options.onBufferFlush) {\n options.onBufferFlush(toFlush);\n }\n }\n\n function applyUpdate(updates: Partial<ConsentCategoryState>): void {\n let changed = false;\n for (const category of CONSENT_CATEGORIES) {\n const newValue = updates[category];\n if (newValue !== undefined && newValue !== state[category]) {\n state[category] = newValue;\n changed = true;\n }\n }\n\n if (!changed) return;\n\n debugLog(\"state changed\", { ...state });\n writeConsentCookie(state);\n notifyListeners();\n processBuffer();\n }\n\n if (debug) {\n debugLog(\"initialized\", { ...state, source: readConsentCookie() ? \"cookie\" : \"default\" });\n }\n\n return {\n getState(): AnalyticsConsentState {\n return deriveOverallConsentState(state);\n },\n\n getCategories(): ConsentCategoryState {\n return { ...state };\n },\n\n grantAll(): void {\n applyUpdate({\n analytics_storage: \"granted\",\n ad_storage: \"granted\",\n ad_user_data: \"granted\",\n ad_personalization: \"granted\",\n });\n },\n\n denyAll(): void {\n applyUpdate({\n analytics_storage: \"denied\",\n ad_storage: \"denied\",\n ad_user_data: \"denied\",\n ad_personalization: \"denied\",\n });\n },\n\n grant(categories: ConsentCategory[]): void {\n const updates: Partial<ConsentCategoryState> = {};\n for (const category of categories) {\n updates[category] = \"granted\";\n }\n applyUpdate(updates);\n },\n\n deny(categories: ConsentCategory[]): void {\n const updates: Partial<ConsentCategoryState> = {};\n for (const category of categories) {\n updates[category] = \"denied\";\n }\n applyUpdate(updates);\n },\n\n update(updates: Partial<ConsentCategoryState>): void {\n applyUpdate(updates);\n },\n\n reset(): void {\n state = defaultCategoryState();\n debugLog(\"reset to unknown\");\n clearConsentCookie();\n notifyListeners();\n // On reset, all buffered entries stay buffered (unknown state).\n },\n\n onChange(callback: ConsentChangeCallback): () => void {\n listeners.add(callback);\n return () => {\n listeners.delete(callback);\n };\n },\n\n resolveConsentState(): AnalyticsConsentState {\n return deriveOverallConsentState(state);\n },\n\n shouldBuffer(provider: TrackingProvider): boolean {\n return !providerConsentGranted(provider, state) && !providerConsentDenied(provider, state);\n },\n\n shouldDispatch(provider: TrackingProvider): boolean {\n return providerConsentGranted(provider, state);\n },\n\n shouldDiscard(provider: TrackingProvider): boolean {\n return providerConsentDenied(provider, state);\n },\n\n bufferDispatch(entry: ConsentBufferEntry): void {\n if (buffer.length >= CONSENT_BUFFER_MAX) {\n buffer.shift();\n debugLog(\"buffer: evicted oldest entry (cap reached)\");\n }\n buffer.push(entry);\n debugLog(`buffer: added entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NotFoundError, type StorefrontError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type { PageInfo, PaginatedResult, StorefrontClientContext } from \"./types.ts\";\n\n/** Published TipTap content with safe HTML and plain text for alternate renderers. */\nexport interface RichText {\n html: string;\n json: unknown;\n text: string;\n}\n/** Optional merchant-authored metadata; callers choose their own defaults for missing values. */\nexport interface Seo {\n title: string | null;\n description: string | null;\n}\n/** A currently published page; drafts, scheduled pages and deleted pages are excluded. */\nexport interface Page {\n id: string;\n handle: string;\n title: string;\n content: RichText;\n seo: Seo;\n publishedAt: string;\n updatedAt: string;\n}\n/** A published legal-policy slot containing the extracted TipTap body. */\nexport interface Policy {\n id: string;\n slot: string;\n title: string;\n content: RichText;\n seo: Seo;\n updatedAt: string;\n}\n/** Resolved destination; resource handles reflect current publication and unavailable targets are omitted. */\nexport type MenuLinkTarget =\n | {\n kind: \"SYSTEM\";\n handle: null;\n systemRoute: \"HOME\" | \"CATALOG\" | \"COLLECTIONS\" | \"CART\" | \"CHECKOUT\";\n externalUrl: null;\n }\n | { kind: \"URL\"; handle: null; systemRoute: null; externalUrl: string }\n | {\n kind: \"PAGE\" | \"PRODUCT\" | \"COLLECTION\" | \"CATEGORY\" | \"POLICY\";\n handle: string;\n systemRoute: null;\n externalUrl: null;\n };\n/** Ordered menu entry with up to three levels of nested entries. */\nexport interface MenuItem {\n id: string;\n label: string;\n openInNewTab: boolean;\n target: MenuLinkTarget;\n items: MenuItem[];\n}\n/** A merchant menu with unavailable resource destinations filtered out. */\nexport interface Menu {\n id: string;\n handle: string;\n title: string;\n items: MenuItem[];\n}\n/** Cursor page request, capped at fifty results by the API. */\nexport interface PagesListOptions {\n first?: number;\n after?: string;\n}\n/** Read published pages; listAll crawls sequentially with bounded retries for throttling. */\nexport interface PagesOperations {\n get(handle: string): Promise<Result<Page, StorefrontError>>;\n list(options?: PagesListOptions): Promise<Result<PaginatedResult<Page>, StorefrontError>>;\n listAll(): Promise<Result<Page[], StorefrontError>>;\n}\n/** Read published legal policies in the platform’s stable slot order. */\nexport interface PoliciesOperations {\n get(slot: string): Promise<Result<Policy, StorefrontError>>;\n list(): Promise<Result<Policy[], StorefrontError>>;\n}\n/** Read a menu by handle with resolved, currently available destinations. */\nexport interface MenusOperations {\n get(handle: string): Promise<Result<Menu, StorefrontError>>;\n}\nconst CONTENT_FIELDS = `id title content { html json text } seo { title description } updatedAt`;\nconst PAGE_FIELDS = `${CONTENT_FIELDS} handle publishedAt`;\nconst PAGE_QUERY = `query Page($handle: String!) { page(handle: $handle) { ${PAGE_FIELDS} } }`;\nconst PAGES_QUERY = `query Pages($first: Int, $after: String) { pages(first: $first, after: $after) {\n edges { node { ${PAGE_FIELDS} } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor }\n} }`;\nconst POLICY_QUERY = `query Policy($slot: String!) { policy(slot: $slot) { ${CONTENT_FIELDS} slot } }`;\nconst POLICIES_QUERY = `query Policies { policies { ${CONTENT_FIELDS} slot } }`;\nconst MENU_ITEM_FIELDS = `id label openInNewTab target { kind handle systemRoute externalUrl }`;\nconst MENU_QUERY = `query Menu($handle: String!) { menu(handle: $handle) { id handle title\n items { ${MENU_ITEM_FIELDS} items { ${MENU_ITEM_FIELDS} items { ${MENU_ITEM_FIELDS} } } }\n} }`;\n\nexport function createPagesOperations(client: StorefrontClientContext): PagesOperations {\n const pages: PagesOperations = {\n async get(handle) {\n const result = await client.query<{ page: Page | null }>({ query: PAGE_QUERY, variables: { handle } });\n if (result.isErr()) return err(result.error);\n return result.value.page ? ok(result.value.page) : err(new NotFoundError(`Page not found: ${handle}`));\n },\n async list(options = {}) {\n const result = await client.query<{ pages: { edges: Array<{ node: Page }>; pageInfo: PageInfo } }>({\n query: PAGES_QUERY,\n variables: { ...options },\n });\n if (result.isErr()) return err(result.error);\n return ok({ items: result.value.pages.edges.map((edge) => edge.node), pageInfo: result.value.pages.pageInfo });\n },\n listAll: () => collectAllPages((options) => pages.list(options), 50),\n };\n return pages;\n}\nexport function createPoliciesOperations(client: StorefrontClientContext): PoliciesOperations {\n return {\n async get(slot) {\n const result = await client.query<{ policy: Policy | null }>({ query: POLICY_QUERY, variables: { slot } });\n if (result.isErr()) return err(result.error);\n return result.value.policy ? ok(result.value.policy) : err(new NotFoundError(`Policy not found: ${slot}`));\n },\n async list() {\n const result = await client.query<{ policies: Policy[] }>({ query: POLICIES_QUERY });\n return result.map((value) => value.policies);\n },\n };\n}\nexport function createMenusOperations(client: StorefrontClientContext): MenusOperations {\n return {\n async get(handle) {\n const result = await client.query<{ menu: Menu | null }>({ query: MENU_QUERY, variables: { handle } });\n if (result.isErr()) return err(result.error);\n return result.value.menu ? ok(result.value.menu) : err(new NotFoundError(`Menu not found: ${handle}`));\n },\n };\n}\n","export function getWindowObject(getWindow: (() => object | null) | undefined): object | null {\n if (getWindow) {\n return getWindow();\n }\n\n if (typeof window === \"undefined\") {\n return null;\n }\n\n return window;\n}\n\nexport function getNumberPropFromKeys(properties: Record<string, unknown>, keys: string[]): number | null {\n for (const key of keys) {\n const value = properties[key];\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n\n return null;\n}\n","import type { TrackingProvider } from \"@ekomerc/tracking-policy\";\nimport { getWindowObject } from \"./browser-helpers.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsBrowserAdapter,\n} from \"./tracking-runtime.ts\";\n\nconst DEBUG_DATA_LAYER_NAME = \"ekomercDebugDataLayer\";\n\ninterface DebugDataLayerEntry {\n timestamp: string;\n eventType: string;\n eventId: string;\n sessionId: string;\n visitorId: string;\n path: string;\n consentState: string;\n properties: Record<string, unknown>;\n}\n\ninterface DebugBrowserAdapterOptions {\n getWindow?: () => object | null;\n}\n\nfunction isLocalhost(): boolean {\n if (typeof window === \"undefined\") return false;\n const { hostname } = window.location;\n return hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n}\n\n/**\n * Creates a debug browser adapter that appends all analytics events to\n * `window.ekomercDebugDataLayer`. Only activates on localhost.\n */\nexport function createDebugBrowserAdapter(options: DebugBrowserAdapterOptions = {}): AnalyticsBrowserAdapter | null {\n if (!isLocalhost()) return null;\n\n return {\n provider: \"debug\" as TrackingProvider,\n dispatch(input: AnalyticsAdapterDispatchInput): AnalyticsAdapterOperationResult {\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n return { status: \"skipped\", reason: \"runtime_unavailable\" };\n }\n\n let dataLayer = Reflect.get(windowObject, DEBUG_DATA_LAYER_NAME) as DebugDataLayerEntry[] | undefined;\n if (!Array.isArray(dataLayer)) {\n dataLayer = [];\n Reflect.set(windowObject, DEBUG_DATA_LAYER_NAME, dataLayer);\n }\n\n const entry: DebugDataLayerEntry = {\n timestamp: input.event.occurredAt,\n eventType: input.event.eventType,\n eventId: input.event.eventId,\n sessionId: input.event.sessionId,\n visitorId: input.event.visitorId,\n path: input.event.context.path,\n consentState: input.event.consentState,\n properties: input.event.properties,\n };\n\n dataLayer.push(entry);\n\n // biome-ignore lint/suspicious/noConsole: dev-only debug adapter\n console.debug(\"[ekomerc:debug]\", entry.eventType, entry);\n\n return { status: \"success\" };\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { QueryCache } from \"./cache.ts\";\nimport {\n AuthError,\n GraphQLError,\n NetworkError,\n NotFoundError,\n RateLimitError,\n type StorefrontError,\n ValidationError,\n} from \"./errors.ts\";\n\nexport interface GraphQLRequest {\n query: string;\n variables?: Record<string, unknown>;\n operationName?: string;\n}\n\nexport interface GraphQLResponse<T = unknown> {\n data?: T;\n errors?: Array<{ message: string; path?: readonly (string | number)[] }>;\n}\n\nexport interface GraphQLClientConfig {\n endpoint: string;\n apiKey: string;\n getCartToken: () => string | null;\n getCustomerToken: () => string | null;\n getMarketSlug: () => string | null;\n cache: QueryCache;\n cacheTTL: number;\n}\n\nexport interface GraphQLClient {\n query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>>;\n mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>>;\n}\n\nfunction mapHttpError(status: number, body: string): StorefrontError {\n if (status === 401 || status === 403) {\n let message = \"Authentication failed\";\n try {\n const parsed = JSON.parse(body) as { error?: string; message?: string };\n message = parsed.error ?? parsed.message ?? message;\n } catch {\n // Use default message\n }\n return new AuthError(message);\n }\n\n if (status === 404) {\n return new NotFoundError(\"Resource not found\");\n }\n\n return new GraphQLError(`HTTP error ${status}`, [{ message: body }]);\n}\n\nfunction mapGraphQLErrors(errors: Array<{ message: string; path?: readonly (string | number)[] }>): StorefrontError {\n const messages = errors.map((e) => e.message).join(\"; \");\n return new GraphQLError(messages, errors);\n}\n\nfunction getCacheKey(request: GraphQLRequest): string {\n return JSON.stringify({\n query: request.query,\n variables: request.variables ?? {},\n operationName: request.operationName,\n });\n}\n\nexport function createGraphQLClient(config: GraphQLClientConfig): GraphQLClient {\n async function execute<T>(\n request: GraphQLRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Result<GraphQLResponse<T>, StorefrontError>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"x-storefront-key\": config.apiKey,\n };\n\n const cartToken = config.getCartToken();\n if (cartToken) {\n headers[\"x-cart-token\"] = cartToken;\n }\n\n const customerToken = config.getCustomerToken();\n if (customerToken) {\n headers.Authorization = `Bearer ${customerToken}`;\n }\n\n const marketSlug = config.getMarketSlug();\n if (marketSlug) {\n headers[\"x-market-slug\"] = marketSlug;\n }\n\n let response: Response;\n try {\n response = await fetch(config.endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n query: request.query,\n variables: request.variables,\n operationName: request.operationName,\n }),\n signal: options?.signal,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Network request failed\";\n return err(new NetworkError(message, { cause: error instanceof Error ? error : undefined }));\n }\n\n if (!response.ok) {\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const milliseconds =\n retryAfter && /^\\d+$/.test(retryAfter)\n ? Number(retryAfter) * 1000\n : Date.parse(retryAfter ?? \"\") - Date.now();\n return err(new RateLimitError(Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : 1000));\n }\n const body = await response.text().catch(() => \"\");\n return err(mapHttpError(response.status, body));\n }\n\n let json: GraphQLResponse<T>;\n try {\n json = (await response.json()) as GraphQLResponse<T>;\n } catch {\n return err(new GraphQLError(\"Invalid JSON response\", [{ message: \"Failed to parse response\" }]));\n }\n\n return ok(json);\n }\n\n return {\n async query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>> {\n const useCache = options?.cache !== false;\n const cacheKey = getCacheKey(request);\n\n if (useCache) {\n const cached = config.cache.get<T>(cacheKey);\n if (cached !== null) {\n return ok(cached);\n }\n }\n\n const result = await execute<T>(request, options);\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const response = result.value;\n\n if (response.errors && response.errors.length > 0) {\n return err(mapGraphQLErrors(response.errors));\n }\n\n if (!response.data) {\n return err(new GraphQLError(\"No data in response\", [{ message: \"Response has no data\" }]));\n }\n\n if (useCache) {\n config.cache.set(cacheKey, response.data, config.cacheTTL);\n }\n\n return ok(response.data);\n },\n\n async mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>> {\n const result = await execute<T>(request, options);\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const response = result.value;\n\n if (response.errors && response.errors.length > 0) {\n return err(mapGraphQLErrors(response.errors));\n }\n\n if (!response.data) {\n return err(new GraphQLError(\"No data in response\", [{ message: \"Response has no data\" }]));\n }\n\n return ok(response.data);\n },\n };\n}\n\n/**\n * Extract userErrors from mutation result and convert to ValidationError if present\n */\nexport function extractUserErrors<\n T extends { userErrors?: Array<{ field: string | null; message: string; code?: string | null }> },\n>(data: T, fieldName: keyof T): Result<Exclude<T[keyof T], undefined>, ValidationError> {\n const payload = data[fieldName];\n if (!payload || typeof payload !== \"object\") {\n return err(new ValidationError(\"Unexpected response format\", []));\n }\n\n const typedPayload = payload as {\n userErrors?: Array<{ field: string | null; message: string; code?: string | null }>;\n data?: unknown;\n };\n\n if (typedPayload.userErrors && typedPayload.userErrors.length > 0) {\n const messages = typedPayload.userErrors.map((e) => e.message).join(\"; \");\n return err(new ValidationError(messages, typedPayload.userErrors));\n }\n\n return ok(payload as Exclude<T[keyof T], undefined>);\n}\n","import {\n GTM_STANDARD_EVENTS,\n type GtmStandardEventName,\n getTrackingProviderDedupeConvention,\n getTrackingProviderEventName,\n getTrackingProviderSupportRule,\n} from \"@ekomerc/tracking-policy\";\nimport { getNumberPropFromKeys, getWindowObject } from \"./browser-helpers.ts\";\nimport type { ConsentCategoryState } from \"./consent.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsBrowserAdapter,\n AnalyticsConsentState,\n AnalyticsConsentUpdate,\n AnalyticsProperties,\n} from \"./tracking-runtime.ts\";\nimport { INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY } from \"./tracking-runtime.ts\";\nimport type { GtmBrowserTrackingConfig } from \"./types.ts\";\n\nconst DEFAULT_DATA_LAYER_NAME = \"dataLayer\";\nconst GTM_CONSENT_DEFAULT_STATE: GtmConsentModeUpdate = {\n analytics_storage: \"denied\",\n ad_storage: \"denied\",\n ad_user_data: \"denied\",\n ad_personalization: \"denied\",\n};\n\nexport type GtmConsentCommand = [\"consent\", \"default\" | \"update\", GtmConsentModeUpdate];\ntype GtmPushEntry = GtmConsentCommand | GtmDataLayerEvent;\n\ninterface GtmDataLayer {\n push(entry: GtmPushEntry): number;\n}\n\n/**\n * Namespaced GTM event names emitted by the storefront adapter.\n */\nexport type GtmNamespacedEventName = `ekomerc.${GtmStandardEventName}`;\n\nconst GTM_TRIGGER_EVENT_MAP = Object.fromEntries(\n GTM_STANDARD_EVENTS.map((name) => [name, `ekomerc.${name}` as const]),\n) as { readonly [K in GtmStandardEventName]: `ekomerc.${K}` };\n\n/**\n * GTM ecommerce item payload derived from storefront analytics properties.\n */\nexport interface GtmItem {\n item_id: string;\n item_name?: string;\n item_variant?: string | null;\n price?: number;\n item_list_id?: string;\n item_list_name?: string;\n index?: number;\n item_category?: string;\n product_id?: string;\n variant_id?: string;\n sku?: string | null;\n quantity: number;\n unit_price?: number;\n line_total?: number;\n currency?: string;\n}\n\n/**\n * GTM attribution payload copied from captured UTM and click ID data.\n */\nexport interface GtmAttributionPayload {\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_term: string | null;\n utm_content: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n fbclid: string | null;\n ttclid: string | null;\n}\n\n/**\n * GTM page context payload copied from the storefront analytics event.\n */\nexport interface GtmContextPayload {\n path: string;\n referrer: string | null;\n}\n\n/**\n * GTM `ekomerc` payload pushed alongside each `dataLayer` event.\n */\nexport interface GtmEcommercePayload {\n event_name: GtmNamespacedEventName;\n event_id: string;\n consent_state: AnalyticsConsentState;\n context: GtmContextPayload;\n attribution: GtmAttributionPayload;\n ga4_campaign_override_active?: boolean;\n lead_type?: string;\n lead_source?: string;\n placement?: string;\n currency?: string;\n value?: number;\n order_id?: string;\n cart_id?: string;\n quantity?: number;\n items_count?: number;\n search_term?: string;\n results_count?: number;\n items?: GtmItem[];\n}\n\n/**\n * Full object pushed to the configured GTM data layer.\n */\nexport interface GtmDataLayerEvent {\n event: GtmNamespacedEventName;\n ekomerc: GtmEcommercePayload;\n}\n\n/**\n * GTM consent-mode update payload derived from storefront consent state.\n */\nexport interface GtmConsentModeUpdate {\n analytics_storage: \"granted\" | \"denied\";\n ad_storage: \"granted\" | \"denied\";\n ad_user_data: \"granted\" | \"denied\";\n ad_personalization: \"granted\" | \"denied\";\n}\n\n/**\n * Optional runtime overrides for the GTM browser adapter.\n */\nexport interface GtmBrowserAdapterOptions {\n dataLayerName?: string;\n getWindow?: () => object | null;\n debug?: boolean;\n initialConsentState?: ConsentCategoryState;\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isGtmDataLayer(value: unknown): value is GtmDataLayer {\n return isObjectRecord(value) && typeof value.push === \"function\";\n}\n\nfunction getStringProp(properties: Record<string, unknown>, key: string): string | null {\n const value = properties[key];\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction getNumberProp(properties: Record<string, unknown>, key: string): number | null {\n const value = properties[key];\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction getAmountValue(properties: Record<string, unknown>, keys: string[]): number | null {\n return getNumberPropFromKeys(properties, keys);\n}\n\nfunction normalizeQuantity(value: number | null): number {\n if (value === null) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction resolveItemId(properties: Record<string, unknown>): string | null {\n return (\n getStringProp(properties, \"itemId\") ??\n getStringProp(properties, \"item_id\") ??\n getStringProp(properties, \"contentId\") ??\n getStringProp(properties, \"content_id\") ??\n getStringProp(properties, \"variantId\") ??\n getStringProp(properties, \"variant_id\") ??\n getStringProp(properties, \"sku\") ??\n getStringProp(properties, \"productId\") ??\n getStringProp(properties, \"product_id\") ??\n getStringProp(properties, \"id\")\n );\n}\n\nfunction resolveProductId(properties: Record<string, unknown>): string | null {\n return (\n getStringProp(properties, \"productId\") ?? getStringProp(properties, \"product_id\") ?? getStringProp(properties, \"id\")\n );\n}\n\nfunction buildItem(properties: Record<string, unknown>, currency: string): GtmItem | null {\n const itemId = resolveItemId(properties);\n if (!itemId) {\n return null;\n }\n\n const quantity = normalizeQuantity(getNumberProp(properties, \"quantity\"));\n const unitPrice = getAmountValue(properties, [\"unitPrice\", \"unit_price\", \"price\"]) ?? 0;\n const lineTotal = getAmountValue(properties, [\"lineTotal\", \"line_total\", \"total\"]) ?? unitPrice * quantity;\n\n const item: GtmItem = {\n item_id: itemId,\n quantity,\n };\n\n const itemName =\n getStringProp(properties, \"itemName\") ??\n getStringProp(properties, \"item_name\") ??\n getStringProp(properties, \"productTitle\");\n if (itemName) {\n item.item_name = itemName;\n }\n\n const itemVariant =\n getStringProp(properties, \"itemVariant\") ??\n getStringProp(properties, \"item_variant\") ??\n getStringProp(properties, \"variantTitle\");\n if (itemVariant || properties.itemVariant === null || properties.variantTitle === null) {\n item.item_variant = itemVariant;\n }\n\n if (unitPrice > 0) {\n item.price = unitPrice;\n item.unit_price = unitPrice;\n }\n\n if (lineTotal > 0) {\n item.line_total = lineTotal;\n }\n\n if (currency) {\n item.currency = currency;\n }\n\n const itemListId =\n getStringProp(properties, \"itemListId\") ??\n getStringProp(properties, \"item_list_id\") ??\n getStringProp(properties, \"listId\");\n if (itemListId) {\n item.item_list_id = itemListId;\n }\n\n const itemListName =\n getStringProp(properties, \"itemListName\") ??\n getStringProp(properties, \"item_list_name\") ??\n getStringProp(properties, \"listName\");\n if (itemListName) {\n item.item_list_name = itemListName;\n }\n\n const index = getNumberProp(properties, \"index\");\n if (index !== null) {\n item.index = Math.max(0, Math.floor(index));\n }\n\n const itemCategory = getStringProp(properties, \"itemCategory\") ?? getStringProp(properties, \"item_category\");\n if (itemCategory) {\n item.item_category = itemCategory;\n }\n\n const productId = resolveProductId(properties);\n if (productId) {\n item.product_id = productId;\n }\n\n const variantId = getStringProp(properties, \"variantId\") ?? getStringProp(properties, \"variant_id\");\n if (variantId) {\n item.variant_id = variantId;\n }\n\n const sku = getStringProp(properties, \"sku\");\n if (sku || properties.sku === null) {\n item.sku = sku;\n }\n\n return item;\n}\n\nfunction buildNormalizedItems(\n eventName: GtmStandardEventName,\n properties: AnalyticsProperties,\n currency: string,\n): GtmItem[] {\n const rawLineItems = properties.lineItems;\n if (Array.isArray(rawLineItems)) {\n const items: GtmItem[] = [];\n for (const lineItem of rawLineItems) {\n if (!isObjectRecord(lineItem)) {\n continue;\n }\n\n const mappedItem = buildItem(lineItem, currency);\n if (mappedItem) {\n items.push(mappedItem);\n }\n }\n\n if (items.length > 0) {\n return items;\n }\n }\n\n if (\n eventName === \"view_item\" ||\n eventName === \"select_item\" ||\n eventName === \"add_to_cart\" ||\n eventName === \"remove_from_cart\" ||\n eventName === \"view_cart\" ||\n eventName === \"begin_checkout\" ||\n eventName === \"purchase\"\n ) {\n const singleItem = buildItem(properties, currency);\n return singleItem ? [singleItem] : [];\n }\n\n return [];\n}\n\nfunction sumItemValue(items: GtmItem[]): number | null {\n if (items.length === 0) {\n return null;\n }\n\n let total = 0;\n let hasPricedItem = false;\n\n for (const item of items) {\n if (typeof item.line_total === \"number\" && Number.isFinite(item.line_total)) {\n total += item.line_total;\n hasPricedItem = true;\n } else if (typeof item.price === \"number\" && Number.isFinite(item.price)) {\n total += item.price * item.quantity;\n hasPricedItem = true;\n } else if (typeof item.unit_price === \"number\" && Number.isFinite(item.unit_price)) {\n total += item.unit_price * item.quantity;\n hasPricedItem = true;\n }\n }\n\n if (!hasPricedItem) {\n return null;\n }\n\n return Number.isFinite(total) ? total : null;\n}\n\nfunction buildAttributionPayload(input: AnalyticsAdapterDispatchInput): GtmAttributionPayload {\n return {\n utm_source: input.event.utm.source,\n utm_medium: input.event.utm.medium,\n utm_campaign: input.event.utm.campaign,\n utm_term: input.event.utm.term,\n utm_content: input.event.utm.content,\n gclid: input.event.clickIds.gclid,\n gbraid: input.event.clickIds.gbraid,\n wbraid: input.event.clickIds.wbraid,\n fbclid: input.event.clickIds.fbclid,\n ttclid: input.event.clickIds.ttclid,\n };\n}\n\nconst CHECKOUT_STEP_GTM_EVENT_MAP: Record<string, GtmNamespacedEventName | null> = {\n shipping: \"ekomerc.add_shipping_info\",\n payment: \"ekomerc.add_payment_info\",\n};\n\nfunction assignEcommerceFields(\n ekomerc: GtmEcommercePayload,\n properties: AnalyticsProperties,\n providerEventName: GtmStandardEventName,\n): void {\n const currency = getStringProp(properties, \"currency\") ?? \"\";\n const items = buildNormalizedItems(providerEventName, properties, currency);\n const itemValue = sumItemValue(items);\n const fallbackValue = getAmountValue(properties, [\"value\", \"total\", \"orderTotal\", \"cartValue\"]);\n const value = itemValue ?? fallbackValue;\n const quantity = getNumberProp(properties, \"quantity\");\n const itemsCount = getNumberPropFromKeys(properties, [\"itemsCount\", \"numItems\"]);\n\n if (currency) {\n ekomerc.currency = currency;\n }\n\n if (value !== null) {\n ekomerc.value = value;\n }\n\n const cartId = getStringProp(properties, \"cartId\");\n if (cartId) {\n ekomerc.cart_id = cartId;\n }\n\n const orderId = getStringProp(properties, \"orderId\");\n if (orderId) {\n ekomerc.order_id = orderId;\n }\n\n if (quantity !== null) {\n ekomerc.quantity = quantity;\n }\n\n if (itemsCount !== null) {\n ekomerc.items_count = itemsCount;\n } else if (items.length > 0) {\n ekomerc.items_count = items.reduce((sum, item) => sum + item.quantity, 0);\n }\n\n if (items.length > 0) {\n ekomerc.items = items;\n }\n}\n\nfunction assignLeadFields(ekomerc: GtmEcommercePayload, properties: AnalyticsProperties): void {\n const leadType = getStringProp(properties, \"leadType\") ?? getStringProp(properties, \"lead_type\");\n const leadSource = getStringProp(properties, \"source\") ?? getStringProp(properties, \"leadSource\");\n const placement = getStringProp(properties, \"placement\");\n const currency = getStringProp(properties, \"currency\") ?? \"\";\n const value = getAmountValue(properties, [\"value\"]);\n\n if (leadType) {\n ekomerc.lead_type = leadType;\n }\n if (leadSource) {\n ekomerc.lead_source = leadSource;\n }\n if (placement) {\n ekomerc.placement = placement;\n }\n if (currency) {\n ekomerc.currency = currency;\n }\n if (value !== null) {\n ekomerc.value = value;\n }\n}\n\nfunction buildCheckoutStepDataLayerEvent(input: AnalyticsAdapterDispatchInput): GtmDataLayerEvent | null {\n const step = getStringProp(input.event.properties, \"step\");\n const eventName = step ? (CHECKOUT_STEP_GTM_EVENT_MAP[step] ?? null) : null;\n if (!eventName) {\n return null;\n }\n\n const dedupe = getTrackingProviderDedupeConvention(\"gtm\");\n\n const ekomerc: GtmEcommercePayload = {\n event_name: eventName,\n event_id: input.event[dedupe.canonicalEventIdField],\n consent_state: input.event.consentState,\n context: {\n path: input.event.context.path,\n referrer: input.event.referrer,\n },\n attribution: buildAttributionPayload(input),\n };\n assignEcommerceFields(ekomerc, input.event.properties, eventName.replace(\"ekomerc.\", \"\") as GtmStandardEventName);\n\n return { event: eventName, ekomerc };\n}\n\n/**\n * Maps a storefront analytics event to a GTM `dataLayer.push()` payload.\n */\nexport function buildGtmDataLayerEvent(input: AnalyticsAdapterDispatchInput): GtmDataLayerEvent | null {\n if (input.event.eventType === \"analytics.checkout_step_completed\") {\n return buildCheckoutStepDataLayerEvent(input);\n }\n\n const providerEventName = getTrackingProviderEventName(\"gtm\", input.event.eventType);\n if (providerEventName === null) {\n return null;\n }\n\n const eventName = GTM_TRIGGER_EVENT_MAP[providerEventName];\n const dedupe = getTrackingProviderDedupeConvention(\"gtm\");\n\n const ekomerc: GtmEcommercePayload = {\n event_name: eventName,\n event_id: input.event[dedupe.canonicalEventIdField],\n consent_state: input.event.consentState,\n context: {\n path: input.event.context.path,\n referrer: input.event.referrer,\n },\n attribution: buildAttributionPayload(input),\n };\n\n if (\n providerEventName === \"page_view\" &&\n input.event.properties[INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY] === true\n ) {\n ekomerc.ga4_campaign_override_active = true;\n }\n\n if (providerEventName === \"search\") {\n const query = getStringProp(input.event.properties, \"query\");\n if (query) {\n ekomerc.search_term = query;\n }\n\n const resultsCount = getNumberProp(input.event.properties, \"resultsCount\");\n if (resultsCount !== null) {\n ekomerc.results_count = resultsCount;\n }\n }\n\n if (providerEventName === \"generate_lead\") {\n assignLeadFields(ekomerc, input.event.properties);\n } else if (providerEventName !== \"page_view\" && providerEventName !== \"search\") {\n assignEcommerceFields(ekomerc, input.event.properties, providerEventName);\n }\n\n return {\n event: eventName,\n ekomerc,\n };\n}\n\n/**\n * Converts storefront consent state into a GTM consent-mode update payload.\n * Accepts either an `AnalyticsConsentUpdate` (overall state) or a per-category `ConsentCategoryState`.\n */\nexport function buildGtmConsentModeUpdate(input: AnalyticsConsentUpdate | ConsentCategoryState): GtmConsentModeUpdate {\n if (\"consentState\" in input) {\n const consentValue = input.consentState === \"granted\" ? \"granted\" : \"denied\";\n return {\n analytics_storage: consentValue,\n ad_storage: consentValue,\n ad_user_data: consentValue,\n ad_personalization: consentValue,\n };\n }\n\n return {\n analytics_storage: input.analytics_storage === \"granted\" ? \"granted\" : \"denied\",\n ad_storage: input.ad_storage === \"granted\" ? \"granted\" : \"denied\",\n ad_user_data: input.ad_user_data === \"granted\" ? \"granted\" : \"denied\",\n ad_personalization: input.ad_personalization === \"granted\" ? \"granted\" : \"denied\",\n };\n}\n\nfunction getDataLayer(windowObject: object, dataLayerName: string): GtmDataLayer | null {\n const dataLayer = Reflect.get(windowObject, dataLayerName);\n if (isGtmDataLayer(dataLayer)) {\n return dataLayer;\n }\n\n if (dataLayer !== undefined && dataLayer !== null) {\n return null;\n }\n\n const initializedDataLayer: GtmPushEntry[] = [];\n if (!Reflect.set(windowObject, dataLayerName, initializedDataLayer)) {\n return null;\n }\n\n return initializedDataLayer;\n}\n\nfunction pushConsentCommand(\n windowObject: object,\n dataLayer: GtmDataLayer,\n mode: \"default\" | \"update\",\n consentUpdate: GtmConsentModeUpdate,\n): void {\n const gtag = Reflect.get(windowObject, \"gtag\");\n if (typeof gtag === \"function\") {\n gtag(\"consent\", mode, consentUpdate);\n return;\n }\n\n dataLayer.push([\"consent\", mode, consentUpdate]);\n}\n\nfunction runtimeUnavailable(): AnalyticsAdapterOperationResult {\n return {\n status: \"skipped\",\n reason: \"runtime_unavailable\",\n };\n}\n\n/**\n * Creates a GTM browser adapter that pushes storefront analytics events into `window.dataLayer`.\n */\nexport function createGtmBrowserAdapter(\n config: GtmBrowserTrackingConfig,\n options: GtmBrowserAdapterOptions = {},\n): AnalyticsBrowserAdapter | null {\n const supportRule = getTrackingProviderSupportRule(\"gtm\");\n const debug = options.debug === true;\n\n if (!supportRule.supportsBrowserDispatch || !config.enabled || !config.containerId) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM adapter not created:\", {\n supportsBrowserDispatch: supportRule.supportsBrowserDispatch,\n enabled: config.enabled,\n containerId: config.containerId ?? null,\n });\n }\n return null;\n }\n\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM adapter created:\", {\n containerId: config.containerId,\n dataLayerName: options.dataLayerName ?? DEFAULT_DATA_LAYER_NAME,\n });\n }\n\n const dataLayerName = options.dataLayerName ?? DEFAULT_DATA_LAYER_NAME;\n let consentDefaultsApplied = false;\n\n function applyConsentDefaults(windowObject: object, dataLayer: GtmDataLayer): void {\n if (consentDefaultsApplied) {\n return;\n }\n\n const defaultState = options.initialConsentState\n ? buildGtmConsentModeUpdate(options.initialConsentState)\n : GTM_CONSENT_DEFAULT_STATE;\n pushConsentCommand(windowObject, dataLayer, \"default\", defaultState);\n consentDefaultsApplied = true;\n }\n\n return {\n provider: \"gtm\",\n dispatch(input) {\n const payload = buildGtmDataLayerEvent(input);\n if (payload === null) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: no payload for event\", input.event.eventType);\n }\n return {\n status: \"success\",\n };\n }\n\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: window unavailable\");\n }\n return runtimeUnavailable();\n }\n\n const dataLayer = getDataLayer(windowObject, dataLayerName);\n if (!dataLayer) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: dataLayer unavailable\");\n }\n return runtimeUnavailable();\n }\n\n applyConsentDefaults(windowObject, dataLayer);\n dataLayer.push(payload);\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dataLayer.push:\", payload);\n }\n return {\n status: \"success\",\n };\n },\n updateConsent(input) {\n if (!supportRule.requiresConsentBridge) {\n return {\n status: \"success\",\n };\n }\n\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n return runtimeUnavailable();\n }\n\n const dataLayer = getDataLayer(windowObject, dataLayerName);\n if (!dataLayer) {\n return runtimeUnavailable();\n }\n\n applyConsentDefaults(windowObject, dataLayer);\n const consentUpdate = buildGtmConsentModeUpdate(input);\n pushConsentCommand(windowObject, dataLayer, \"update\", consentUpdate);\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM consent update:\", consentUpdate);\n }\n return {\n status: \"success\",\n };\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport type { StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\n// GQL queries/mutations\n\nconst SIGNUP_OFFER_QUERY = `\nquery SignupOffer {\n signupOffer {\n id\n enabled\n headline\n body\n submitLabel\n successTitle\n successBody\n triggerDelaySeconds\n frequencyCapDays\n promotionSummary {\n promotionId\n discountType\n discountValue\n description\n }\n }\n}\n`;\n\nconst SIGNUP_OFFER_SUBSCRIBE_MUTATION = `\nmutation SignupOfferSubscribe($input: SignupOfferSubscribeInput!) {\n signupOfferSubscribe(input: $input) {\n success\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst BACK_IN_STOCK_SUBSCRIBE_MUTATION = `\nmutation BackInStockSubscribe($input: BackInStockSubscribeInput!) {\n backInStockSubscribe(input: $input) {\n success\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\n// Types\n\ninterface SignupOfferApiConfig {\n enabled: boolean;\n id: string;\n headline: string;\n body: string | null;\n submitLabel: string;\n successTitle: string;\n successBody: string | null;\n triggerDelaySeconds: number;\n frequencyCapDays: number;\n promotionSummary: {\n promotionId: string;\n discountType: string;\n discountValue: number;\n description: string | null;\n } | null;\n}\n\nexport interface SignupOfferConfig extends SignupOfferApiConfig {\n shouldShow: boolean;\n}\n\nexport interface SignupOfferLocalState {\n lastSeenAt: number | null;\n dismissedUntil: number | null;\n subscribed: boolean;\n}\n\nexport interface MarketingUserError {\n field: string[];\n message: string;\n code?: string;\n}\n\nexport interface BackInStockSubscribeResult {\n success: boolean;\n userErrors: MarketingUserError[];\n}\n\nexport interface MarketingOperations {\n getSignupOffer(): Promise<Result<SignupOfferConfig | null, StorefrontError>>;\n subscribeToSignupOffer(input: {\n email: string;\n pageUrl?: string;\n referrerUrl?: string;\n }): Promise<Result<{ success: boolean }, StorefrontError>>;\n backInStockSubscribe(input: {\n productId: string;\n variantId: string;\n email: string;\n }): Promise<Result<BackInStockSubscribeResult, StorefrontError>>;\n getSignupOfferState(offerId: string): SignupOfferLocalState;\n markSignupOfferSeen(input: { offerId: string; at?: number }): void;\n dismissSignupOffer(input: { offerId: string; until?: number }): void;\n clearSignupOfferState(offerId: string): void;\n}\n\n// Response types\n\ninterface SignupOfferQueryResponse {\n signupOffer: SignupOfferApiConfig | null;\n}\n\ninterface SignupOfferSubscribeResponse {\n signupOfferSubscribe: {\n success: boolean;\n userErrors: Array<{ field: string[]; message: string; code?: string }>;\n };\n}\n\ninterface BackInStockSubscribeResponse {\n backInStockSubscribe: {\n success: boolean;\n userErrors: MarketingUserError[];\n };\n}\n\n// Storage keys\n\nfunction stateKey(offerId: string): string {\n return `ekomerc:signup_offer:${offerId}:state`;\n}\n\nfunction parseState(raw: string | null): SignupOfferLocalState {\n if (!raw) return { lastSeenAt: null, dismissedUntil: null, subscribed: false };\n try {\n const parsed = JSON.parse(raw) as Partial<SignupOfferLocalState>;\n return {\n lastSeenAt: typeof parsed.lastSeenAt === \"number\" ? parsed.lastSeenAt : null,\n dismissedUntil: typeof parsed.dismissedUntil === \"number\" ? parsed.dismissedUntil : null,\n subscribed: parsed.subscribed === true,\n };\n } catch {\n return { lastSeenAt: null, dismissedUntil: null, subscribed: false };\n }\n}\n\nfunction computeShouldShow(\n client: StorefrontClientContext,\n config: SignupOfferApiConfig,\n localState: SignupOfferLocalState,\n): boolean {\n if (!config.enabled) return false;\n if (localState.subscribed) return false;\n\n if (client.getCustomerToken() !== null) return false;\n\n if (typeof window !== \"undefined\" && window.location.pathname.startsWith(\"/checkout\")) {\n return false;\n }\n\n const now = Date.now();\n\n if (localState.dismissedUntil !== null && now < localState.dismissedUntil) {\n return false;\n }\n\n if (localState.lastSeenAt !== null && config.frequencyCapDays > 0) {\n const capMs = config.frequencyCapDays * 24 * 60 * 60 * 1000;\n if (now - localState.lastSeenAt < capMs) {\n return false;\n }\n }\n\n return true;\n}\n\n// Factory\n\nexport function createMarketingOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n analyticsEmit: AnalyticsEmitFn | null = null,\n): MarketingOperations {\n let lastOfferId: string | null = null;\n\n return {\n async getSignupOffer(): Promise<Result<SignupOfferConfig | null, StorefrontError>> {\n const result = await client.query<SignupOfferQueryResponse>({ query: SIGNUP_OFFER_QUERY }, { cache: true });\n if (result.isErr()) return err(result.error);\n const offer = result.value.signupOffer;\n if (!offer) {\n lastOfferId = null;\n return ok(null);\n }\n\n lastOfferId = offer.id;\n const localState = parseState(storage.get(stateKey(offer.id)));\n return ok({\n ...offer,\n shouldShow: computeShouldShow(client, offer, localState),\n });\n },\n\n async subscribeToSignupOffer(input): Promise<Result<{ success: boolean }, StorefrontError>> {\n const result = await client.mutate<SignupOfferSubscribeResponse>({\n query: SIGNUP_OFFER_SUBSCRIBE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) return err(result.error);\n\n const subscriptionSucceeded = result.value.signupOfferSubscribe.success === true;\n\n if (subscriptionSucceeded && lastOfferId) {\n const nextState = parseState(storage.get(stateKey(lastOfferId)));\n nextState.subscribed = true;\n storage.set(stateKey(lastOfferId), JSON.stringify(nextState));\n }\n\n if (subscriptionSucceeded) {\n analyticsEmit?.(\"analytics.lead_generated\", {\n leadType: \"newsletter_signup\",\n source: \"signup_offer\",\n ...(lastOfferId ? { signupOfferId: lastOfferId } : {}),\n });\n }\n\n return ok({ success: subscriptionSucceeded });\n },\n\n async backInStockSubscribe(input): Promise<Result<BackInStockSubscribeResult, StorefrontError>> {\n const result = await client.mutate<BackInStockSubscribeResponse>({\n query: BACK_IN_STOCK_SUBSCRIBE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.backInStockSubscribe;\n return ok({\n success: payload.success === true,\n userErrors: payload.userErrors ?? [],\n });\n },\n\n getSignupOfferState(offerId: string): SignupOfferLocalState {\n return parseState(storage.get(stateKey(offerId)));\n },\n\n markSignupOfferSeen(input: { offerId: string; at?: number }): void {\n const state = parseState(storage.get(stateKey(input.offerId)));\n state.lastSeenAt = input.at ?? Date.now();\n storage.set(stateKey(input.offerId), JSON.stringify(state));\n },\n\n dismissSignupOffer(input: { offerId: string; until?: number }): void {\n const state = parseState(storage.get(stateKey(input.offerId)));\n state.dismissedUntil = input.until ?? Number.MAX_SAFE_INTEGER;\n storage.set(stateKey(input.offerId), JSON.stringify(state));\n },\n\n clearSignupOfferState(offerId: string): void {\n storage.remove(stateKey(offerId));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { mapUserErrors, type UserError } from \"./cart-shared.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, StorefrontError as StorefrontSdkError } from \"./errors.ts\";\nimport {\n clearPaymentRecovery,\n finalizeRedirectPayment,\n isPaymentRef,\n type PaymentRecoveryRecord,\n paymentRecoveryExists,\n persistPaymentRecovery,\n readPaymentRecovery,\n resolvePaymentStoreId,\n} from \"./payment-lifecycle.ts\";\nimport type {\n AvailablePaymentMethod,\n Money,\n PaymentRedirectOutcome,\n PaymentReturnOutcome,\n PaymentReturnProgress,\n StorageAdapter,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ninterface AvailablePaymentMethodData {\n method: string;\n displayName: string;\n presentation: AvailablePaymentMethod[\"presentation\"];\n additionalFee: Money;\n}\n\ninterface AvailablePaymentMethodsResponse {\n availablePaymentMethods: AvailablePaymentMethodData[];\n}\n\ninterface PaymentStatusResult {\n status: \"pending\" | \"paid\" | \"failed\";\n orderNumber: string;\n}\n\ninterface PaymentStatusResponse {\n paymentStatus: PaymentStatusResult | null;\n}\n\ntype PaymentAction =\n | { kind: \"none\"; redirectUrl: null; paymentRef: null }\n | { kind: \"redirect\"; redirectUrl: string; paymentRef: string }\n | { kind: \"redirect_pending\"; redirectUrl: null; paymentRef: string };\n\ninterface PaymentSessionCreateResponse {\n paymentSessionCreate: {\n paymentAction: PaymentAction;\n userErrors: UserError[];\n };\n}\n\nconst PAYMENT_POLL_LIMIT = 30;\nconst PAYMENT_POLL_INTERVAL_MS = 2_000;\nconst MAX_TRANSIENT_FAILURES = 4;\nconst MAX_TRANSIENT_BACKOFF_MS = 8_000;\n\nconst AVAILABLE_PAYMENT_METHODS_QUERY = `\nquery AvailablePaymentMethods {\n availablePaymentMethods {\n method\n displayName\n presentation\n additionalFee { amount currency }\n }\n}\n`;\n\nconst PAYMENT_STATUS_QUERY = `\nquery PaymentStatus($ref: ID!) {\n paymentStatus(ref: $ref) {\n status\n orderNumber\n }\n}\n`;\n\nconst PAYMENT_SESSION_CREATE_MUTATION = `\nmutation PaymentSessionCreate($ref: ID!) {\n paymentSessionCreate(ref: $ref) {\n paymentAction {\n kind\n redirectUrl\n paymentRef\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nexport interface PaymentsOperations {\n /** Fetch payment methods currently available for checkout. */\n getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>>;\n resumeReturn(options?: {\n url?: string | URL;\n signal?: AbortSignal;\n onStateChange?: (state: PaymentReturnProgress) => void;\n }): Promise<Result<PaymentReturnOutcome, StorefrontError>>;\n retryRedirect(options?: {\n signal?: AbortSignal;\n navigate?: (url: string) => void;\n }): Promise<Result<PaymentRedirectOutcome, StorefrontError>>;\n clearReturn(): void;\n}\n\nfunction mapPaymentMethod(data: AvailablePaymentMethodData): AvailablePaymentMethod {\n return {\n method: data.method,\n displayName: data.displayName,\n presentation: data.presentation,\n additionalFee: data.additionalFee,\n };\n}\n\nfunction cancelledError(): StorefrontError {\n return new StorefrontSdkError(\"Payment return check was cancelled\", \"ABORTED\");\n}\n\nfunction waitFor(ms: number, signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted) return Promise.resolve(false);\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", abort);\n resolve(true);\n }, ms);\n function abort() {\n clearTimeout(timer);\n resolve(false);\n }\n signal?.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction resolveUrl(value?: string | URL): URL | null {\n if (value instanceof URL) return new URL(value.href);\n const fallback = typeof window !== \"undefined\" ? window.location.href : \"https://storefront.invalid/\";\n try {\n return new URL(value ?? fallback, fallback);\n } catch {\n return null;\n }\n}\n\nfunction readReturnRef(value?: string | URL): { ref: string | null; applicable: boolean } {\n const url = resolveUrl(value);\n if (!url || url.searchParams.get(\"payment\") !== \"return\") return { ref: null, applicable: false };\n const ref = url.searchParams.get(\"ref\");\n return { ref: ref && isPaymentRef(ref) ? ref : null, applicable: true };\n}\n\nfunction cleanBrowserReturnUrl(): void {\n if (typeof window === \"undefined\" || typeof window.history?.replaceState !== \"function\") return;\n const url = new URL(window.location.href);\n if (url.searchParams.get(\"payment\") !== \"return\") return;\n url.searchParams.delete(\"payment\");\n url.searchParams.delete(\"ref\");\n window.history.replaceState(window.history.state, \"\", `${url.pathname}${url.search}${url.hash}`);\n}\n\nfunction notify(callback: ((state: PaymentReturnProgress) => void) | undefined, state: PaymentReturnProgress): void {\n callback?.(state);\n}\n\nfunction updateRecovery(\n storage: StorageAdapter,\n record: PaymentRecoveryRecord | null,\n update: Partial<PaymentRecoveryRecord>,\n): Result<PaymentRecoveryRecord | null, StorefrontError> {\n if (!record) return ok(null);\n const next = { ...record, ...update };\n const result = persistPaymentRecovery(storage, next);\n return result.isErr() ? err(result.error) : ok(next);\n}\n\nfunction navigateTo(url: string, navigate?: (url: string) => void): Result<void, StorefrontError> {\n try {\n if (navigate) navigate(url);\n else if (typeof window !== \"undefined\") window.location.assign(url);\n return ok(undefined);\n } catch (cause) {\n return err(\n new StorefrontSdkError(\"Could not navigate to the payment provider\", \"NAVIGATION_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n }),\n );\n }\n}\n\nexport function createPaymentsOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n cache: CartSnapshotCache,\n consentManager: ConsentManager | null,\n): PaymentsOperations {\n async function fetchPaymentStatus(\n ref: string,\n signal?: AbortSignal,\n ): Promise<Result<PaymentStatusResult, StorefrontError>> {\n const result = await client.query<PaymentStatusResponse>(\n { query: PAYMENT_STATUS_QUERY, variables: { ref } },\n { cache: false, signal },\n );\n if (result.isErr()) return err(result.error);\n if (!result.value.paymentStatus) return err(new NotFoundError(\"Payment not found\"));\n return ok(result.value.paymentStatus);\n }\n\n return {\n async getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>> {\n const result = await client.query<AvailablePaymentMethodsResponse>(\n { query: AVAILABLE_PAYMENT_METHODS_QUERY },\n { cache: true },\n );\n if (result.isErr()) return err(result.error);\n if (!result.value.availablePaymentMethods) {\n return err(new NotFoundError(\"Payment methods not available\"));\n }\n return ok(result.value.availablePaymentMethods.map(mapPaymentMethod));\n },\n\n async resumeReturn(options): Promise<Result<PaymentReturnOutcome, StorefrontError>> {\n const urlReturn = readReturnRef(options?.url);\n if (options?.url === undefined && urlReturn.applicable) cleanBrowserReturnUrl();\n\n const recoveryExists = paymentRecoveryExists(storage);\n if (recoveryExists.isErr()) return err(recoveryExists.error);\n if (!urlReturn.applicable && !recoveryExists.value) {\n const outcome = { kind: \"not_applicable\" } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n const storeIdResult = await resolvePaymentStoreId(client, options?.signal);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const recoveryResult = readPaymentRecovery(storage, storeIdResult.value);\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n let recovery = recoveryResult.value;\n const paymentRef = recovery?.paymentRef ?? urlReturn.ref;\n if (!paymentRef) {\n const outcome = { kind: \"not_applicable\" } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n if (recovery?.phase === \"session_unavailable\") {\n const outcome = {\n kind: \"session_unavailable\",\n paymentRef,\n orderNumber: recovery.orderNumber,\n } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n if (recovery?.phase === \"failed\" && recovery.orderNumber) {\n const outcome = { kind: \"failed\", paymentRef, orderNumber: recovery.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n notify(options?.onStateChange, {\n kind: \"checking\",\n paymentRef,\n orderNumber: recovery?.orderNumber ?? null,\n });\n const checkingResult = updateRecovery(storage, recovery, { phase: \"checking\" });\n if (checkingResult.isErr()) return err(checkingResult.error);\n recovery = checkingResult.value;\n\n let transientFailures = 0;\n let lastTransientError: StorefrontError | null = null;\n for (let attempt = 0; attempt < PAYMENT_POLL_LIMIT; attempt += 1) {\n if (options?.signal?.aborted) return err(cancelledError());\n const statusResult = await fetchPaymentStatus(paymentRef, options?.signal);\n if (statusResult.isErr()) {\n if (options?.signal?.aborted) return err(cancelledError());\n if (statusResult.error.code !== \"NETWORK_ERROR\") return err(statusResult.error);\n lastTransientError = statusResult.error;\n transientFailures += 1;\n if (transientFailures >= MAX_TRANSIENT_FAILURES) return err(lastTransientError);\n const continued = await waitFor(\n Math.min(1_000 * 2 ** (transientFailures - 1), MAX_TRANSIENT_BACKOFF_MS),\n options?.signal,\n );\n if (!continued) return err(cancelledError());\n continue;\n }\n\n transientFailures = 0;\n const status = statusResult.value;\n if (status.status === \"paid\") {\n if (recovery) finalizeRedirectPayment({ client, storage, cache, consentManager }, recovery);\n const outcome = { kind: \"paid\", paymentRef, orderNumber: status.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n if (status.status === \"failed\") {\n const failedResult = updateRecovery(storage, recovery, {\n phase: \"failed\",\n orderNumber: status.orderNumber,\n });\n if (failedResult.isErr()) return err(failedResult.error);\n const outcome = { kind: \"failed\", paymentRef, orderNumber: status.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n const pendingResult = updateRecovery(storage, recovery, {\n phase: \"pending\",\n orderNumber: status.orderNumber,\n });\n if (pendingResult.isErr()) return err(pendingResult.error);\n recovery = pendingResult.value;\n notify(options?.onStateChange, {\n kind: \"checking\",\n paymentRef,\n orderNumber: status.orderNumber,\n });\n const continued = await waitFor(PAYMENT_POLL_INTERVAL_MS, options?.signal);\n if (!continued) return err(cancelledError());\n }\n\n const outcome = {\n kind: \"pending\",\n paymentRef,\n orderNumber: recovery?.orderNumber ?? null,\n reason: \"confirmation_timeout\",\n } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n },\n\n async retryRedirect(options): Promise<Result<PaymentRedirectOutcome, StorefrontError>> {\n if (options?.signal?.aborted) return err(cancelledError());\n const storeIdResult = await resolvePaymentStoreId(client, options?.signal);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const recoveryResult = readPaymentRecovery(storage, storeIdResult.value);\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n const recovery = recoveryResult.value;\n if (!recovery || recovery.phase !== \"session_unavailable\") {\n return err(new StateError(\"Payment redirect can only be retried while its session is unavailable\", \"not_open\"));\n }\n\n const result = await client.mutate<PaymentSessionCreateResponse>(\n { query: PAYMENT_SESSION_CREATE_MUTATION, variables: { ref: recovery.paymentRef } },\n { signal: options?.signal },\n );\n if (result.isErr()) return err(result.error);\n const payload = result.value.paymentSessionCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (payload.paymentAction.kind === \"redirect_pending\" || userError?.code === \"PAYMENT_SESSION_FAILED\") {\n const persisted = persistPaymentRecovery(storage, { ...recovery, phase: \"session_unavailable\" });\n if (persisted.isErr()) return err(persisted.error);\n return ok({\n kind: \"session_unavailable\",\n paymentRef: recovery.paymentRef,\n orderNumber: recovery.orderNumber,\n });\n }\n if (userError) return err(userError);\n if (\n payload.paymentAction.kind !== \"redirect\" ||\n payload.paymentAction.paymentRef !== recovery.paymentRef ||\n !isPaymentRef(payload.paymentAction.paymentRef)\n ) {\n return err(new StateError(\"Payment provider did not return a usable redirect\", \"session_unavailable\"));\n }\n\n const persisted = persistPaymentRecovery(storage, { ...recovery, phase: \"redirecting\" });\n if (persisted.isErr()) return err(persisted.error);\n const navigation = navigateTo(payload.paymentAction.redirectUrl, options?.navigate);\n if (navigation.isErr()) return err(navigation.error);\n return ok({\n kind: \"redirecting\",\n paymentRef: recovery.paymentRef,\n orderNumber: recovery.orderNumber,\n });\n },\n\n clearReturn(): void {\n clearPaymentRecovery(storage);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type {\n DetailSection,\n DisplayIntent,\n PaginatedResult,\n Product,\n ProductFilter,\n ProductSortKey,\n StorefrontClientContext,\n} from \"./types.ts\";\nimport { normalizeProductAssetUrls } from \"./url.ts\";\n\ninterface RawDetailSection {\n id: string;\n title: string;\n sectionType: string;\n content: Record<string, unknown>;\n displayIntent: string;\n position: number;\n}\n\ntype RawProduct = Omit<Product, \"detailSections\"> & { detailSections: RawDetailSection[] };\n\nfunction mapDisplayIntent(raw: string): DisplayIntent {\n switch (raw) {\n case \"ACCORDION\":\n return \"ACCORDION\";\n case \"SPECIFICATIONS\":\n return \"SPECIFICATIONS\";\n case \"BOTH\":\n return \"BOTH\";\n default:\n return \"ACCORDION\";\n }\n}\n\nfunction mapDetailSection(raw: RawDetailSection): DetailSection {\n const base = {\n id: raw.id,\n title: raw.title,\n displayIntent: mapDisplayIntent(raw.displayIntent),\n position: raw.position,\n };\n switch (raw.sectionType) {\n case \"RICH_TEXT\":\n return { ...base, sectionType: \"RICH_TEXT\", content: { html: raw.content.html as string } };\n case \"BULLET_LIST\":\n return { ...base, sectionType: \"BULLET_LIST\", content: { items: raw.content.items as string[] } };\n case \"TABLE\":\n return { ...base, sectionType: \"TABLE\", content: { rows: raw.content.rows as [string, string][] } };\n default:\n return { ...base, sectionType: \"RICH_TEXT\", content: { html: \"\" } };\n }\n}\n\nfunction mapProduct(raw: RawProduct): Product {\n return { ...raw, detailSections: raw.detailSections.map(mapDetailSection) };\n}\n\nexport interface ProductsListOptions {\n first?: number;\n after?: string;\n filter?: ProductFilter;\n sort?: ProductSortKey;\n}\n\ninterface ProductEdge {\n node: RawProduct;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface ProductsQueryResponse {\n products: ProductConnection;\n}\n\ninterface ProductQueryResponse {\n product: RawProduct | null;\n}\n\ninterface ProductsByHandlesQueryResponse {\n productsByHandles: (RawProduct | null)[];\n}\n\ninterface ProductsByIdsQueryResponse {\n productsByIds: (RawProduct | null)[];\n}\n\nconst PRODUCTS_QUERY = `\nquery Products($first: Int, $after: String, $filter: ProductFilter, $sort: ProductSortKey) {\n products(first: $first, after: $after, filter: $filter, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst PRODUCT_BY_ID_QUERY = `\nquery ProductById($id: ID!) {\n product(id: $id) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCT_BY_HANDLE_QUERY = `\nquery ProductByHandle($handle: String!) {\n product(handle: $handle) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCTS_BY_HANDLES_QUERY = `\nquery ProductsByHandles($handles: [String!]!) {\n productsByHandles(handles: $handles) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCTS_BY_IDS_QUERY = `\nquery ProductsByIds($ids: [ID!]!) {\n productsByIds(ids: $ids) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nexport interface ProductsOperations {\n listAll(filter?: ProductFilter): Promise<Result<Product[], StorefrontError>>;\n /**\n * List products with cursor pagination and optional filters.\n *\n * @param options - Pagination, search, and sort options.\n * @returns Paginated storefront products.\n */\n list(options?: ProductsListOptions): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n /**\n * Fetch a single product by UUID.\n *\n * @param id - Product UUID.\n * @returns The matching product.\n */\n byId(id: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch a single product by handle.\n *\n * @param handle - Product handle.\n * @returns The matching product.\n */\n byHandle(handle: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch a single product by handle.\n *\n * @param handle - Product handle.\n * @returns The matching product.\n */\n get(handle: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch multiple products by handle in request order.\n *\n * @param handles - Product handles to resolve.\n * @returns Products for each requested handle, with `null` for missing entries.\n */\n getByHandles(handles: string[]): Promise<Result<(Product | null)[], StorefrontError>>;\n /**\n * Fetch multiple products by UUID in request order.\n *\n * @param ids - Product UUIDs to resolve.\n * @returns Products for each requested UUID, with `null` for missing or inaccessible entries.\n */\n productsByIds(ids: string[]): Promise<Result<(Product | null)[], StorefrontError>>;\n}\n\nexport function createProductsOperations(client: StorefrontClientContext, emit?: AnalyticsEmitFn): ProductsOperations {\n const operations: ProductsOperations = {\n listAll: (filter) => collectAllPages((options) => operations.list({ ...options, filter })),\n async list(options?: ProductsListOptions): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<ProductsQueryResponse>({\n query: PRODUCTS_QUERY,\n variables: {\n first: options?.first,\n after: options?.after,\n filter: options?.filter,\n sort: options?.sort,\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const connection = result.value.products;\n\n if (emit && options?.filter?.search) {\n emit(\"analytics.search_performed\", {\n query: options.filter.search,\n resultsCount: connection.edges.length,\n });\n }\n\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(mapProduct(edge.node), client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async byId(id: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${id}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${handle}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${handle}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async getByHandles(handles: string[]): Promise<Result<(Product | null)[], StorefrontError>> {\n if (handles.length === 0) {\n return ok([]);\n }\n\n const result = await client.query<ProductsByHandlesQueryResponse>({\n query: PRODUCTS_BY_HANDLES_QUERY,\n variables: { handles },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(\n result.value.productsByHandles.map((product) =>\n product ? normalizeProductAssetUrls(mapProduct(product), client.config.endpoint) : null,\n ),\n );\n },\n\n async productsByIds(ids: string[]): Promise<Result<(Product | null)[], StorefrontError>> {\n if (ids.length === 0) {\n return ok([]);\n }\n\n const result = await client.query<ProductsByIdsQueryResponse>({\n query: PRODUCTS_BY_IDS_QUERY,\n variables: { ids },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(\n result.value.productsByIds.map((product) =>\n product ? normalizeProductAssetUrls(mapProduct(product), client.config.endpoint) : null,\n ),\n );\n },\n };\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Money, ShippingRate, StorefrontClientContext } from \"./types.ts\";\n\ninterface ShippingRateData {\n id: string;\n name: string;\n price: Money;\n minOrderAmount: Money | null;\n estimatedDaysMin: number | null;\n estimatedDaysMax: number | null;\n isFree: boolean;\n}\n\ninterface AvailableShippingRatesResponse {\n availableShippingRates: ShippingRateData[];\n}\n\nconst AVAILABLE_SHIPPING_RATES_QUERY = `\nquery AvailableShippingRates {\n availableShippingRates {\n id\n name\n price { amount currency }\n minOrderAmount { amount currency }\n estimatedDaysMin\n estimatedDaysMax\n isFree\n }\n}\n`;\n\nfunction mapShippingRate(data: ShippingRateData): ShippingRate {\n return {\n id: data.id,\n name: data.name,\n price: data.price,\n minOrderAmount: data.minOrderAmount,\n estimatedDaysMin: data.estimatedDaysMin,\n estimatedDaysMax: data.estimatedDaysMax,\n isFree: data.isFree,\n };\n}\n\nexport interface ShippingOperations {\n /**\n * Fetch shipping rates currently available for checkout.\n *\n * @returns Available shipping rates.\n */\n getAvailableRates(): Promise<Result<ShippingRate[], StorefrontError>>;\n}\n\nexport function createShippingOperations(client: StorefrontClientContext): ShippingOperations {\n return {\n async getAvailableRates(): Promise<Result<ShippingRate[], StorefrontError>> {\n const result = await client.query<AvailableShippingRatesResponse>(\n { query: AVAILABLE_SHIPPING_RATES_QUERY },\n { cache: false },\n );\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.availableShippingRates) {\n return err(new NotFoundError(\"Shipping rates not available\"));\n }\n\n return ok(result.value.availableShippingRates.map(mapShippingRate));\n },\n };\n}\n","import { err, ok } from \"neverthrow\";\nimport type { Store, StorefrontClientContext, StorefrontResult } from \"./types.ts\";\n\n/**\n * Store-level read operations exposed by the storefront SDK.\n */\nexport interface StoreOperations {\n get(options?: { cache?: boolean }): Promise<StorefrontResult<Store>>;\n}\n\ninterface StoreQueryResponse {\n store: Store;\n}\n\nconst STORE_QUERY = `\nquery Store {\n store {\n id\n name\n slug\n description\n currency\n timezone\n locale\n contactEmail\n contactPhone\n branding {\n tagline\n logoUrl\n socialLinks {\n instagram\n facebook\n tiktok\n twitter\n youtube\n }\n contactInfo {\n email\n phone\n address\n }\n }\n browserTrackingConfig {\n gtm {\n enabled\n containerId\n }\n }\n analytics {\n enabled\n firstPartyEnabled\n gtm {\n enabled\n containerId\n }\n }\n }\n}\n`;\n\nexport function createStoreOperations(client: StorefrontClientContext): StoreOperations {\n return {\n async get(options?: { cache?: boolean }): Promise<StorefrontResult<Store>> {\n const result = await client.query<StoreQueryResponse>(\n {\n query: STORE_QUERY,\n },\n options,\n );\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(result.value.store);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type AccountOperations, createAccountOperations } from \"./account.ts\";\nimport { type AnalyticsOperations, createAnalyticsOperations } from \"./analytics.ts\";\nimport { type AuthOperations, createAuthOperations } from \"./auth.ts\";\nimport { createQueryCache, type QueryCache } from \"./cache.ts\";\nimport { type CartOperations, createCartOperations } from \"./cart.ts\";\nimport { createCartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport { type CategoriesOperations, createCategoriesOperations } from \"./categories.ts\";\nimport { type CheckoutOperations, createCheckoutOperations } from \"./checkout.ts\";\nimport { type CollectionsOperations, createCollectionsOperations } from \"./collections.ts\";\nimport { type ConsentBufferEntry, type ConsentManager, createConsentManager } from \"./consent.ts\";\nimport {\n createMenusOperations,\n createPagesOperations,\n createPoliciesOperations,\n type MenusOperations,\n type PagesOperations,\n type PoliciesOperations,\n} from \"./content.ts\";\nimport { createDebugBrowserAdapter } from \"./debug-browser-adapter.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { createGraphQLClient, type GraphQLClient, type GraphQLRequest } from \"./graphql-client.ts\";\nimport { createGtmBrowserAdapter } from \"./gtm-browser-adapter.ts\";\nimport { createMarketingOperations, type MarketingOperations } from \"./marketing.ts\";\nimport { createPaymentsOperations, type PaymentsOperations } from \"./payments.ts\";\nimport { createProductsOperations, type ProductsOperations } from \"./products.ts\";\nimport { createShippingOperations, type ShippingOperations } from \"./shipping.ts\";\nimport {\n CART_SESSION_KEY,\n CUSTOMER_SESSION_KEY,\n createDefaultAdapter,\n createNamespacedAdapter,\n getCheckoutLeadDispatchKey,\n getMarketStorageKey,\n getMarketStorageKeyByStoreId,\n isSandboxApiKey,\n} from \"./storage.ts\";\nimport { createStoreOperations, type StoreOperations } from \"./store.ts\";\nimport type {\n ResolvedStorefrontInitConfig,\n StorageAdapter,\n StorefrontAnalyticsInitConfig,\n StorefrontClientConfig,\n StorefrontClientContext,\n StorefrontInitOptions,\n} from \"./types.ts\";\n\nconst DEFAULT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport interface CacheHelpers {\n /**\n * Clear all cached query results for this client instance.\n */\n clear(): void;\n}\n\nexport interface StorefrontClient extends StorefrontClientContext {\n readonly cache: CacheHelpers;\n readonly products: ProductsOperations;\n readonly pages: PagesOperations;\n readonly policies: PoliciesOperations;\n readonly menus: MenusOperations;\n readonly store: StoreOperations;\n readonly collections: CollectionsOperations;\n readonly categories: CategoriesOperations;\n readonly cart: CartOperations;\n readonly checkout: CheckoutOperations;\n readonly payments: PaymentsOperations;\n readonly auth: AuthOperations;\n readonly account: AccountOperations;\n readonly shipping: ShippingOperations;\n readonly analytics: AnalyticsOperations;\n readonly marketing: MarketingOperations;\n\n init(options?: StorefrontInitOptions): Promise<Result<ResolvedStorefrontInitConfig, StorefrontError>>;\n}\n\ninterface InternalClient extends StorefrontClient {\n readonly _graphql: GraphQLClient;\n readonly _storage: StorageAdapter;\n readonly _queryCache: QueryCache;\n _analyticsRuntimeConfig: StorefrontAnalyticsInitConfig | null;\n _resolvedInitConfig: ResolvedStorefrontInitConfig | null;\n}\n\nexport type { AccountOperations } from \"./account.ts\";\nexport type { AnalyticsOperations } from \"./analytics.ts\";\nexport type { AuthOperations } from \"./auth.ts\";\nexport type { CartOperations } from \"./cart.ts\";\nexport type { CategoriesOperations } from \"./categories.ts\";\nexport type { CheckoutOperations } from \"./checkout.ts\";\nexport type { CollectionProductSort, CollectionsOperations } from \"./collections.ts\";\nexport type { MarketingOperations } from \"./marketing.ts\";\nexport type { PaymentsOperations } from \"./payments.ts\";\nexport type { ProductsOperations } from \"./products.ts\";\nexport type { ShippingOperations } from \"./shipping.ts\";\nexport type { StoreOperations } from \"./store.ts\";\n\n/**\n * Create a new Storefront SDK client\n *\n * @param config - Client configuration including endpoint, API key, and optional storage adapter\n * @returns A configured StorefrontClient instance\n *\n * @example\n * ```typescript\n * import { createStorefrontClient } from \"@ekomerc/storefront\";\n *\n * const client = createStorefrontClient({\n * endpoint: \"https://storefront-api.mystore.com/graphql\",\n * apiKey: \"sfk_abc123...\",\n * });\n *\n * // Query products\n * const result = await client.query({\n * query: `query { products { edges { node { id title } } } }`,\n * });\n *\n * if (result.isOk()) {\n * console.log(result.value);\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport function createStorefrontClient(config: StorefrontClientConfig): StorefrontClient {\n if (config.tracking) {\n // biome-ignore lint/suspicious/noConsole: SDK deprecation warning for consumers\n console.warn(\n \"[ekomerc] StorefrontClientConfig.tracking is deprecated. Pass analytics hooks to client.init({ analytics: ... }) instead.\",\n );\n }\n const rawStorage = config.storage ?? createDefaultAdapter();\n const storage = isSandboxApiKey(config.apiKey) ? createNamespacedAdapter(rawStorage, \"sandbox:\") : rawStorage;\n const queryCache = createQueryCache();\n const cacheTTL = config.cacheTTL ?? DEFAULT_CACHE_TTL;\n\n // Initially scoped to apiKey (storeId not yet known); migrated to storeId during init().\n let marketStorageKey = getMarketStorageKey(config.apiKey);\n\n const graphqlClient = createGraphQLClient({\n endpoint: config.endpoint,\n apiKey: config.apiKey,\n getCartToken: () => storage.get(CART_SESSION_KEY),\n getCustomerToken: () => storage.get(CUSTOMER_SESSION_KEY),\n getMarketSlug: () => storage.get(marketStorageKey),\n cache: queryCache,\n cacheTTL,\n });\n\n const client: InternalClient = {\n config,\n _graphql: graphqlClient,\n _storage: storage,\n _queryCache: queryCache,\n _analyticsRuntimeConfig: null,\n _resolvedInitConfig: null,\n\n cache: {\n clear(): void {\n queryCache.clear();\n },\n },\n\n // Placeholder - will be assigned below\n products: null as unknown as ProductsOperations,\n pages: null as unknown as PagesOperations,\n policies: null as unknown as PoliciesOperations,\n menus: null as unknown as MenusOperations,\n store: null as unknown as StoreOperations,\n collections: null as unknown as CollectionsOperations,\n categories: null as unknown as CategoriesOperations,\n cart: null as unknown as CartOperations,\n checkout: null as unknown as CheckoutOperations,\n payments: null as unknown as PaymentsOperations,\n auth: null as unknown as AuthOperations,\n account: null as unknown as AccountOperations,\n shipping: null as unknown as ShippingOperations,\n analytics: null as unknown as AnalyticsOperations,\n marketing: null as unknown as MarketingOperations,\n\n init: null as unknown as StorefrontClient[\"init\"],\n\n query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>> {\n return graphqlClient.query<T>(request, options);\n },\n\n mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>> {\n return graphqlClient.mutate<T>(request, options);\n },\n\n getCartToken(): string | null {\n return storage.get(CART_SESSION_KEY);\n },\n\n setCartToken(token: string): void {\n storage.set(CART_SESSION_KEY, token);\n },\n\n clearCartToken(): void {\n const currentToken = storage.get(CART_SESSION_KEY);\n if (currentToken) {\n storage.remove(getCheckoutLeadDispatchKey(currentToken));\n }\n storage.remove(CART_SESSION_KEY);\n },\n\n getCustomerToken(): string | null {\n return storage.get(CUSTOMER_SESSION_KEY);\n },\n\n setCustomerToken(token: string): void {\n storage.set(CUSTOMER_SESSION_KEY, token);\n },\n\n clearCustomerToken(): void {\n storage.remove(CUSTOMER_SESSION_KEY);\n },\n\n getMarket(): string | null {\n return storage.get(marketStorageKey);\n },\n\n setMarket(slug: string): void {\n const current = storage.get(marketStorageKey);\n if (current !== slug) {\n storage.set(marketStorageKey, slug);\n client.clearCartToken();\n queryCache.clear();\n }\n },\n\n clearMarket(): void {\n const current = storage.get(marketStorageKey);\n if (current !== null) {\n storage.remove(marketStorageKey);\n client.clearCartToken();\n queryCache.clear();\n }\n },\n };\n\n // Consent manager and analytics must be created before cart/checkout so auto-tracking can emit events\n const hasCustomConsentResolver = Boolean(config.tracking?.resolveConsentState);\n let consentMgr: ConsentManager | null = null;\n let unsubConsentBridge: (() => void) | null = null;\n\n if (!hasCustomConsentResolver) {\n consentMgr = createConsentManager({\n debug: config.debug,\n onBufferFlush(entries: ConsentBufferEntry[]) {\n for (const entry of entries) {\n try {\n entry.adapter.dispatch(entry.input);\n } catch {\n // Best-effort flush — must not throw.\n }\n }\n },\n });\n }\n\n const { operations: analyticsController, emit: analyticsEmit } = createAnalyticsOperations(\n client,\n storage,\n consentMgr,\n );\n (client as { analytics: AnalyticsOperations }).analytics = analyticsController;\n\n // Create operations after client and analytics are created\n const cartCache = createCartSnapshotCache(client, storage);\n (client as { products: ProductsOperations }).products = createProductsOperations(client, analyticsEmit);\n (client as { store: StoreOperations }).store = createStoreOperations(client);\n (client as { collections: CollectionsOperations }).collections = createCollectionsOperations(client);\n (client as { categories: CategoriesOperations }).categories = createCategoriesOperations(client);\n (client as { pages: PagesOperations }).pages = createPagesOperations(client);\n (client as { policies: PoliciesOperations }).policies = createPoliciesOperations(client);\n (client as { menus: MenusOperations }).menus = createMenusOperations(client);\n (client as { cart: CartOperations }).cart = createCartOperations(client, storage, analyticsEmit, cartCache);\n (client as { checkout: CheckoutOperations }).checkout = createCheckoutOperations(\n client,\n storage,\n analyticsEmit,\n cartCache,\n consentMgr,\n );\n (client as { payments: PaymentsOperations }).payments = createPaymentsOperations(\n client,\n storage,\n cartCache,\n consentMgr,\n );\n (client as { auth: AuthOperations }).auth = createAuthOperations(client, storage);\n (client as { account: AccountOperations }).account = createAccountOperations(client, storage);\n (client as { shipping: ShippingOperations }).shipping = createShippingOperations(client);\n (client as { marketing: MarketingOperations }).marketing = createMarketingOperations(client, storage, analyticsEmit);\n client.init = async (options?: StorefrontInitOptions) => {\n client._analyticsRuntimeConfig = options?.analytics ?? null;\n\n const hasUserConsentResolver = Boolean(options?.analytics?.resolveConsentState);\n\n const storeResult = await client.store.get({ cache: false });\n if (storeResult.isErr()) {\n return err(storeResult.error);\n }\n\n // Migrate market slug from apiKey-scoped key to the canonical storeId-scoped key.\n const storeIdKey = getMarketStorageKeyByStoreId(storeResult.value.id);\n if (storeIdKey !== marketStorageKey) {\n const existing = storage.get(marketStorageKey);\n if (existing !== null) {\n storage.set(storeIdKey, existing);\n storage.remove(marketStorageKey);\n }\n marketStorageKey = storeIdKey;\n }\n\n const resolvedConfig: ResolvedStorefrontInitConfig = {\n analytics: {\n enabled: storeResult.value.analytics.enabled,\n firstPartyEnabled: storeResult.value.analytics.firstPartyEnabled,\n gtm: storeResult.value.analytics.gtm,\n },\n };\n\n const userAnalytics = options?.analytics ?? {};\n const userAdapters = userAnalytics.adapters ?? [];\n const hasUserGtmAdapter = userAdapters.some((a) => a.provider === \"gtm\");\n\n const autoAdapters = (() => {\n const adapters = [...userAdapters];\n if (!hasUserGtmAdapter) {\n const gtmAdapter = createGtmBrowserAdapter(resolvedConfig.analytics.gtm, {\n debug: config.debug,\n initialConsentState: consentMgr && !hasUserConsentResolver ? consentMgr.getCategories() : undefined,\n });\n if (gtmAdapter) adapters.push(gtmAdapter);\n }\n const debugAdapter = createDebugBrowserAdapter();\n if (debugAdapter) adapters.push(debugAdapter);\n return adapters;\n })();\n\n client._analyticsRuntimeConfig = {\n ...userAnalytics,\n adapters: autoAdapters,\n };\n client._resolvedInitConfig = resolvedConfig;\n analyticsController.init(resolvedConfig.analytics);\n\n if (consentMgr && !hasUserConsentResolver) {\n unsubConsentBridge?.();\n unsubConsentBridge = consentMgr.onChange(() => {\n for (const adapter of autoAdapters) {\n if (!adapter.updateConsent) continue;\n try {\n adapter.updateConsent({ consentState: consentMgr.getState() });\n } catch {\n // Best-effort consent bridge update.\n }\n }\n });\n }\n\n return ok(resolvedConfig);\n };\n\n return client;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport { StorefrontError } from \"./errors.ts\";\nimport type { Collection, CollectionSortOrder, Product, ProductSortKey } from \"./types.ts\";\n\n/** Sort modes supported by product feed descriptors. */\nexport type ProductFeedSort = \"manual\" | \"newest\" | \"oldest\" | \"title_asc\" | \"title_desc\";\n/** Sort modes supported by collection feed descriptors. */\nexport type CollectionFeedSort = \"manual\" | \"newest\" | \"oldest\" | \"title_asc\" | \"title_desc\";\ntype CollectionProductFeedSort = Extract<ProductFeedSort, \"manual\" | \"newest\">;\ntype CatalogProductFeedSort = Extract<ProductFeedSort, \"newest\" | \"title_asc\">;\n\n/** Stored product-feed descriptor that themes resolve through storefront GraphQL at render time. */\nexport type ProductFeedDescriptor =\n | {\n version: 1;\n source: \"manual\";\n limit: number;\n productIds: string[];\n sort: \"manual\";\n }\n | {\n version: 1;\n source: \"collection\";\n limit: number;\n collectionId: string;\n sort: CollectionProductFeedSort;\n }\n | {\n version: 1;\n source: \"category\";\n limit: number;\n categoryId: string;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"latest\";\n limit: number;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"all\";\n limit: number;\n sort: CatalogProductFeedSort;\n };\n\n/** Stored collection-feed descriptor that themes resolve through storefront GraphQL at render time. */\nexport type CollectionFeedDescriptor =\n | {\n version: 1;\n source: \"manual\";\n limit: number;\n collectionIds: string[];\n sort: \"manual\";\n }\n | {\n version: 1;\n source: \"latest\";\n limit: number;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"all\";\n limit: number;\n sort: \"newest\";\n };\n\n/** Product-feed descriptor input, including future versions that resolve to an unsupported descriptor error. */\nexport type ProductFeedDescriptorInput = ProductFeedDescriptor | { version: number; [key: string]: unknown };\n/** Collection-feed descriptor input, including future versions that resolve to an unsupported descriptor error. */\nexport type CollectionFeedDescriptorInput = CollectionFeedDescriptor | { version: number; [key: string]: unknown };\n/** Minimal storefront client surface required to resolve theme commerce descriptors. */\nexport type CommerceDescriptorClient = Pick<StorefrontClient, \"products\" | \"collections\" | \"categories\">;\n\n/** Resolved product-feed payload returned to SDK-backed theme sections. */\nexport interface ProductFeedResult {\n version: 1;\n source: ProductFeedDescriptor[\"source\"];\n limit: number;\n products: Product[];\n collection: Collection | null;\n}\n\n/** Resolved collection-feed payload returned to SDK-backed theme sections. */\nexport interface CollectionFeedResult {\n version: 1;\n source: CollectionFeedDescriptor[\"source\"];\n limit: number;\n collections: Collection[];\n}\n\nexport class UnsupportedDescriptorError extends StorefrontError {\n constructor(kind: \"product_feed\" | \"collection_feed\", version: unknown) {\n super(`${kind} descriptor version is not supported: ${String(version)}`, \"UNSUPPORTED_DESCRIPTOR\");\n this.name = \"UnsupportedDescriptorError\";\n }\n}\n\nconst MAX_FEED_LIMIT = 50;\n\nfunction normalizeLimit(limit: number): number {\n if (!Number.isFinite(limit)) return 1;\n return Math.min(Math.max(1, Math.floor(limit)), MAX_FEED_LIMIT);\n}\n\nfunction isSupportedProductFeedDescriptor(value: ProductFeedDescriptorInput): value is ProductFeedDescriptor {\n if (value.version !== 1) return false;\n\n switch (value.source) {\n case \"manual\":\n return Array.isArray(value.productIds) && value.sort === \"manual\";\n case \"collection\":\n return typeof value.collectionId === \"string\" && (value.sort === \"manual\" || value.sort === \"newest\");\n case \"category\":\n return typeof value.categoryId === \"string\" && value.sort === \"newest\";\n case \"latest\":\n return value.sort === \"newest\";\n case \"all\":\n return value.sort === \"newest\" || value.sort === \"title_asc\";\n default:\n return false;\n }\n}\n\nfunction isSupportedCollectionFeedDescriptor(value: CollectionFeedDescriptorInput): value is CollectionFeedDescriptor {\n if (value.version !== 1) return false;\n\n switch (value.source) {\n case \"manual\":\n return Array.isArray(value.collectionIds) && value.sort === \"manual\";\n case \"latest\":\n return value.sort === \"newest\";\n case \"all\":\n return value.sort === \"newest\";\n default:\n return false;\n }\n}\n\nfunction compact<T>(values: Array<T | null>): T[] {\n return values.filter((value): value is T => value !== null);\n}\n\nfunction productSort(sort: CatalogProductFeedSort): ProductSortKey {\n switch (sort) {\n case \"title_asc\":\n return \"TITLE\";\n case \"newest\":\n return \"CREATED_AT\";\n default:\n return sort satisfies never;\n }\n}\n\nfunction collectionSort(sort: CollectionProductFeedSort): CollectionSortOrder {\n switch (sort) {\n case \"manual\":\n return \"manual\";\n case \"newest\":\n return \"newest\";\n default:\n return sort satisfies never;\n }\n}\n\nasync function resolveCollectionByIdOrNull(\n client: CommerceDescriptorClient,\n id: string,\n): Promise<Result<Collection | null, StorefrontError>> {\n const result = await client.collections.byId(id);\n if (result.isOk()) return ok(result.value);\n if (result.error.code === \"NOT_FOUND\") return ok(null);\n return err(result.error);\n}\n\n/** Resolve one collection descriptor id through storefront visibility rules. */\nexport async function resolveCollectionById(\n client: CommerceDescriptorClient,\n id: string | null | undefined,\n): Promise<Result<Collection | null, StorefrontError>> {\n if (!id) return ok(null);\n return resolveCollectionByIdOrNull(client, id);\n}\n\n/** Resolve a product-feed descriptor while preserving manual ordering and omitting inaccessible products. */\nexport async function resolveProductFeed(\n client: CommerceDescriptorClient,\n descriptor: ProductFeedDescriptorInput | null | undefined,\n): Promise<Result<ProductFeedResult | null, StorefrontError>> {\n if (!descriptor) return ok(null);\n if (!isSupportedProductFeedDescriptor(descriptor)) {\n return err(new UnsupportedDescriptorError(\"product_feed\", descriptor.version));\n }\n\n const limit = normalizeLimit(descriptor.limit);\n let productsResult: Result<Product[], StorefrontError>;\n let collection: Collection | null = null;\n\n switch (descriptor.source) {\n case \"manual\": {\n const result = await client.products.productsByIds(descriptor.productIds.slice(0, limit));\n if (result.isErr()) return err(result.error);\n productsResult = ok(compact(result.value));\n break;\n }\n case \"collection\": {\n const collectionResult = await resolveCollectionByIdOrNull(client, descriptor.collectionId);\n if (collectionResult.isErr()) return err(collectionResult.error);\n collection = collectionResult.value;\n if (!collection) {\n productsResult = ok([]);\n break;\n }\n const result = await client.collections.getProductsById(descriptor.collectionId, {\n first: limit,\n sort: collectionSort(descriptor.sort),\n });\n if (result.isErr()) return err(result.error);\n productsResult = ok(result.value.items);\n break;\n }\n case \"category\": {\n const result = await client.categories.getProductsById(descriptor.categoryId, {\n first: limit,\n includeDescendants: true,\n });\n if (result.isErr()) {\n if (result.error.code === \"NOT_FOUND\") {\n productsResult = ok([]);\n break;\n }\n return err(result.error);\n }\n productsResult = ok(result.value.items);\n break;\n }\n case \"latest\":\n case \"all\": {\n const result = await client.products.list({ first: limit, sort: productSort(descriptor.sort) });\n if (result.isErr()) return err(result.error);\n productsResult = ok(result.value.items);\n break;\n }\n default:\n return descriptor satisfies never;\n }\n\n return productsResult.map((products) => ({\n version: 1,\n source: descriptor.source,\n limit,\n products,\n collection,\n }));\n}\n\n/** Resolve a collection-feed descriptor while omitting inaccessible collections. */\nexport async function resolveCollectionFeed(\n client: CommerceDescriptorClient,\n descriptor: CollectionFeedDescriptorInput | null | undefined,\n): Promise<Result<CollectionFeedResult | null, StorefrontError>> {\n if (!descriptor) return ok(null);\n if (!isSupportedCollectionFeedDescriptor(descriptor)) {\n return err(new UnsupportedDescriptorError(\"collection_feed\", descriptor.version));\n }\n\n const limit = normalizeLimit(descriptor.limit);\n\n switch (descriptor.source) {\n case \"manual\": {\n const settled = await Promise.all(\n descriptor.collectionIds.slice(0, limit).map((id) => resolveCollectionByIdOrNull(client, id)),\n );\n const firstError = settled.find((result) => result.isErr());\n if (firstError?.isErr()) return err(firstError.error);\n return ok({\n version: 1,\n source: \"manual\",\n limit,\n collections: compact(settled.map((result) => (result.isOk() ? result.value : null))),\n });\n }\n case \"latest\":\n case \"all\": {\n const result = await client.collections.list({ first: limit });\n if (result.isErr()) return err(result.error);\n return ok({\n version: 1,\n source: descriptor.source,\n limit,\n collections: result.value.items,\n });\n }\n default:\n return descriptor satisfies never;\n }\n}\n\n/**\n * Deprecated compatibility alias for {@link resolveProductFeed}.\n *\n * @deprecated Use {@link resolveProductFeed}. This alias remains for existing async SDK callers.\n */\nexport const useProductFeed = resolveProductFeed;\n/**\n * Deprecated compatibility alias for {@link resolveCollectionById}.\n *\n * @deprecated Use {@link resolveCollectionById}. This alias remains for existing async SDK callers.\n */\nexport const useCollectionById = resolveCollectionById;\n/**\n * Deprecated compatibility alias for {@link resolveCollectionFeed}.\n *\n * @deprecated Use {@link resolveCollectionFeed}. This alias remains for existing async SDK callers.\n */\nexport const useCollectionFeed = resolveCollectionFeed;\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NetworkError, type StorefrontError } from \"./errors.ts\";\nimport type { StorefrontClientConfig } from \"./types.ts\";\n\n/** Validated platform discovery metadata; the publishable key is safe to ship in the site. */\nexport interface SiteDiscovery extends Pick<StorefrontClientConfig, \"endpoint\" | \"apiKey\"> {\n siteId: string;\n primaryOrigin: string;\n urlTemplates: Record<string, string>;\n}\n\nfunction publicHttpUrl(value: unknown): value is string {\n if (typeof value !== \"string\") return false;\n try {\n const url = new URL(value);\n return [\"http:\", \"https:\"].includes(url.protocol) && !url.username && !url.password;\n } catch {\n return false;\n }\n}\n\n/** Reads platform discovery metadata; accepts only v1 responses carrying a live publishable key. */\nexport async function discoverSite(origin: string): Promise<Result<SiteDiscovery, StorefrontError>> {\n try {\n if (!publicHttpUrl(origin)) return err(new NetworkError(\"Invalid site origin\"));\n const response = await fetch(new URL(\"/.well-known/ekomerc/site.json\", origin));\n if (!response.ok) return err(new NetworkError(`Site discovery failed: HTTP ${response.status}`));\n const value: unknown = await response.json();\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return err(new NetworkError(\"Invalid site discovery response\"));\n const data = value as Record<string, unknown>;\n if (\n data.version !== 1 ||\n typeof data.siteId !== \"string\" ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(data.siteId) ||\n !publicHttpUrl(data.storefrontApiUrl) ||\n !publicHttpUrl(data.primaryOrigin) ||\n typeof data.publishableKey !== \"string\" ||\n !/^sfk_live_[a-zA-Z0-9]{28}$/.test(data.publishableKey) ||\n !data.urlTemplates ||\n typeof data.urlTemplates !== \"object\" ||\n Array.isArray(data.urlTemplates) ||\n !Object.values(data.urlTemplates).every((path) => typeof path === \"string\")\n ) {\n return err(new NetworkError(\"Invalid site discovery response\"));\n }\n return ok({\n siteId: data.siteId,\n endpoint: data.storefrontApiUrl,\n apiKey: data.publishableKey,\n primaryOrigin: data.primaryOrigin,\n urlTemplates: data.urlTemplates as Record<string, string>,\n });\n } catch (error) {\n return err(new NetworkError(\"Site discovery failed\", { cause: error instanceof Error ? error : undefined }));\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/cache.ts","../src/storage.ts","../src/account.ts","../../../shared/tracking-policy/src/policy.ts","../src/analytics-retry-queue.ts","../src/tracking-attribution.ts","../src/tracking-runtime.ts","../src/analytics.ts","../src/auth.ts","../../../shared/cart-contract/src/index.ts","../src/url.ts","../src/cart-shared.ts","../src/cart-mutation-runner.ts","../src/cart-snapshot-cache.ts","../src/cart.ts","../src/categories.ts","../src/payment-lifecycle.ts","../src/checkout.ts","../src/list-all.ts","../src/collections.ts","../src/consent.ts","../src/content.ts","../src/browser-helpers.ts","../src/debug-browser-adapter.ts","../src/graphql-client.ts","../src/gtm-browser-adapter.ts","../src/marketing.ts","../src/payments.ts","../src/products.ts","../src/shipping.ts","../src/store.ts","../src/client.ts","../src/commerce-descriptors.ts","../src/discover-site.ts"],"sourcesContent":["interface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport interface QueryCache {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttl: number): void;\n clear(): void;\n}\n\nexport function createQueryCache(): QueryCache {\n const cache = new Map<string, CacheEntry<unknown>>();\n\n return {\n get<T>(key: string): T | null {\n const entry = cache.get(key);\n if (!entry) return null;\n if (Date.now() > entry.expiresAt) {\n cache.delete(key);\n return null;\n }\n return entry.value as T;\n },\n\n set<T>(key: string, value: T, ttl: number): void {\n cache.set(key, {\n value,\n expiresAt: Date.now() + ttl,\n });\n },\n\n clear(): void {\n cache.clear();\n },\n };\n}\n","import type { StorageAdapter } from \"./types.ts\";\n\nconst SANDBOX_API_KEY_RE = /^(sfk|ssk)_sandbox_/;\n\nexport const CART_SESSION_KEY = \"ekomerc_cart_token\";\nexport const CUSTOMER_SESSION_KEY = \"ekomerc_customer_token\";\nexport const CONSENT_COOKIE_NAME = \"ekomerc_consent\";\nexport const CART_STORAGE_KEY = CART_SESSION_KEY;\nexport const CUSTOMER_STORAGE_KEY = CUSTOMER_SESSION_KEY;\nexport const CHECKOUT_LEAD_DISPATCH_PREFIX = \"ekomerc_checkout_lead_dispatched\";\n\nexport function getCheckoutLeadDispatchKey(cartToken: string): string {\n return `${CHECKOUT_LEAD_DISPATCH_PREFIX}:${cartToken}`;\n}\n\nexport function isSandboxApiKey(apiKey: string): boolean {\n return SANDBOX_API_KEY_RE.test(apiKey);\n}\n\n/** Wraps a StorageAdapter so every key is prefixed, isolating storage namespaces. */\nexport function createNamespacedAdapter(inner: StorageAdapter, prefix: string): StorageAdapter {\n return {\n get(key: string): string | null {\n return inner.get(prefix + key);\n },\n set(key: string, value: string): void {\n inner.set(prefix + key, value);\n },\n remove(key: string): void {\n inner.remove(prefix + key);\n },\n };\n}\n\n/** Returns the localStorage key for the active market slug, scoped to the API key (used before storeId is known). */\nexport function getMarketStorageKey(apiKey: string): string {\n return `ekomerc_market_${apiKey}`;\n}\n\n/** Returns the canonical localStorage key for the active market slug, scoped to the store ID. */\nexport function getMarketStorageKeyByStoreId(storeId: string): string {\n return `ekomerc_market_${storeId}`;\n}\n\n/**\n * localStorage adapter for browser environments\n */\nexport function createLocalStorageAdapter(): StorageAdapter {\n return {\n get(key: string): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n set(key: string, value: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n remove(key: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(key);\n },\n };\n}\n\n/**\n * In-memory adapter for SSR or testing\n */\nexport function createMemoryAdapter(): StorageAdapter {\n const store = new Map<string, string>();\n\n return {\n get(key: string): string | null {\n return store.get(key) ?? null;\n },\n set(key: string, value: string): void {\n store.set(key, value);\n },\n remove(key: string): void {\n store.delete(key);\n },\n };\n}\n\n/**\n * Detect environment and create appropriate default adapter\n */\nexport function createDefaultAdapter(): StorageAdapter {\n if (typeof window !== \"undefined\" && typeof localStorage !== \"undefined\") {\n return createLocalStorageAdapter();\n }\n return createMemoryAdapter();\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { AuthError, ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_SESSION_KEY } from \"./storage.ts\";\nimport type {\n Customer,\n CustomerAddress,\n CustomerAddressInput,\n CustomerAddressUpdateInput,\n CustomerOrder,\n CustomerUpdateInput,\n Money,\n PaginatedResult,\n StorageAdapter,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: Money;\n totalPrice: Money;\n}\n\ninterface OrderNodeData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n subtotal: Money;\n total: Money;\n note: string | null;\n items: OrderItemData[];\n createdAt: string;\n}\n\ninterface AddressData {\n id: string;\n label: string | null;\n firstName: string | null;\n lastName: string | null;\n addressLine1: string;\n addressLine2: string | null;\n city: string;\n zip: string | null;\n phone: string | null;\n isDefault: boolean;\n createdAt: string;\n}\n\ninterface CustomerData {\n id: string;\n name: string | null;\n email: string;\n emailVerified: boolean;\n}\n\ninterface CustomerOrdersResponse {\n customerOrders: {\n edges: Array<{ node: OrderNodeData; cursor: string }>;\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n };\n}\n\ninterface CustomerAddressesResponse {\n customerAddresses: AddressData[];\n}\n\ninterface CustomerAddressCreateResponse {\n customerAddressCreate: {\n address: AddressData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerAddressUpdateResponse {\n customerAddressUpdate: {\n address: AddressData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerAddressDeleteResponse {\n customerAddressDelete: {\n deletedAddressId: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerUpdateResponse {\n customerUpdate: {\n customer: CustomerData | null;\n userErrors: UserError[];\n };\n}\n\nconst ORDER_ITEM_FRAGMENT = `\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice { amount currency }\n totalPrice { amount currency }\n`;\n\nconst CUSTOMER_ORDERS_QUERY = `\nquery CustomerOrders($first: Int, $after: String, $last: Int, $before: String) {\n customerOrders(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n orderNumber\n status\n customerEmail\n customerPhone\n subtotal { amount currency }\n total { amount currency }\n note\n items { ${ORDER_ITEM_FRAGMENT} }\n createdAt\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst ADDRESS_FRAGMENT = `\n id\n label\n firstName\n lastName\n addressLine1\n addressLine2\n city\n zip\n phone\n isDefault\n createdAt\n`;\n\nconst CUSTOMER_ADDRESSES_QUERY = `\nquery CustomerAddresses {\n customerAddresses { ${ADDRESS_FRAGMENT} }\n}\n`;\n\nconst CUSTOMER_ADDRESS_CREATE_MUTATION = `\nmutation CustomerAddressCreate($input: CustomerAddressCreateInput!) {\n customerAddressCreate(input: $input) {\n address { ${ADDRESS_FRAGMENT} }\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_ADDRESS_UPDATE_MUTATION = `\nmutation CustomerAddressUpdate($addressId: ID!, $input: CustomerAddressUpdateInput!) {\n customerAddressUpdate(addressId: $addressId, input: $input) {\n address { ${ADDRESS_FRAGMENT} }\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_ADDRESS_DELETE_MUTATION = `\nmutation CustomerAddressDelete($addressId: ID!) {\n customerAddressDelete(addressId: $addressId) {\n deletedAddressId\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_UPDATE_MUTATION = `\nmutation CustomerUpdate($input: CustomerUpdateInput!) {\n customerUpdate(input: $input) {\n customer {\n id\n name\n email\n emailVerified\n }\n userErrors { field message code }\n }\n}\n`;\n\nfunction mapOrderNode(data: OrderNodeData): CustomerOrder {\n return {\n id: data.id,\n orderNumber: data.orderNumber,\n status: data.status,\n email: data.customerEmail,\n phone: data.customerPhone,\n subtotal: data.subtotal,\n total: data.total,\n note: data.note,\n items: data.items.map((item) => ({\n id: item.id,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n sku: item.sku,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.totalPrice,\n })),\n createdAt: data.createdAt,\n };\n}\n\nfunction mapAddressData(data: AddressData): CustomerAddress {\n return {\n id: data.id,\n label: data.label,\n firstName: data.firstName,\n lastName: data.lastName,\n addressLine1: data.addressLine1,\n addressLine2: data.addressLine2,\n city: data.city,\n zip: data.zip,\n phone: data.phone,\n isDefault: data.isDefault,\n createdAt: data.createdAt,\n };\n}\n\nfunction mapUserErrors(userErrors: UserError[]): ValidationError | null {\n if (userErrors.length === 0) return null;\n const messages = userErrors.map((e) => e.message).join(\"; \");\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\n\nexport interface AccountOperations {\n /**\n * Fetch paginated orders for the authenticated customer.\n *\n * @param args - Forward or backward pagination options.\n * @returns Paginated customer orders.\n */\n orders(args?: {\n first?: number;\n after?: string;\n last?: number;\n before?: string;\n }): Promise<Result<PaginatedResult<CustomerOrder>, StorefrontError>>;\n /**\n * Fetch saved addresses for the authenticated customer.\n *\n * @returns Customer addresses.\n */\n addresses(): Promise<Result<CustomerAddress[], StorefrontError>>;\n /**\n * Create a saved customer address.\n *\n * @param input - Address fields to create.\n * @returns The created address.\n */\n createAddress(input: CustomerAddressInput): Promise<Result<CustomerAddress, StorefrontError>>;\n /**\n * Update a saved customer address.\n *\n * @param addressId - Address identifier to update.\n * @param input - Address fields to change.\n * @returns The updated address.\n */\n updateAddress(\n addressId: string,\n input: CustomerAddressUpdateInput,\n ): Promise<Result<CustomerAddress, StorefrontError>>;\n /**\n * Delete a saved customer address.\n *\n * @param addressId - Address identifier to delete.\n * @returns The deleted address identifier.\n */\n deleteAddress(addressId: string): Promise<Result<string, StorefrontError>>;\n /**\n * Update the authenticated customer's profile fields.\n *\n * @param input - Customer fields to update.\n * @returns The updated customer profile.\n */\n update(input: CustomerUpdateInput): Promise<Result<Customer, StorefrontError>>;\n}\n\nexport function createAccountOperations(client: StorefrontClientContext, storage: StorageAdapter): AccountOperations {\n function requireAuth(): Result<void, AuthError> {\n if (!storage.get(CUSTOMER_SESSION_KEY)) {\n return err(new AuthError(\"Not authenticated. Call auth.login() or auth.register() first.\"));\n }\n return ok(undefined);\n }\n\n return {\n async orders(args) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const variables: Record<string, unknown> = {};\n if (args?.first !== undefined) variables.first = args.first;\n if (args?.after !== undefined) variables.after = args.after;\n if (args?.last !== undefined) variables.last = args.last;\n if (args?.before !== undefined) variables.before = args.before;\n if (!variables.first && !variables.last) variables.first = 20;\n\n const result = await client.query<CustomerOrdersResponse>(\n { query: CUSTOMER_ORDERS_QUERY, variables },\n { cache: false },\n );\n\n if (result.isErr()) return err(result.error);\n\n const { edges, pageInfo } = result.value.customerOrders;\n return ok({\n items: edges.map((edge) => mapOrderNode(edge.node)),\n pageInfo,\n });\n },\n\n async addresses() {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.query<CustomerAddressesResponse>(\n { query: CUSTOMER_ADDRESSES_QUERY },\n { cache: false },\n );\n\n if (result.isErr()) return err(result.error);\n\n return ok(result.value.customerAddresses.map(mapAddressData));\n },\n\n async createAddress(input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressCreateResponse>({\n query: CUSTOMER_ADDRESS_CREATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.address) {\n return err(new ValidationError(\"Failed to create address\", []));\n }\n\n return ok(mapAddressData(payload.address));\n },\n\n async updateAddress(addressId, input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressUpdateResponse>({\n query: CUSTOMER_ADDRESS_UPDATE_MUTATION,\n variables: { addressId, input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressUpdate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.address) {\n return err(new ValidationError(\"Failed to update address\", []));\n }\n\n return ok(mapAddressData(payload.address));\n },\n\n async deleteAddress(addressId) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerAddressDeleteResponse>({\n query: CUSTOMER_ADDRESS_DELETE_MUTATION,\n variables: { addressId },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerAddressDelete;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.deletedAddressId) {\n return err(new ValidationError(\"Failed to delete address\", []));\n }\n\n return ok(payload.deletedAddressId);\n },\n\n async update(input) {\n const authCheck = requireAuth();\n if (authCheck.isErr()) return err(authCheck.error);\n\n const result = await client.mutate<CustomerUpdateResponse>({\n query: CUSTOMER_UPDATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerUpdate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Failed to update profile\", []));\n }\n\n return ok({\n id: payload.customer.id,\n name: payload.customer.name,\n email: payload.customer.email,\n emailVerified: payload.customer.emailVerified,\n });\n },\n };\n}\n","export const TRACKING_POLICY_EVENT_TYPES = [\n \"analytics.page_view\",\n \"analytics.product_view\",\n \"analytics.collection_view\",\n \"analytics.search_performed\",\n \"analytics.lead_generated\",\n \"analytics.select_item\",\n \"analytics.add_to_cart\",\n \"analytics.remove_from_cart\",\n \"analytics.view_cart\",\n \"analytics.checkout_started\",\n \"analytics.checkout_step_completed\",\n \"analytics.checkout_completed\",\n \"analytics.custom\",\n] as const;\nexport type TrackingPolicyEventType = (typeof TRACKING_POLICY_EVENT_TYPES)[number];\n\nexport const TRACKING_PROVIDERS = [\"gtm\", \"meta\", \"tiktok\"] as const;\nexport type TrackingProvider = (typeof TRACKING_PROVIDERS)[number];\n\nexport const GTM_STANDARD_EVENTS = [\n \"page_view\",\n \"view_item\",\n \"view_item_list\",\n \"search\",\n \"generate_lead\",\n \"select_item\",\n \"add_to_cart\",\n \"remove_from_cart\",\n \"view_cart\",\n \"begin_checkout\",\n \"add_shipping_info\",\n \"add_payment_info\",\n \"purchase\",\n] as const;\nexport type GtmStandardEventName = (typeof GTM_STANDARD_EVENTS)[number];\n\nexport const META_STANDARD_EVENTS = [\n \"PageView\",\n \"ViewContent\",\n \"Search\",\n \"Lead\",\n \"AddToCart\",\n \"InitiateCheckout\",\n \"Purchase\",\n] as const;\nexport type MetaStandardEventName = (typeof META_STANDARD_EVENTS)[number];\n\nexport const TIKTOK_STANDARD_EVENTS = [\n \"PageView\",\n \"ViewContent\",\n \"Search\",\n \"AddToCart\",\n \"InitiateCheckout\",\n \"CompletePayment\",\n] as const;\nexport type TiktokStandardEventName = (typeof TIKTOK_STANDARD_EVENTS)[number];\n\nexport const GTM_EVENT_MAP = {\n \"analytics.page_view\": \"page_view\",\n \"analytics.product_view\": \"view_item\",\n \"analytics.collection_view\": \"view_item_list\",\n \"analytics.search_performed\": \"search\",\n \"analytics.lead_generated\": \"generate_lead\",\n \"analytics.select_item\": \"select_item\",\n \"analytics.add_to_cart\": \"add_to_cart\",\n \"analytics.remove_from_cart\": \"remove_from_cart\",\n \"analytics.view_cart\": \"view_cart\",\n \"analytics.checkout_started\": \"begin_checkout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"purchase\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, GtmStandardEventName | null>;\n\nexport const META_EVENT_MAP = {\n \"analytics.page_view\": \"PageView\",\n \"analytics.product_view\": \"ViewContent\",\n \"analytics.collection_view\": \"ViewContent\",\n \"analytics.search_performed\": \"Search\",\n \"analytics.lead_generated\": \"Lead\",\n \"analytics.select_item\": null,\n \"analytics.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_cart\": null,\n \"analytics.view_cart\": null,\n \"analytics.checkout_started\": \"InitiateCheckout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"Purchase\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, MetaStandardEventName | null>;\n\nexport const TIKTOK_EVENT_MAP = {\n \"analytics.page_view\": \"PageView\",\n \"analytics.product_view\": \"ViewContent\",\n \"analytics.collection_view\": \"ViewContent\",\n \"analytics.search_performed\": \"Search\",\n \"analytics.lead_generated\": null,\n \"analytics.select_item\": null,\n \"analytics.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_cart\": null,\n \"analytics.view_cart\": null,\n \"analytics.checkout_started\": \"InitiateCheckout\",\n \"analytics.checkout_step_completed\": null,\n \"analytics.checkout_completed\": \"CompletePayment\",\n \"analytics.custom\": null,\n} as const satisfies Record<TrackingPolicyEventType, TiktokStandardEventName | null>;\n\nexport type TrackingProviderEventNameMap = {\n gtm: GtmStandardEventName;\n meta: MetaStandardEventName;\n tiktok: TiktokStandardEventName;\n};\n\nexport type TrackingProviderEventMap = {\n [Provider in TrackingProvider]: Record<TrackingPolicyEventType, TrackingProviderEventNameMap[Provider] | null>;\n};\n\nexport const TRACKING_PROVIDER_EVENT_MAPS = {\n gtm: GTM_EVENT_MAP,\n meta: META_EVENT_MAP,\n tiktok: TIKTOK_EVENT_MAP,\n} as const satisfies TrackingProviderEventMap;\n\nexport interface TrackingProviderSupportRule {\n supportsBrowserDispatch: boolean;\n supportsServerDispatch: boolean;\n requiresConsentBridge: boolean;\n supportedEventTypes: TrackingPolicyEventType[];\n}\n\nfunction collectSupportedEventTypes<Provider extends TrackingProvider>(\n provider: Provider,\n): TrackingProviderSupportRule[\"supportedEventTypes\"] {\n const eventMap = TRACKING_PROVIDER_EVENT_MAPS[provider];\n return TRACKING_POLICY_EVENT_TYPES.filter((eventType) => eventMap[eventType] !== null);\n}\n\nexport const TRACKING_PROVIDER_SUPPORT_RULES = {\n gtm: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: false,\n requiresConsentBridge: true,\n supportedEventTypes: collectSupportedEventTypes(\"gtm\"),\n },\n meta: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: true,\n requiresConsentBridge: false,\n supportedEventTypes: collectSupportedEventTypes(\"meta\"),\n },\n tiktok: {\n supportsBrowserDispatch: true,\n supportsServerDispatch: true,\n requiresConsentBridge: false,\n supportedEventTypes: collectSupportedEventTypes(\"tiktok\"),\n },\n} as const satisfies Record<TrackingProvider, TrackingProviderSupportRule>;\n\nexport interface TrackingProviderDedupeConvention {\n canonicalEventIdField: \"eventId\";\n providerEventIdField: \"event_id\";\n confirmedPurchaseSource: \"order.id\";\n}\n\nconst SHARED_DEDUPE_CONVENTION: TrackingProviderDedupeConvention = {\n canonicalEventIdField: \"eventId\",\n providerEventIdField: \"event_id\",\n confirmedPurchaseSource: \"order.id\",\n};\n\nexport const TRACKING_PROVIDER_DEDUPE_FIELDS = {\n gtm: SHARED_DEDUPE_CONVENTION,\n meta: SHARED_DEDUPE_CONVENTION,\n tiktok: SHARED_DEDUPE_CONVENTION,\n} as const satisfies Record<TrackingProvider, TrackingProviderDedupeConvention>;\n\nexport function getTrackingProviderEventName(\n provider: \"gtm\",\n eventType: TrackingPolicyEventType,\n): GtmStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: \"meta\",\n eventType: TrackingPolicyEventType,\n): MetaStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: \"tiktok\",\n eventType: TrackingPolicyEventType,\n): TiktokStandardEventName | null;\nexport function getTrackingProviderEventName(\n provider: TrackingProvider,\n eventType: TrackingPolicyEventType,\n): string | null {\n return TRACKING_PROVIDER_EVENT_MAPS[provider][eventType];\n}\n\nexport function providerSupportsTrackingEvent(provider: TrackingProvider, eventType: TrackingPolicyEventType): boolean {\n return TRACKING_PROVIDER_EVENT_MAPS[provider][eventType] !== null;\n}\n\nexport function getTrackingProviderSupportRule(provider: TrackingProvider): TrackingProviderSupportRule {\n return TRACKING_PROVIDER_SUPPORT_RULES[provider];\n}\n\nexport function getTrackingProviderDedupeConvention(provider: TrackingProvider): TrackingProviderDedupeConvention {\n return TRACKING_PROVIDER_DEDUPE_FIELDS[provider];\n}\n\nexport const CONSENT_CATEGORIES = [\"analytics_storage\", \"ad_storage\", \"ad_user_data\", \"ad_personalization\"] as const;\nexport type ConsentCategory = (typeof CONSENT_CATEGORIES)[number];\n\nexport const TRACKING_PROVIDER_REQUIRED_CONSENT = {\n gtm: [\"analytics_storage\"],\n meta: [\"ad_storage\", \"ad_user_data\"],\n tiktok: [\"ad_storage\", \"ad_user_data\"],\n} as const satisfies Record<TrackingProvider, readonly ConsentCategory[]>;\n\nexport function getTrackingProviderRequiredConsent(provider: TrackingProvider): readonly ConsentCategory[] {\n return TRACKING_PROVIDER_REQUIRED_CONSENT[provider];\n}\n","import type { AnalyticsBrowserEvent, AnalyticsDiagnostic } from \"./tracking-runtime.ts\";\nimport type { StorageAdapter } from \"./types.ts\";\n\nconst ANALYTICS_QUEUE_KEY_PREFIX = \"ekomerc_aq_\";\nconst ANALYTICS_QUEUE_KEY_API_PREFIX_LENGTH = 12;\nconst ANALYTICS_QUEUE_MAX_EVENTS = 100;\nconst ANALYTICS_QUEUE_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport interface AnalyticsRetryQueueEntry {\n event: AnalyticsBrowserEvent;\n queuedAt: number;\n notBefore?: number;\n}\n\nexport interface AnalyticsRetryQueue {\n read(nowMs?: number): AnalyticsRetryQueueEntry[];\n enqueue(entry: AnalyticsRetryQueueEntry): AnalyticsRetryQueueEntry[];\n dequeue(count: number, nowMs?: number): AnalyticsRetryQueueEntry[];\n replace(entries: AnalyticsRetryQueueEntry[]): void;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isAnalyticsRetryQueueEntry(value: unknown): value is AnalyticsRetryQueueEntry {\n if (!isPlainObject(value)) {\n return false;\n }\n\n const event = value.event;\n return (\n isPlainObject(event) &&\n typeof event.eventId === \"string\" &&\n typeof value.queuedAt === \"number\" &&\n (value.notBefore === undefined || typeof value.notBefore === \"number\")\n );\n}\n\nexport function getAnalyticsRetryQueueKey(apiKey: string): string {\n return `${ANALYTICS_QUEUE_KEY_PREFIX}${apiKey.slice(0, ANALYTICS_QUEUE_KEY_API_PREFIX_LENGTH)}`;\n}\n\nexport function createAnalyticsRetryQueue(\n storage: StorageAdapter,\n apiKey: string,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n): AnalyticsRetryQueue {\n const queueKey = getAnalyticsRetryQueueKey(apiKey);\n\n function persist(entries: AnalyticsRetryQueueEntry[]): void {\n try {\n if (entries.length === 0) {\n storage.remove(queueKey);\n return;\n }\n\n storage.set(queueKey, JSON.stringify(entries));\n } catch {\n // Queue persistence is best-effort and must never affect callers.\n }\n }\n\n function read(nowMs = Date.now()): AnalyticsRetryQueueEntry[] {\n let raw: string | null;\n\n try {\n raw = storage.get(queueKey);\n } catch {\n return [];\n }\n\n if (!raw) {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n const entries = parsed.filter(isAnalyticsRetryQueueEntry);\n const activeEntries = entries.filter((entry) => {\n const isExpired = nowMs - entry.queuedAt >= ANALYTICS_QUEUE_TTL_MS;\n if (isExpired) {\n emitDiagnostic({\n target: \"queue\",\n status: \"evicted_expired\",\n eventId: entry.event.eventId,\n });\n }\n\n return !isExpired;\n });\n\n if (activeEntries.length !== entries.length) {\n persist(activeEntries);\n }\n\n return activeEntries;\n }\n\n function enqueue(entry: AnalyticsRetryQueueEntry): AnalyticsRetryQueueEntry[] {\n const entries = read(entry.queuedAt);\n const nextEntries = [...entries];\n\n while (nextEntries.length >= ANALYTICS_QUEUE_MAX_EVENTS) {\n const evicted = nextEntries.shift();\n if (evicted) {\n emitDiagnostic({\n target: \"queue\",\n status: \"evicted_full\",\n event: evicted.event,\n });\n }\n }\n\n nextEntries.push(entry);\n persist(nextEntries);\n emitDiagnostic({\n target: \"queue\",\n status: \"enqueued\",\n event: entry.event,\n });\n return nextEntries;\n }\n\n function dequeue(count: number, nowMs = Date.now()): AnalyticsRetryQueueEntry[] {\n const entries = read(nowMs);\n const dequeueCount = Math.max(0, Math.floor(count));\n const removedEntries = entries.slice(0, dequeueCount);\n persist(entries.slice(removedEntries.length));\n emitDiagnostic({\n target: \"queue\",\n status: \"flushed\",\n count: removedEntries.length,\n });\n return removedEntries;\n }\n\n function replace(entries: AnalyticsRetryQueueEntry[]): void {\n persist(entries);\n }\n\n return {\n read,\n enqueue,\n dequeue,\n replace,\n };\n}\n","const TRACKING_SCHEMA_VERSION = 1 as const;\nconst TRACKING_ATTRIBUTION_STORAGE_KEY = \"ekomerc_tracking_attribution\";\nexport const DEFAULT_TRACKING_ATTRIBUTION_TTL_MS = 30 * 24 * 60 * 60 * 1000;\nexport const TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n \"gclid\",\n \"gbraid\",\n \"wbraid\",\n \"ttclid\",\n \"fbclid\",\n] as const;\n\nexport interface TrackingAttributionSnapshot {\n schemaVersion: 1;\n capturedAt: string;\n utm: {\n schemaVersion: 1;\n source: string | null;\n medium: string | null;\n campaign: string | null;\n term: string | null;\n content: string | null;\n };\n clickIds: {\n schemaVersion: 1;\n capturedAt: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n ttclid: string | null;\n fbclid: string | null;\n };\n}\n\nexport interface TrackingAttributionOptions {\n ttlMs?: number;\n}\n\nfunction hasBrowserContext(): boolean {\n return typeof window !== \"undefined\";\n}\n\nfunction hasTrackingAttributionParams(search: string): boolean {\n const params = new URLSearchParams(search);\n return TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS.some((key) => {\n const value = params.get(key);\n return value !== null && value.trim().length > 0;\n });\n}\n\nfunction normalizeParam(value: string | null): string | null {\n if (value === null) return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction hasAttributionValue(snapshot: TrackingAttributionSnapshot): boolean {\n return [\n snapshot.utm.source,\n snapshot.utm.medium,\n snapshot.utm.campaign,\n snapshot.utm.term,\n snapshot.utm.content,\n snapshot.clickIds.gclid,\n snapshot.clickIds.gbraid,\n snapshot.clickIds.wbraid,\n snapshot.clickIds.ttclid,\n snapshot.clickIds.fbclid,\n ].some((value) => value !== null);\n}\n\nfunction resolveTrackingAttributionTtlMs(options?: TrackingAttributionOptions): number {\n const ttlMs = options?.ttlMs;\n if (typeof ttlMs !== \"number\" || !Number.isFinite(ttlMs) || ttlMs < 0) {\n return DEFAULT_TRACKING_ATTRIBUTION_TTL_MS;\n }\n\n return ttlMs;\n}\n\nfunction isSnapshotExpired(snapshot: TrackingAttributionSnapshot, ttlMs: number): boolean {\n const capturedAtMs = Date.parse(snapshot.capturedAt);\n if (Number.isNaN(capturedAtMs)) {\n return true;\n }\n\n return Date.now() - capturedAtMs > ttlMs;\n}\n\nfunction parseStoredSnapshot(raw: string | null): TrackingAttributionSnapshot | null {\n if (!raw) return null;\n\n try {\n const parsed = JSON.parse(raw) as Partial<TrackingAttributionSnapshot>;\n if (parsed.schemaVersion !== TRACKING_SCHEMA_VERSION || typeof parsed.capturedAt !== \"string\") {\n return null;\n }\n\n const utm = parsed.utm;\n const clickIds = parsed.clickIds;\n if (!utm || !clickIds) return null;\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: parsed.capturedAt,\n utm: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: typeof utm.source === \"string\" ? utm.source : null,\n medium: typeof utm.medium === \"string\" ? utm.medium : null,\n campaign: typeof utm.campaign === \"string\" ? utm.campaign : null,\n term: typeof utm.term === \"string\" ? utm.term : null,\n content: typeof utm.content === \"string\" ? utm.content : null,\n },\n clickIds: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: typeof clickIds.capturedAt === \"string\" ? clickIds.capturedAt : null,\n gclid: typeof clickIds.gclid === \"string\" ? clickIds.gclid : null,\n gbraid: typeof clickIds.gbraid === \"string\" ? clickIds.gbraid : null,\n wbraid: typeof clickIds.wbraid === \"string\" ? clickIds.wbraid : null,\n ttclid: typeof clickIds.ttclid === \"string\" ? clickIds.ttclid : null,\n fbclid: typeof clickIds.fbclid === \"string\" ? clickIds.fbclid : null,\n },\n };\n } catch {\n return null;\n }\n}\n\nfunction removeStoredSnapshot(): void {\n if (!hasBrowserContext()) return;\n\n try {\n window.localStorage.removeItem(TRACKING_ATTRIBUTION_STORAGE_KEY);\n } catch {\n // ignore storage failures\n }\n}\n\n/**\n * Reads the stored tracking attribution snapshot from localStorage.\n * Expired snapshots are removed from localStorage during the read — this is a destructive operation despite the read-only name.\n */\nfunction readStoredSnapshot(options?: TrackingAttributionOptions): TrackingAttributionSnapshot | null {\n if (!hasBrowserContext()) return null;\n\n try {\n const snapshot = parseStoredSnapshot(window.localStorage.getItem(TRACKING_ATTRIBUTION_STORAGE_KEY));\n if (!snapshot) {\n return null;\n }\n\n if (isSnapshotExpired(snapshot, resolveTrackingAttributionTtlMs(options))) {\n removeStoredSnapshot();\n return null;\n }\n\n return snapshot;\n } catch {\n return null;\n }\n}\n\nfunction writeStoredSnapshot(snapshot: TrackingAttributionSnapshot): void {\n if (!hasBrowserContext()) return;\n\n try {\n window.localStorage.setItem(TRACKING_ATTRIBUTION_STORAGE_KEY, JSON.stringify(snapshot));\n } catch {\n // ignore storage failures\n }\n}\n\nfunction buildSnapshotFromSearch(search: string): TrackingAttributionSnapshot {\n const params = new URLSearchParams(search);\n const capturedAt = new Date().toISOString();\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt,\n utm: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: normalizeParam(params.get(\"utm_source\")),\n medium: normalizeParam(params.get(\"utm_medium\")),\n campaign: normalizeParam(params.get(\"utm_campaign\")),\n term: normalizeParam(params.get(\"utm_term\")),\n content: normalizeParam(params.get(\"utm_content\")),\n },\n clickIds: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt,\n gclid: normalizeParam(params.get(\"gclid\")),\n gbraid: normalizeParam(params.get(\"gbraid\")),\n wbraid: normalizeParam(params.get(\"wbraid\")),\n ttclid: normalizeParam(params.get(\"ttclid\")),\n fbclid: normalizeParam(params.get(\"fbclid\")),\n },\n };\n}\n\nexport function captureLandingTrackingAttribution(\n options?: TrackingAttributionOptions,\n): TrackingAttributionSnapshot | null {\n if (!hasBrowserContext()) return null;\n\n const snapshot = buildSnapshotFromSearch(window.location.search);\n if (hasAttributionValue(snapshot)) {\n writeStoredSnapshot(snapshot);\n return snapshot;\n }\n\n return readStoredSnapshot(options);\n}\n\n/**\n * Returns the current tracking attribution snapshot, or null if none exists or it has expired.\n * Note: expired snapshots are deleted from localStorage as a side effect of this call.\n */\nexport function getTrackingAttributionSnapshot(\n options?: TrackingAttributionOptions,\n): TrackingAttributionSnapshot | null {\n return readStoredSnapshot(options);\n}\n\nexport function stripLandingTrackingAttributionFromUrl(): boolean {\n if (!hasBrowserContext()) return false;\n if (!hasTrackingAttributionParams(window.location.search)) return false;\n if (typeof window.history?.replaceState !== \"function\") return false;\n\n const params = new URLSearchParams(window.location.search);\n for (const key of TRACKING_ATTRIBUTION_QUERY_PARAM_KEYS) {\n params.delete(key);\n }\n\n const search = params.toString();\n const hash = window.location.hash ?? \"\";\n const nextUrl = `${window.location.pathname}${search ? `?${search}` : \"\"}${hash}`;\n window.history.replaceState(window.history.state, \"\", nextUrl);\n return true;\n}\n","import {\n providerSupportsTrackingEvent,\n type TrackingPolicyEventType,\n type TrackingProvider,\n} from \"@ekomerc/tracking-policy\";\n\nexport const TRACKING_SCHEMA_VERSION = 1 as const;\nexport const INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY = \"__ga4CampaignOverrideActive\" as const;\n\n/**\n * Consent states emitted with browser-side analytics events.\n */\nexport type AnalyticsConsentState = \"granted\" | \"denied\" | \"unknown\";\n\n/**\n * UTM parameters captured for a visitor session.\n */\nexport interface AnalyticsUtm {\n schemaVersion: 1;\n source: string | null;\n medium: string | null;\n campaign: string | null;\n term: string | null;\n content: string | null;\n}\n\n/**\n * Click identifiers captured from ad platforms and passed through analytics events.\n */\nexport interface AnalyticsClickIds {\n schemaVersion: 1;\n capturedAt: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n ttclid: string | null;\n fbclid: string | null;\n}\n\n/**\n * Request context attached to each browser analytics event.\n */\nexport interface AnalyticsEventContextPayload {\n schemaVersion: 1;\n path: string;\n}\n\n/**\n * Primitive JSON values supported inside analytics properties.\n */\nexport type AnalyticsJsonPrimitive = string | number | boolean | null;\n\n/**\n * Recursive JSON value shape supported by analytics event properties.\n */\nexport type AnalyticsJsonValue = AnalyticsJsonPrimitive | AnalyticsJsonValue[] | { [key: string]: AnalyticsJsonValue };\n\n/**\n * Arbitrary analytics event properties sent to ingest and browser adapters.\n */\nexport interface AnalyticsProperties {\n [key: string]: AnalyticsJsonValue;\n}\n\n/**\n * Best-effort browser device fingerprint attached to an analytics event.\n */\nexport interface AnalyticsBrowserEventDevice {\n deviceType: string;\n deviceOs: string | null;\n deviceBrowser: string | null;\n}\n\n/**\n * Canonical browser analytics event shape used by the storefront SDK.\n */\nexport interface AnalyticsBrowserEvent {\n schemaVersion: 1;\n eventId: string;\n eventType: TrackingPolicyEventType;\n occurredAt: string;\n sessionId: string;\n visitorId: string;\n customerId: string | null;\n consentState: AnalyticsConsentState;\n context: AnalyticsEventContextPayload;\n referrer: string | null;\n utm: AnalyticsUtm;\n clickIds: AnalyticsClickIds;\n device: AnalyticsBrowserEventDevice;\n properties: AnalyticsProperties;\n}\n\n/**\n * Consent state payload passed to browser adapters and diagnostics.\n */\nexport interface AnalyticsConsentUpdate {\n consentState: AnalyticsConsentState;\n}\n\n/**\n * Input provided to a browser adapter when dispatching an analytics event.\n */\nexport interface AnalyticsAdapterDispatchInput {\n event: AnalyticsBrowserEvent;\n consent: AnalyticsConsentUpdate;\n}\n\n/**\n * Reasons a browser adapter may skip dispatch instead of throwing.\n */\nexport type AnalyticsAdapterSkipReason = \"unsupported_event\" | \"consent_blocked\" | \"runtime_unavailable\";\n\n/**\n * Structured result returned when a browser adapter intentionally skips dispatch.\n */\nexport interface AnalyticsAdapterOperationSkippedResult {\n status: \"skipped\";\n reason: \"runtime_unavailable\";\n}\n\n/**\n * Result returned by browser adapter dispatch and consent-update hooks.\n */\nexport type AnalyticsAdapterOperationResult =\n | undefined\n | { status: \"success\" }\n | AnalyticsAdapterOperationSkippedResult;\n\n/**\n * Browser-side analytics adapter contract for GTM, Meta, TikTok, or custom integrations.\n */\nexport interface AnalyticsBrowserAdapter {\n provider: TrackingProvider;\n dispatch(\n input: AnalyticsAdapterDispatchInput,\n ): AnalyticsAdapterOperationResult | Promise<AnalyticsAdapterOperationResult>;\n updateConsent?(\n input: AnalyticsConsentUpdate,\n ): AnalyticsAdapterOperationResult | Promise<AnalyticsAdapterOperationResult>;\n}\n\n/**\n * Diagnostic events emitted by the analytics runtime for ingest and adapter activity.\n */\nexport type AnalyticsDiagnostic =\n | {\n target: \"ingest\";\n status: \"success\";\n event: AnalyticsBrowserEvent;\n response: {\n acceptedCount: number;\n duplicateCount: number;\n rejectedCount: number;\n };\n }\n | {\n target: \"ingest\";\n status: \"error\";\n event: AnalyticsBrowserEvent;\n error: Error;\n }\n | {\n target: \"ingest\";\n status: \"accepted_unknown\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"enqueued\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"flushed\";\n count: number;\n }\n | {\n target: \"queue\";\n status: \"evicted_full\";\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"queue\";\n status: \"evicted_expired\";\n eventId: string;\n }\n | {\n target: \"adapter\";\n status: \"success\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n }\n | {\n target: \"adapter\";\n status: \"skipped\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n reason: AnalyticsAdapterSkipReason;\n }\n | {\n target: \"adapter\";\n status: \"error\";\n provider: TrackingProvider;\n event: AnalyticsBrowserEvent;\n error: Error;\n }\n | {\n target: \"consent_bridge\";\n status: \"success\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n }\n | {\n target: \"consent_bridge\";\n status: \"skipped\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n reason: \"runtime_unavailable\";\n }\n | {\n target: \"consent_bridge\";\n status: \"error\";\n provider: TrackingProvider;\n consent: AnalyticsConsentUpdate;\n error: Error;\n }\n | {\n target: \"consent\";\n status: \"error\";\n error: Error;\n };\n\n/**\n * Optional browser analytics runtime hooks passed to `createStorefrontClient()`.\n */\nexport interface StorefrontTrackingRuntimeConfig {\n resolveConsentState?: () => AnalyticsConsentState | Promise<AnalyticsConsentState>;\n adapters?: AnalyticsBrowserAdapter[];\n onDiagnostic?: (diagnostic: AnalyticsDiagnostic) => void;\n}\n\n/**\n * Returns whether the current consent state allows browser-side event dispatch.\n * Unknown consent always blocks — events should be buffered by the consent manager.\n */\nexport function shouldDispatchForTrackingConsent(consentState: AnalyticsConsentState): boolean {\n return consentState === \"granted\";\n}\n\n/**\n * Returns whether a provider can receive the requested event under the current consent state.\n */\nexport function shouldDispatchBrowserAdapter(\n provider: TrackingProvider,\n eventType: TrackingPolicyEventType,\n consentState: AnalyticsConsentState,\n): { allowed: true } | { allowed: false; reason: \"unsupported_event\" | \"consent_blocked\" } {\n if (!providerSupportsTrackingEvent(provider, eventType)) {\n return { allowed: false, reason: \"unsupported_event\" };\n }\n\n if (!shouldDispatchForTrackingConsent(consentState)) {\n return { allowed: false, reason: \"consent_blocked\" };\n }\n\n return { allowed: true };\n}\n","import { TRACKING_PROVIDERS, type TrackingPolicyEventType } from \"@ekomerc/tracking-policy\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport {\n type AnalyticsRetryQueue,\n type AnalyticsRetryQueueEntry,\n createAnalyticsRetryQueue,\n} from \"./analytics-retry-queue.ts\";\nimport type { ConsentManager, ConsentOperations } from \"./consent.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NetworkError } from \"./errors.ts\";\nimport {\n captureLandingTrackingAttribution,\n getTrackingAttributionSnapshot,\n stripLandingTrackingAttributionFromUrl,\n} from \"./tracking-attribution.ts\";\nimport {\n type AnalyticsBrowserAdapter,\n type AnalyticsBrowserEvent,\n type AnalyticsClickIds,\n type AnalyticsConsentState,\n type AnalyticsConsentUpdate,\n type AnalyticsDiagnostic,\n type AnalyticsProperties,\n type AnalyticsUtm,\n INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY,\n shouldDispatchBrowserAdapter,\n TRACKING_SCHEMA_VERSION,\n} from \"./tracking-runtime.ts\";\nimport type {\n ResolvedStorefrontAnalyticsConfig,\n StorageAdapter,\n StorefrontAnalyticsInitConfig,\n StorefrontClientContext,\n} from \"./types.ts\";\n\nexport {\n type AnalyticsRetryQueue,\n type AnalyticsRetryQueueEntry,\n createAnalyticsRetryQueue,\n getAnalyticsRetryQueueKey,\n} from \"./analytics-retry-queue.ts\";\n\nexport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsAdapterOperationSkippedResult,\n AnalyticsAdapterSkipReason,\n AnalyticsBrowserAdapter,\n AnalyticsBrowserEvent,\n AnalyticsBrowserEventDevice,\n AnalyticsClickIds,\n AnalyticsConsentState,\n AnalyticsConsentUpdate,\n AnalyticsDiagnostic,\n AnalyticsEventContextPayload,\n AnalyticsJsonPrimitive,\n AnalyticsJsonValue,\n AnalyticsProperties,\n AnalyticsUtm,\n StorefrontTrackingRuntimeConfig,\n} from \"./tracking-runtime.ts\";\n\nexport interface AnalyticsInitOptions {\n stripUrl?: boolean;\n}\n\nconst ANALYTICS_PATH = \"/analytics/ingest\";\nconst VISITOR_COOKIE_NAME = \"ekomerc_vid\";\nconst SESSION_STORAGE_KEY = \"ekomerc_sid\";\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\nconst KEEPALIVE_MAX_BODY_BYTES = 60 * 1024;\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst LANDING_GA4_CAMPAIGN_QUERY_PARAM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\nconst ACCEPTED_UNKNOWN_RESPONSE: AnalyticsIngestResponse = {\n acceptedCount: 0,\n duplicateCount: 0,\n rejectedCount: 0,\n errors: [],\n};\n\n/**\n * Checkout step identifiers for `checkout_step_completed` analytics events.\n */\nexport type CheckoutStep = \"contact\" | \"shipping\" | \"payment\" | \"review\";\n\n/**\n * Canonical analytics event type values accepted by the storefront ingest endpoint.\n */\nexport type AnalyticsEventType = TrackingPolicyEventType;\n\n/**\n * Supported preset event names accepted by `track()`.\n */\nexport type AnalyticsPresetEventName =\n | \"page_view\"\n | \"product_view\"\n | \"collection_view\"\n | \"search_performed\"\n | \"lead_generated\"\n | \"select_item\"\n | \"add_to_cart\"\n | \"remove_from_cart\"\n | \"view_cart\"\n | \"checkout_started\"\n | \"checkout_step_completed\";\n\nconst ANALYTICS_PRESET_EVENT_MAP = {\n page_view: \"analytics.page_view\",\n product_view: \"analytics.product_view\",\n collection_view: \"analytics.collection_view\",\n search_performed: \"analytics.search_performed\",\n lead_generated: \"analytics.lead_generated\",\n select_item: \"analytics.select_item\",\n add_to_cart: \"analytics.add_to_cart\",\n remove_from_cart: \"analytics.remove_from_cart\",\n view_cart: \"analytics.view_cart\",\n checkout_started: \"analytics.checkout_started\",\n checkout_step_completed: \"analytics.checkout_step_completed\",\n} as const satisfies Record<AnalyticsPresetEventName, AnalyticsEventType>;\n\n/**\n * Event name accepted by `track()`.\n * Preset names (e.g. `product_view`) are normalized to `analytics.*` types.\n * Unknown names are sent as `analytics.custom` with `{ eventName: <name> }`.\n */\nexport type AnalyticsTrackEventName = AnalyticsPresetEventName | AnalyticsEventType;\n\ntype PresetEventProperties = {\n page_view: Record<string, never>;\n product_view: {\n productId: string;\n variantId?: string | null;\n itemId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n currency?: string;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n collection_view: {\n collectionId: string;\n listId?: string;\n listName?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n search_performed: {\n query: string;\n resultsCount: number;\n };\n lead_generated: {\n leadType: string;\n source?: string;\n placement?: string;\n value?: number;\n currency?: string;\n signupOfferId?: string;\n promotionId?: string;\n };\n select_item: {\n productId: string;\n variantId?: string;\n itemId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n currency?: string;\n listId?: string;\n listName?: string;\n index?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n add_to_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n currency: string;\n itemId?: string;\n productId?: string;\n variantId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n remove_from_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n currency: string;\n itemId?: string;\n productId?: string;\n variantId?: string;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n unitPrice?: number;\n price?: number;\n itemCategory?: string;\n lineItems?: AnalyticsLineItemInput[];\n };\n view_cart: {\n cartId: string;\n cartValue: number;\n currency: string;\n itemsCount: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n checkout_started: {\n cartId: string;\n cartValue: number;\n currency: string;\n itemsCount: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n checkout_step_completed: {\n cartId: string;\n step: CheckoutStep;\n cartValue?: number;\n currency?: string;\n itemsCount?: number;\n lineItems?: AnalyticsLineItemInput[];\n };\n};\n\nexport interface AnalyticsLineItemInput {\n itemId?: string;\n productId?: string | null;\n variantId?: string | null;\n sku?: string | null;\n itemName?: string;\n productTitle?: string;\n itemVariant?: string | null;\n variantTitle?: string | null;\n quantity?: number;\n unitPrice?: number;\n price?: number;\n lineTotal?: number;\n itemListId?: string;\n listId?: string;\n itemListName?: string;\n listName?: string;\n index?: number;\n itemCategory?: string;\n}\n\ntype PresetPropertiesByName<T extends AnalyticsPresetEventName> = PresetEventProperties[T];\n\ninterface NormalizedPresetEvent {\n eventType: AnalyticsEventType;\n customEventName?: string;\n}\n\n/**\n * Optional context overrides for a tracking call.\n */\nexport interface AnalyticsContext {\n path?: string;\n referrer?: string | null;\n occurredAt?: Date | string;\n sessionId?: string;\n visitorId?: string;\n customerId?: string | null;\n utmSource?: string | null;\n utmMedium?: string | null;\n utmCampaign?: string | null;\n utmTerm?: string | null;\n utmContent?: string | null;\n consentState?: AnalyticsConsentState;\n clickIds?: Partial<Omit<AnalyticsClickIds, \"schemaVersion\">>;\n deviceType?: string;\n deviceOs?: string | null;\n deviceBrowser?: string | null;\n}\n\n/**\n * Error detail for a single ingest payload item.\n */\nexport interface AnalyticsErrorItem {\n /**\n * Index of the event in the request `events` array.\n */\n index: number;\n\n /**\n * Server-assigned identifier for the event, if available.\n */\n eventId: string | null;\n\n /**\n * Validation or processing error code.\n */\n code: string;\n\n /**\n * Human-readable description of the failure.\n */\n message: string;\n}\n\n/**\n * Response summary from the analytics ingest endpoint.\n */\nexport interface AnalyticsIngestResponse {\n /**\n * Number of events accepted and persisted.\n */\n acceptedCount: number;\n\n /**\n * Number of events recognized as duplicates.\n */\n duplicateCount: number;\n\n /**\n * Number of events rejected by validation or storage.\n */\n rejectedCount: number;\n\n /**\n * Per-item errors, aligned by event index.\n */\n errors: AnalyticsErrorItem[];\n}\n\ninterface AnalyticsIngestPayload {\n events: AnalyticsBrowserEvent[];\n}\n\ninterface SessionState {\n id: string;\n startedAt: number;\n lastSeenAt: number;\n}\n\ninterface DeviceInfo {\n deviceType: string;\n deviceOs: string | null;\n deviceBrowser: string | null;\n}\n\nexport interface ConfirmedPurchaseTrackingLineItem {\n contentId: string;\n productId: string | null;\n variantId: string | null;\n sku: string | null;\n productTitle: string;\n variantTitle: string | null;\n quantity: number;\n unitPrice: { amount: number };\n lineTotal: { amount: number };\n}\n\nexport interface ConfirmedPurchaseTrackingPayload {\n eventId: string;\n orderId: string;\n cartId: string;\n total: { amount: number };\n currency: string;\n numItems: number;\n lineItems: ConfirmedPurchaseTrackingLineItem[];\n}\n\ninterface AnalyticsIngestErrorResponse {\n error?: string;\n details?: { message?: string }[];\n}\n\nexport interface AnalyticsFlushSendOutcome {\n result: Result<AnalyticsIngestResponse, StorefrontError>;\n retryDisposition: {\n retryable: boolean;\n notBefore?: number;\n };\n}\n\nfunction hasBrowserContext(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction getDocument(): Document | null {\n return hasBrowserContext() ? document : null;\n}\n\nfunction getWindow(): Window | null {\n return hasBrowserContext() ? window : null;\n}\n\nfunction isUuid(value: string): boolean {\n return UUID_REGEX.test(value);\n}\n\nfunction randomUuid(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n const template = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\";\n return template.replace(/[xy]/g, (character) => {\n const random = Math.floor(Math.random() * 16);\n const value = character === \"x\" ? random : (random & 0x3) | 0x8;\n return value.toString(16);\n });\n}\n\nfunction getOrCreateVisitorId(): string {\n const doc = getDocument();\n if (doc) {\n const raw = doc.cookie;\n for (const pair of raw.split(\";\")) {\n const [name, ...valueParts] = pair.trim().split(\"=\");\n if (name === VISITOR_COOKIE_NAME) {\n return valueParts.join(\"=\") ? decodeURIComponent(valueParts.join(\"=\")) : randomUuid();\n }\n }\n }\n\n const value = randomUuid();\n if (doc) {\n const maxAge = 60 * 60 * 24 * 365 * 2;\n doc.cookie = `${VISITOR_COOKIE_NAME}=${encodeURIComponent(value)}; Max-Age=${maxAge}; Path=/; SameSite=Lax`;\n }\n\n return value;\n}\n\nlet fallbackSessionState: SessionState | null = null;\n\nfunction getSessionStorageState(): SessionState | null {\n const win = getWindow();\n if (!win) return fallbackSessionState;\n\n try {\n const raw = win.localStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) return fallbackSessionState;\n\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n\n const id = parsed.id;\n const startedAt = parsed.startedAt;\n const lastSeenAt = parsed.lastSeenAt;\n if (typeof id !== \"string\" || !id) return null;\n if (typeof startedAt !== \"number\" || typeof lastSeenAt !== \"number\") return null;\n\n return { id, startedAt, lastSeenAt };\n } catch {\n return fallbackSessionState;\n }\n}\n\nfunction setSessionStorageState(state: SessionState): void {\n fallbackSessionState = state;\n const win = getWindow();\n if (!win) return;\n\n try {\n win.localStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(state));\n } catch {\n // ignore localStorage failures\n }\n}\n\nfunction resolveSessionState(existing: SessionState | null, nowMs: number): SessionState {\n if (!existing) {\n return { id: randomUuid(), startedAt: nowMs, lastSeenAt: nowMs };\n }\n\n if (nowMs - existing.lastSeenAt > SESSION_TIMEOUT_MS) {\n return { id: randomUuid(), startedAt: nowMs, lastSeenAt: nowMs };\n }\n\n return { id: existing.id, startedAt: existing.startedAt, lastSeenAt: nowMs };\n}\n\nfunction resolveSessionId(nowMs: number): string {\n const existing = getSessionStorageState();\n const state = resolveSessionState(existing, nowMs);\n setSessionStorageState(state);\n return state.id;\n}\n\nfunction base64UrlDecode(value: string): string {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = normalized.length % 4;\n const padded = padding === 0 ? normalized : normalized + \"=\".repeat(4 - padding);\n return atob(padded);\n}\n\nfunction parseJWT(payload: string): Record<string, unknown> | null {\n try {\n const decoded = base64UrlDecode(payload);\n const parsed = JSON.parse(decoded);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n}\n\nfunction parseCustomerIdFromToken(token: string | null): string | null {\n if (!token) return null;\n\n const payload = token.split(\".\");\n const encodedPayload = payload[1];\n if (!encodedPayload) return null;\n\n const parsed = parseJWT(encodedPayload);\n if (!parsed) return null;\n\n const customerId = parsed.customerId;\n return typeof customerId === \"string\" && isUuid(customerId) ? customerId : null;\n}\n\nfunction decodeAnalyticsEntityId(value: string | null | undefined): string | null {\n if (!value) return null;\n return isUuid(value) ? value : null;\n}\n\nfunction normalizePositiveQuantity(value: number | null | undefined): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction normalizeOptionalNumber(value: number | null | undefined): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction normalizeOptionalString(value: string | null | undefined): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction normalizeOptionalNullableString(value: string | null | undefined): string | null | undefined {\n if (value === null) {\n return null;\n }\n\n return normalizeOptionalString(value);\n}\n\nfunction buildAnalyticsLineItem(input: AnalyticsLineItemInput): AnalyticsProperties {\n const productId = decodeAnalyticsEntityId(input.productId);\n const variantId = decodeAnalyticsEntityId(input.variantId);\n const sku = normalizeOptionalNullableString(input.sku);\n const quantity = normalizePositiveQuantity(input.quantity);\n const unitPrice = normalizeOptionalNumber(input.unitPrice ?? input.price);\n const lineTotal =\n normalizeOptionalNumber(input.lineTotal) ?? (unitPrice !== undefined ? unitPrice * quantity : undefined);\n const itemName = normalizeOptionalString(input.itemName ?? input.productTitle);\n const itemVariant = normalizeOptionalNullableString(input.itemVariant ?? input.variantTitle);\n const itemId = normalizeOptionalString(input.itemId) ?? variantId ?? sku ?? productId ?? undefined;\n const itemListId = normalizeOptionalString(input.itemListId ?? input.listId);\n const itemListName = normalizeOptionalString(input.itemListName ?? input.listName);\n const index =\n typeof input.index === \"number\" && Number.isFinite(input.index) ? Math.max(0, Math.floor(input.index)) : undefined;\n const itemCategory = normalizeOptionalString(input.itemCategory);\n\n const item: AnalyticsProperties = {\n quantity,\n };\n\n if (itemId) item.itemId = itemId;\n if (productId) item.productId = productId;\n if (variantId) item.variantId = variantId;\n if (sku !== undefined) item.sku = sku;\n if (itemName) {\n item.itemName = itemName;\n item.productTitle = itemName;\n }\n if (itemVariant !== undefined) {\n item.itemVariant = itemVariant;\n item.variantTitle = itemVariant;\n }\n if (unitPrice !== undefined) {\n item.unitPrice = unitPrice;\n item.price = unitPrice;\n }\n if (lineTotal !== undefined) item.lineTotal = lineTotal;\n if (itemListId) {\n item.itemListId = itemListId;\n item.listId = itemListId;\n }\n if (itemListName) {\n item.itemListName = itemListName;\n item.listName = itemListName;\n }\n if (index !== undefined) item.index = index;\n if (itemCategory) item.itemCategory = itemCategory;\n\n return item;\n}\n\nfunction buildLineItems(input: AnalyticsLineItemInput[] | undefined): AnalyticsProperties[\"lineItems\"] | undefined {\n if (!input || input.length === 0) {\n return undefined;\n }\n\n return input.map((item) => buildAnalyticsLineItem(item));\n}\n\nfunction applyLineItemToProperties(properties: AnalyticsProperties, lineItem: AnalyticsProperties): void {\n const itemId = lineItem.itemId;\n if (typeof itemId === \"string\") {\n properties.itemId = itemId;\n }\n\n const productId = lineItem.productId;\n if (typeof productId === \"string\") {\n properties.productId = productId;\n }\n\n const variantId = lineItem.variantId;\n if (typeof variantId === \"string\") {\n properties.variantId = variantId;\n }\n\n const sku = lineItem.sku;\n if (typeof sku === \"string\" || sku === null) {\n properties.sku = sku;\n }\n\n const itemName = lineItem.itemName;\n if (typeof itemName === \"string\") {\n properties.itemName = itemName;\n properties.productTitle = itemName;\n }\n\n const itemVariant = lineItem.itemVariant;\n if (typeof itemVariant === \"string\" || itemVariant === null) {\n properties.itemVariant = itemVariant;\n properties.variantTitle = itemVariant;\n }\n\n const unitPrice = lineItem.unitPrice;\n if (typeof unitPrice === \"number\") {\n properties.unitPrice = unitPrice;\n properties.price = unitPrice;\n }\n\n const lineTotal = lineItem.lineTotal;\n if (typeof lineTotal === \"number\") {\n properties.lineTotal = lineTotal;\n }\n\n const quantity = lineItem.quantity;\n if (typeof quantity === \"number\") {\n properties.quantity = quantity;\n }\n\n const itemListId = lineItem.itemListId;\n if (typeof itemListId === \"string\") {\n properties.itemListId = itemListId;\n properties.listId = itemListId;\n }\n\n const itemListName = lineItem.itemListName;\n if (typeof itemListName === \"string\") {\n properties.itemListName = itemListName;\n properties.listName = itemListName;\n }\n\n const index = lineItem.index;\n if (typeof index === \"number\") {\n properties.index = index;\n }\n\n const itemCategory = lineItem.itemCategory;\n if (typeof itemCategory === \"string\") {\n properties.itemCategory = itemCategory;\n }\n}\n\nfunction resolveDeviceInfo(): DeviceInfo {\n const win = getWindow();\n if (!win) {\n return { deviceType: \"server\", deviceOs: null, deviceBrowser: null };\n }\n\n const ua = win.navigator.userAgent.toLowerCase();\n\n const deviceType = /ipad|tablet|playbook|silk/.test(ua)\n ? \"tablet\"\n : /mobi|android|iphone|ipod|windows phone/.test(ua)\n ? \"mobile\"\n : \"desktop\";\n\n let deviceOs: string | null = null;\n if (ua.includes(\"windows\")) {\n deviceOs = \"Windows\";\n } else if (ua.includes(\"mac os\") || ua.includes(\"macintosh\")) {\n deviceOs = \"macOS\";\n } else if (ua.includes(\"android\")) {\n deviceOs = \"Android\";\n } else if (ua.includes(\"iphone\") || ua.includes(\"ipad\") || ua.includes(\"ios\")) {\n deviceOs = \"iOS\";\n } else if (ua.includes(\"linux\")) {\n deviceOs = \"Linux\";\n }\n\n let deviceBrowser: string | null = null;\n if (ua.includes(\"edg/\")) {\n deviceBrowser = \"Edge\";\n } else if (ua.includes(\"firefox/\")) {\n deviceBrowser = \"Firefox\";\n } else if (ua.includes(\"chrome/\") && !ua.includes(\"edg/\")) {\n deviceBrowser = \"Chrome\";\n } else if (ua.includes(\"safari/\") && !ua.includes(\"chrome/\")) {\n deviceBrowser = \"Safari\";\n }\n\n return { deviceType, deviceOs, deviceBrowser };\n}\n\nfunction normalizePath(pathname: string): string {\n return pathname.trim().length > 0 ? pathname : \"/\";\n}\n\nfunction toIsoTimestamp(value: Date | string | number | null | undefined): string | null {\n if (value == null) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n}\n\nfunction buildUtmPayload(context: AnalyticsContext, trackingAttributionTtlMs?: number): AnalyticsUtm {\n const persisted = getTrackingAttributionSnapshot({ ttlMs: trackingAttributionTtlMs });\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n source: context.utmSource ?? persisted?.utm.source ?? null,\n medium: context.utmMedium ?? persisted?.utm.medium ?? null,\n campaign: context.utmCampaign ?? persisted?.utm.campaign ?? null,\n term: context.utmTerm ?? persisted?.utm.term ?? null,\n content: context.utmContent ?? persisted?.utm.content ?? null,\n };\n}\n\nfunction buildClickIdsPayload(context: AnalyticsContext, trackingAttributionTtlMs?: number): AnalyticsClickIds {\n const persisted = getTrackingAttributionSnapshot({ ttlMs: trackingAttributionTtlMs });\n const clickIds = context.clickIds;\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n capturedAt: toIsoTimestamp(clickIds?.capturedAt) ?? persisted?.clickIds.capturedAt ?? null,\n gclid: clickIds?.gclid ?? persisted?.clickIds.gclid ?? null,\n gbraid: clickIds?.gbraid ?? persisted?.clickIds.gbraid ?? null,\n wbraid: clickIds?.wbraid ?? persisted?.clickIds.wbraid ?? null,\n ttclid: clickIds?.ttclid ?? persisted?.clickIds.ttclid ?? null,\n fbclid: clickIds?.fbclid ?? persisted?.clickIds.fbclid ?? null,\n };\n}\n\nfunction buildDefaultContext(): AnalyticsContext {\n const context: AnalyticsContext = {};\n const device = resolveDeviceInfo();\n\n const win = getWindow();\n if (win) {\n const { pathname, search } = win.location;\n context.path = pathname + search;\n context.referrer = win.document.referrer.length > 0 ? win.document.referrer : null;\n const params = new URLSearchParams(win.location.search);\n context.utmSource = params.get(\"utm_source\");\n context.utmMedium = params.get(\"utm_medium\");\n context.utmCampaign = params.get(\"utm_campaign\");\n context.utmTerm = params.get(\"utm_term\");\n context.utmContent = params.get(\"utm_content\");\n context.deviceType = device.deviceType;\n context.deviceOs = device.deviceOs;\n context.deviceBrowser = device.deviceBrowser;\n }\n\n if (!context.deviceType) {\n context.deviceType = \"unknown\";\n }\n\n context.deviceOs ??= null;\n context.deviceBrowser ??= null;\n\n return context;\n}\n\nfunction normalizeEventContext(context: AnalyticsContext | undefined): AnalyticsContext {\n const defaults = buildDefaultContext();\n return { ...defaults, ...context };\n}\n\nfunction hasCurrentLandingGa4CampaignParams(): boolean {\n const win = getWindow();\n if (!win) {\n return false;\n }\n\n const params = new URLSearchParams(win.location.search);\n return LANDING_GA4_CAMPAIGN_QUERY_PARAM_KEYS.some((key) => {\n const value = params.get(key);\n return value !== null && value.trim().length > 0;\n });\n}\n\nfunction isIngestResponse(value: unknown): value is AnalyticsIngestResponse {\n if (typeof value !== \"object\" || value === null) return false;\n\n const response = value as Record<string, unknown>;\n\n return (\n typeof response.acceptedCount === \"number\" &&\n typeof response.duplicateCount === \"number\" &&\n typeof response.rejectedCount === \"number\" &&\n Array.isArray(response.errors)\n );\n}\n\nfunction extractErrorMessage(response: Response): Promise<string> {\n return response\n .json()\n .then((payload: AnalyticsIngestErrorResponse) => {\n if (typeof payload.error === \"string\" && payload.error.length > 0) {\n return payload.error;\n }\n\n const firstMessage = Array.isArray(payload.details)\n ? payload.details\n .map((error) => (typeof error?.message === \"string\" ? error.message : null))\n .find((message) => message !== null)\n : null;\n\n if (firstMessage) {\n return firstMessage;\n }\n\n return `Analytics ingest failed with status ${response.status}`;\n })\n .catch(() => `Analytics ingest failed with status ${response.status}`);\n}\n\nfunction parseRetryAfterHeader(response: Response, nowMs: number): number | null {\n const retryAfter = response.headers.get(\"retry-after\");\n if (!retryAfter) {\n return null;\n }\n\n const trimmed = retryAfter.trim();\n if (!/^\\d+$/.test(trimmed)) {\n return null;\n }\n\n const seconds = Number.parseInt(trimmed, 10);\n if (!Number.isFinite(seconds) || seconds <= 0) {\n return null;\n }\n\n return nowMs + seconds * 1000;\n}\n\nfunction toError(error: unknown, message: string): Error {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(message);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport async function flushAnalyticsRetryQueue(\n retryQueue: AnalyticsRetryQueue,\n sendEventOutcome: (event: AnalyticsBrowserEvent) => Promise<AnalyticsFlushSendOutcome>,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n nowMs = Date.now(),\n): Promise<number> {\n const queuedEntries = retryQueue.read(nowMs);\n const nextEntries: AnalyticsRetryQueueEntry[] = [];\n let sentCount = 0;\n\n for (const entry of queuedEntries) {\n if (entry.notBefore !== undefined && entry.notBefore > nowMs) {\n nextEntries.push(entry);\n continue;\n }\n\n const outcome = await sendEventOutcome(entry.event);\n if (outcome.result.isOk()) {\n sentCount += 1;\n continue;\n }\n\n if (!outcome.retryDisposition.retryable) {\n continue;\n }\n\n nextEntries.push({\n event: entry.event,\n queuedAt: entry.queuedAt,\n ...(outcome.retryDisposition.notBefore !== undefined ? { notBefore: outcome.retryDisposition.notBefore } : {}),\n });\n }\n\n retryQueue.replace(nextEntries);\n emitDiagnostic({\n target: \"queue\",\n status: \"flushed\",\n count: sentCount,\n });\n\n return sentCount;\n}\n\nfunction resolveTrackEvent(eventName: AnalyticsTrackEventName): NormalizedPresetEvent {\n const normalized = eventName.startsWith(\"analytics.\") ? eventName.slice(\"analytics.\".length) : eventName;\n if (normalized in ANALYTICS_PRESET_EVENT_MAP) {\n return { eventType: ANALYTICS_PRESET_EVENT_MAP[normalized as AnalyticsPresetEventName] };\n }\n\n return {\n eventType: \"analytics.custom\",\n customEventName: eventName,\n };\n}\n\nfunction dispatchEventToBrowserRuntime(\n runtime:\n | {\n adapters?: AnalyticsBrowserAdapter[];\n }\n | null\n | undefined,\n event: AnalyticsBrowserEvent,\n resolvedAnalytics: ResolvedStorefrontAnalyticsConfig,\n emitDiagnostic: (diagnostic: AnalyticsDiagnostic) => void,\n scheduleBestEffort: (task: () => void | Promise<void>) => void,\n consentManager: ConsentManager | null,\n debug = false,\n onDispatchSuccess?: (provider: AnalyticsBrowserAdapter[\"provider\"]) => void,\n): void {\n const adapters = (runtime?.adapters ?? []).filter(\n (adapter) => adapter.provider !== \"gtm\" || resolvedAnalytics.gtm.enabled,\n );\n if (adapters.length === 0) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] browser dispatch: no adapters available for\", event.eventType);\n }\n return;\n }\n\n const consent: AnalyticsConsentUpdate = {\n consentState: event.consentState,\n };\n\n scheduleBestEffort(async () => {\n for (const adapter of adapters) {\n if (adapter.updateConsent) {\n try {\n const result = await adapter.updateConsent(consent);\n if (result?.status === \"skipped\") {\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"skipped\",\n provider: adapter.provider,\n consent,\n reason: result.reason,\n });\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: result.reason,\n });\n continue;\n }\n\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"success\",\n provider: adapter.provider,\n consent,\n });\n } catch (error) {\n emitDiagnostic({\n target: \"consent_bridge\",\n status: \"error\",\n provider: adapter.provider,\n consent,\n error: toError(error, `Failed to update ${adapter.provider} consent bridge`),\n });\n emitDiagnostic({\n target: \"adapter\",\n status: \"error\",\n provider: adapter.provider,\n event,\n error: toError(error, `Skipped ${adapter.provider} browser tracking event due to consent bridge failure`),\n });\n continue;\n }\n }\n\n const dispatchInput = { event, consent };\n\n if (consentManager) {\n if (consentManager.shouldBuffer(adapter.provider)) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\n `[ekomerc:analytics] adapter ${adapter.provider} buffered (consent pending)`,\n event.eventType,\n );\n }\n consentManager.bufferDispatch({ adapter, input: dispatchInput });\n continue;\n }\n if (consentManager.shouldDiscard(adapter.provider)) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\n `[ekomerc:analytics] adapter ${adapter.provider} discarded (consent denied)`,\n event.eventType,\n );\n }\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: \"consent_blocked\",\n });\n continue;\n }\n } else if ((TRACKING_PROVIDERS as readonly string[]).includes(adapter.provider)) {\n const dispatchDecision = shouldDispatchBrowserAdapter(adapter.provider, event.eventType, event.consentState);\n if (!dispatchDecision.allowed) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(`[ekomerc:analytics] adapter ${adapter.provider} skipped:`, dispatchDecision.reason);\n }\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: dispatchDecision.reason,\n });\n continue;\n }\n }\n\n try {\n const result = await adapter.dispatch(dispatchInput);\n if (result?.status === \"skipped\") {\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: result.reason,\n });\n continue;\n }\n\n emitDiagnostic({\n target: \"adapter\",\n status: \"success\",\n provider: adapter.provider,\n event,\n });\n onDispatchSuccess?.(adapter.provider);\n } catch (error) {\n emitDiagnostic({\n target: \"adapter\",\n status: \"error\",\n provider: adapter.provider,\n event,\n error: toError(error, `Failed to dispatch ${adapter.provider} browser tracking event`),\n });\n }\n }\n });\n}\n\n/**\n * Fire-and-forget emit function used internally by SDK modules for auto-tracking.\n */\nexport type AnalyticsEmitFn = (\n eventType: AnalyticsEventType,\n properties: AnalyticsProperties,\n context?: AnalyticsContext,\n) => void;\n\n/**\n * Minimal product shape accepted by analytics helper methods.\n */\nexport interface AnalyticsProductLike {\n id: string;\n title?: string;\n productType?: string | null;\n primaryCategory?: { name?: string | null } | null;\n variants?: AnalyticsProductVariantLike[];\n}\n\nexport interface AnalyticsProductVariantLike {\n id: string;\n title?: string | null;\n sku?: string | null;\n price?: { amount: number; currency: string };\n}\n\n/**\n * Minimal collection shape accepted by analytics helper methods.\n */\nexport interface AnalyticsCollectionLike {\n id: string;\n title?: string;\n}\n\n/**\n * Minimal cart shape accepted by analytics helper methods.\n */\nexport interface AnalyticsCartLike {\n id: string;\n totalItems: number;\n total: { amount: number; currency: string };\n items?: Array<{\n variantId: string;\n quantity: number;\n effectiveUnitPrice: { amount: number; currency: string };\n lineTotal: { amount: number; currency: string };\n variant?: {\n productId?: string;\n productTitle?: string | null;\n title?: string | null;\n sku?: string | null;\n } | null;\n }>;\n}\n\ntype TrackResult = Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n\n/**\n * Ergonomic helper methods for built-in analytics events.\n */\nexport interface AnalyticsTrackHelpers {\n pageView(context?: AnalyticsContext): TrackResult;\n productView(\n product: AnalyticsProductLike,\n options?: { variant?: AnalyticsProductVariantLike | null },\n context?: AnalyticsContext,\n ): TrackResult;\n collectionView(collection: AnalyticsCollectionLike, context?: AnalyticsContext): TrackResult;\n viewCart(cart: AnalyticsCartLike, context?: AnalyticsContext): TrackResult;\n selectItem(\n product: AnalyticsProductLike,\n options?: {\n variant?: AnalyticsProductVariantLike | null;\n listId?: string;\n listName?: string;\n index?: number;\n },\n context?: AnalyticsContext,\n ): TrackResult;\n custom(eventName: string, properties?: AnalyticsProperties, context?: AnalyticsContext): TrackResult;\n}\n\n/**\n * Combined track function: callable with preset/custom event names, plus helper methods.\n */\nexport interface AnalyticsTrackFn extends AnalyticsTrackHelpers {\n (eventName: \"page_view\", context?: AnalyticsContext): TrackResult;\n (eventName: \"product_view\", input: PresetPropertiesByName<\"product_view\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"collection_view\",\n input: PresetPropertiesByName<\"collection_view\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"search_performed\",\n input: PresetPropertiesByName<\"search_performed\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"lead_generated\",\n input: PresetPropertiesByName<\"lead_generated\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: \"select_item\", input: PresetPropertiesByName<\"select_item\">, context?: AnalyticsContext): TrackResult;\n (eventName: \"add_to_cart\", input: PresetPropertiesByName<\"add_to_cart\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"remove_from_cart\",\n input: PresetPropertiesByName<\"remove_from_cart\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: \"view_cart\", input: PresetPropertiesByName<\"view_cart\">, context?: AnalyticsContext): TrackResult;\n (\n eventName: \"checkout_started\",\n input: PresetPropertiesByName<\"checkout_started\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (\n eventName: \"checkout_step_completed\",\n input: PresetPropertiesByName<\"checkout_step_completed\">,\n context?: AnalyticsContext,\n ): TrackResult;\n (eventName: string, properties: AnalyticsProperties, context?: AnalyticsContext): TrackResult;\n}\n\nexport interface AnalyticsOperations {\n readonly consent: ConsentOperations | null;\n readonly track: AnalyticsTrackFn;\n}\n\ninterface AnalyticsController extends AnalyticsOperations {\n init(input?: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions): void;\n}\n\nexport interface AnalyticsOperationsResult {\n operations: AnalyticsController;\n emit: AnalyticsEmitFn;\n}\n\ninterface AnalyticsRuntimeClient extends StorefrontClientContext {\n _analyticsRuntimeConfig: StorefrontAnalyticsInitConfig | null;\n _resolvedInitConfig: { analytics: ResolvedStorefrontAnalyticsConfig } | null;\n}\n\nfunction isResolvedAnalyticsConfig(\n input: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions | undefined,\n): input is ResolvedStorefrontAnalyticsConfig {\n return Boolean(input && typeof input === \"object\" && \"enabled\" in input && \"gtm\" in input);\n}\n\nfunction buildDefaultResolvedAnalyticsConfig(\n runtime: StorefrontAnalyticsInitConfig | null,\n): ResolvedStorefrontAnalyticsConfig {\n const hasGtmAdapter = runtime?.adapters?.some((adapter) => adapter.provider === \"gtm\") ?? false;\n\n return {\n enabled: true,\n firstPartyEnabled: true,\n gtm: {\n enabled: hasGtmAdapter,\n containerId: null,\n },\n };\n}\n\n/**\n * Builds the storefront analytics controller around the resolved client config, retry queue, and\n * browser lifecycle hooks.\n *\n * Initialization and event dispatch are intentionally decoupled here, so callers can queue\n * tracking work before `client.init()` has finished without reading stale runtime config.\n */\nexport function createAnalyticsOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n consentManager: ConsentManager | null = null,\n): AnalyticsOperationsResult {\n const trackingAttributionTtlMs = client.config.trackingAttributionTTL;\n const debug = client.config.debug === true;\n const runtimeClient = client as AnalyticsRuntimeClient;\n let lifecycleFlushListenersRegistered = false;\n let pendingGa4CampaignOverride = false;\n\n const endpoint = (() => {\n try {\n const parsedEndpoint = new URL(client.config.endpoint);\n return `${parsedEndpoint.origin}${ANALYTICS_PATH}`;\n } catch {\n return null;\n }\n })();\n\n const apiKey = client.config.apiKey;\n\n function getTrackingRuntime(): StorefrontAnalyticsInitConfig | null {\n return runtimeClient._analyticsRuntimeConfig ?? client.config.tracking ?? null;\n }\n\n function getResolvedAnalyticsConfig(): ResolvedStorefrontAnalyticsConfig | null {\n return runtimeClient._resolvedInitConfig?.analytics ?? null;\n }\n\n function hasEnabledGtmAdapter(\n runtime: StorefrontAnalyticsInitConfig | null,\n resolved: ResolvedStorefrontAnalyticsConfig,\n ): boolean {\n return resolved.gtm.enabled && (runtime?.adapters?.some((adapter) => adapter.provider === \"gtm\") ?? false);\n }\n\n function emitDiagnostic(diagnostic: AnalyticsDiagnostic): void {\n try {\n getTrackingRuntime()?.onDiagnostic?.(diagnostic);\n } catch {\n // Diagnostics are observer-only and must never affect storefront flows.\n }\n }\n\n const retryQueue = createAnalyticsRetryQueue(storage, apiKey, emitDiagnostic);\n\n async function resolveConsentState(explicitConsentState?: AnalyticsConsentState): Promise<AnalyticsConsentState> {\n if (explicitConsentState) {\n return explicitConsentState;\n }\n\n const trackingRuntime = getTrackingRuntime();\n if (!trackingRuntime?.resolveConsentState) {\n return consentManager ? consentManager.resolveConsentState() : \"unknown\";\n }\n\n try {\n return await trackingRuntime.resolveConsentState();\n } catch (error) {\n emitDiagnostic({\n target: \"consent\",\n status: \"error\",\n error: toError(error, \"Failed to resolve tracking consent state\"),\n });\n return \"unknown\";\n }\n }\n\n function scheduleBestEffort(task: () => void | Promise<void>): void {\n Promise.resolve()\n .then(task)\n .catch(() => {\n // Best-effort background tasks must not surface to callers.\n });\n }\n\n function flushRetryQueueInBackground(): void {\n const resolved = getResolvedAnalyticsConfig();\n if (resolved && !resolved.firstPartyEnabled) return;\n scheduleBestEffort(async () => {\n await flushAnalyticsRetryQueue(retryQueue, sendEventOutcome, emitDiagnostic);\n });\n }\n\n function registerLifecycleFlushListeners(): void {\n if (!hasBrowserContext() || lifecycleFlushListenersRegistered) {\n return;\n }\n\n const win = getWindow();\n const doc = getDocument();\n if (!win || !doc) {\n return;\n }\n\n win.addEventListener(\"online\", () => {\n flushRetryQueueInBackground();\n });\n\n doc.addEventListener(\"visibilitychange\", () => {\n if (doc.visibilityState === \"hidden\") {\n flushRetryQueueInBackground();\n }\n });\n\n lifecycleFlushListenersRegistered = true;\n }\n\n function init(input?: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions): void {\n if (isResolvedAnalyticsConfig(input)) {\n runtimeClient._resolvedInitConfig = { analytics: input };\n } else {\n runtimeClient._analyticsRuntimeConfig = {\n ...(getTrackingRuntime() ?? {}),\n ...(input ?? {}),\n };\n runtimeClient._resolvedInitConfig ??= {\n analytics: buildDefaultResolvedAnalyticsConfig(getTrackingRuntime()),\n };\n }\n\n pendingGa4CampaignOverride = hasCurrentLandingGa4CampaignParams();\n captureLandingTrackingAttribution({ ttlMs: trackingAttributionTtlMs });\n if (getTrackingRuntime()?.stripUrl !== false) {\n stripLandingTrackingAttributionFromUrl();\n }\n\n if (debug) {\n const resolved = getResolvedAnalyticsConfig();\n const runtime = getTrackingRuntime();\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] init:\", {\n enabled: resolved?.enabled ?? null,\n gtm: resolved?.gtm ?? null,\n adapterCount: runtime?.adapters?.length ?? 0,\n adapters: runtime?.adapters?.map((a) => a.provider) ?? [],\n });\n }\n\n registerLifecycleFlushListeners();\n flushRetryQueueInBackground();\n }\n\n function buildCanonicalEvent(\n eventType: AnalyticsEventType,\n properties: AnalyticsProperties,\n eventContext: AnalyticsContext,\n consentState: AnalyticsConsentState,\n ): AnalyticsBrowserEvent {\n const now = new Date(eventContext.occurredAt ?? Date.now());\n const nowIso = Number.isNaN(now.getTime()) ? new Date().toISOString() : now.toISOString();\n\n const customerId =\n eventContext.customerId === undefined\n ? parseCustomerIdFromToken(client.getCustomerToken())\n : eventContext.customerId;\n\n return {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n eventId: randomUuid(),\n eventType,\n occurredAt: nowIso,\n sessionId: eventContext.sessionId ?? resolveSessionId(now.getTime()),\n visitorId: eventContext.visitorId ?? getOrCreateVisitorId(),\n customerId: customerId ?? null,\n consentState,\n context: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n path: normalizePath(eventContext.path ?? \"/\"),\n },\n referrer: eventContext.referrer ?? null,\n utm: buildUtmPayload(eventContext, trackingAttributionTtlMs),\n clickIds: buildClickIdsPayload(eventContext, trackingAttributionTtlMs),\n device: {\n deviceType: eventContext.deviceType ?? \"unknown\",\n deviceOs: eventContext.deviceOs ?? null,\n deviceBrowser: eventContext.deviceBrowser ?? null,\n },\n properties,\n };\n }\n\n async function sendEventOutcome(event: AnalyticsBrowserEvent): Promise<AnalyticsFlushSendOutcome> {\n if (!endpoint) {\n return {\n result: err(new NetworkError(\"Invalid storefront endpoint\")),\n retryDisposition: { retryable: true },\n };\n }\n\n const payload: AnalyticsIngestPayload = {\n events: [event],\n };\n const body = JSON.stringify(payload);\n const keepalive = new Blob([body]).size <= KEEPALIVE_MAX_BODY_BYTES;\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-storefront-key\": apiKey,\n },\n body,\n ...(keepalive ? { keepalive: true } : {}),\n });\n\n if (!response.ok) {\n const message = response.headers.get(\"content-type\")?.includes(\"application/json\")\n ? await extractErrorMessage(response)\n : `Analytics ingest failed with status ${response.status}`;\n const networkError = new NetworkError(message);\n const nowMs = Date.now();\n const retryDisposition =\n response.status === 429\n ? (() => {\n const notBefore = parseRetryAfterHeader(response, nowMs);\n return notBefore ? { retryable: true, notBefore } : { retryable: false };\n })()\n : response.status >= 500\n ? { retryable: true }\n : { retryable: false };\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition,\n };\n }\n\n let parsed: unknown;\n try {\n parsed = await response.json();\n } catch {\n emitDiagnostic({\n target: \"ingest\",\n status: \"accepted_unknown\",\n event,\n });\n return {\n result: ok(ACCEPTED_UNKNOWN_RESPONSE),\n retryDisposition: { retryable: false },\n };\n }\n\n if (!isIngestResponse(parsed)) {\n const networkError = new NetworkError(\"Analytics response shape is invalid\");\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition: { retryable: false },\n };\n }\n\n emitDiagnostic({\n target: \"ingest\",\n status: \"success\",\n event,\n response: {\n acceptedCount: parsed.acceptedCount,\n duplicateCount: parsed.duplicateCount,\n rejectedCount: parsed.rejectedCount,\n },\n });\n return {\n result: ok(parsed),\n retryDisposition: { retryable: false },\n };\n } catch (error) {\n const networkError = new NetworkError(\"Failed to send analytics event\", {\n cause: error instanceof Error ? error : undefined,\n });\n emitDiagnostic({\n target: \"ingest\",\n status: \"error\",\n event,\n error: networkError,\n });\n return {\n result: err(networkError),\n retryDisposition: { retryable: true },\n };\n }\n }\n\n type NormalizeResult = Result<{ eventType: AnalyticsEventType; properties: AnalyticsProperties }, StorefrontError>;\n\n function normalizePageView(\n payload: unknown,\n context: AnalyticsContext | undefined,\n ): { result: NormalizeResult; context: AnalyticsContext | undefined } {\n return {\n result: ok({ eventType: \"analytics.page_view\", properties: {} }),\n context: context ?? (isPlainObject(payload) ? (payload as AnalyticsContext) : undefined),\n };\n }\n\n function normalizeProductView(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"productId is required\"));\n const p = payload as PresetPropertiesByName<\"product_view\">;\n const productId = decodeAnalyticsEntityId(p.productId);\n if (!productId) return err(new NetworkError(\"Invalid productId\"));\n const variantId = decodeAnalyticsEntityId(p.variantId);\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId,\n variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: 1,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n\n const properties: AnalyticsProperties = {\n productId,\n lineItems,\n };\n if (variantId) properties.variantId = variantId;\n if (p.currency) properties.currency = p.currency;\n applyLineItemToProperties(properties, lineItem);\n\n return ok({\n eventType: \"analytics.product_view\",\n properties,\n });\n }\n\n function normalizeCollectionView(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"collectionId is required\"));\n const p = payload as PresetPropertiesByName<\"collection_view\">;\n const collectionId = decodeAnalyticsEntityId(p.collectionId);\n if (!collectionId) return err(new NetworkError(\"Invalid collectionId\"));\n const properties: AnalyticsProperties = { collectionId };\n if (p.listId) {\n properties.listId = p.listId;\n properties.itemListId = p.listId;\n }\n if (p.listName) {\n properties.listName = p.listName;\n properties.itemListName = p.listName;\n }\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) {\n properties.lineItems = lineItems;\n }\n\n return ok({ eventType: \"analytics.collection_view\", properties });\n }\n\n function normalizeSearchPerformed(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"query is required\"));\n const p = payload as PresetPropertiesByName<\"search_performed\">;\n const trimmed = p.query.trim();\n if (!trimmed) return err(new NetworkError(\"query is required\"));\n return ok({\n eventType: \"analytics.search_performed\",\n properties: { query: trimmed, resultsCount: Math.max(0, Math.floor(p.resultsCount)) },\n });\n }\n\n function normalizeLeadGenerated(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"leadType is required\"));\n const p = payload as PresetPropertiesByName<\"lead_generated\">;\n const leadType = typeof p.leadType === \"string\" ? p.leadType.trim() : \"\";\n if (!leadType) return err(new NetworkError(\"leadType is required\"));\n if (typeof p.value === \"number\" && Number.isFinite(p.value) && !p.currency) {\n return err(new NetworkError(\"currency is required when value is set\"));\n }\n\n const properties: AnalyticsProperties = { leadType };\n if (p.source) {\n properties.source = p.source;\n }\n if (p.placement) {\n properties.placement = p.placement;\n }\n if (typeof p.value === \"number\" && Number.isFinite(p.value)) {\n properties.value = p.value;\n }\n if (p.currency) {\n properties.currency = p.currency;\n }\n if (p.signupOfferId) {\n properties.signupOfferId = p.signupOfferId;\n }\n if (p.promotionId) {\n properties.promotionId = p.promotionId;\n }\n\n return ok({\n eventType: \"analytics.lead_generated\",\n properties,\n });\n }\n\n function normalizeSelectItem(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"productId is required\"));\n const p = payload as PresetPropertiesByName<\"select_item\">;\n const productId = decodeAnalyticsEntityId(p.productId);\n if (!productId) return err(new NetworkError(\"Invalid productId\"));\n const variantId = decodeAnalyticsEntityId(p.variantId);\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId,\n variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: 1,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n itemListId: p.listId,\n listId: p.listId,\n itemListName: p.listName,\n listName: p.listName,\n index: p.index,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n const props: AnalyticsProperties = { productId, lineItems };\n if (variantId) props.variantId = variantId;\n if (p.currency) props.currency = p.currency;\n applyLineItemToProperties(props, lineItem);\n return ok({ eventType: \"analytics.select_item\", properties: props });\n }\n\n function normalizeCartMutationEvent(\n eventType: \"analytics.add_to_cart\" | \"analytics.remove_from_cart\",\n payload: unknown,\n ): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"add_to_cart\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const props: AnalyticsProperties = {\n cartId,\n quantity: Math.max(1, Math.floor(p.quantity)),\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n cartValue: p.cartValue,\n currency: p.currency,\n };\n const lineItem = buildAnalyticsLineItem({\n itemId: p.itemId,\n productId: p.productId,\n variantId: p.variantId,\n sku: p.sku,\n itemName: p.itemName ?? p.productTitle,\n productTitle: p.productTitle,\n itemVariant: p.itemVariant ?? p.variantTitle,\n variantTitle: p.variantTitle,\n quantity: p.quantity,\n unitPrice: p.unitPrice ?? p.price,\n price: p.price,\n lineTotal:\n p.unitPrice !== undefined\n ? p.unitPrice * Math.max(1, Math.floor(p.quantity))\n : p.price !== undefined\n ? p.price * Math.max(1, Math.floor(p.quantity))\n : undefined,\n itemCategory: p.itemCategory,\n });\n const lineItems = buildLineItems(p.lineItems) ?? [lineItem];\n props.lineItems = lineItems;\n applyLineItemToProperties(props, lineItem);\n return ok({ eventType, properties: props });\n }\n\n function normalizeViewCart(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"view_cart\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const lineItems = buildLineItems(p.lineItems);\n return ok({\n eventType: \"analytics.view_cart\",\n properties: {\n cartId,\n cartValue: p.cartValue,\n currency: p.currency,\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n ...(lineItems ? { lineItems } : {}),\n },\n });\n }\n\n function normalizeCheckoutStarted(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"checkout_started\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const props: AnalyticsProperties = {\n cartId,\n cartValue: p.cartValue,\n currency: p.currency,\n itemsCount: Math.max(0, Math.floor(p.itemsCount)),\n };\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) props.lineItems = lineItems;\n return ok({ eventType: \"analytics.checkout_started\", properties: props });\n }\n\n function normalizeCheckoutStepCompleted(payload: unknown): NormalizeResult {\n if (!isPlainObject(payload)) return err(new NetworkError(\"Invalid cartId\"));\n const p = payload as PresetPropertiesByName<\"checkout_step_completed\">;\n const cartId = decodeAnalyticsEntityId(p.cartId);\n if (!cartId) return err(new NetworkError(\"Invalid cartId\"));\n const properties: AnalyticsProperties = { cartId, step: p.step };\n if (typeof p.cartValue === \"number\" && Number.isFinite(p.cartValue)) {\n properties.cartValue = p.cartValue;\n }\n if (p.currency) {\n properties.currency = p.currency;\n }\n if (typeof p.itemsCount === \"number\" && Number.isFinite(p.itemsCount)) {\n properties.itemsCount = Math.max(0, Math.floor(p.itemsCount));\n }\n const lineItems = buildLineItems(p.lineItems);\n if (lineItems) properties.lineItems = lineItems;\n return ok({ eventType: \"analytics.checkout_step_completed\", properties });\n }\n\n async function track(\n eventName: AnalyticsTrackEventName,\n eventPayload?: AnalyticsProperties | PresetPropertiesByName<AnalyticsPresetEventName> | AnalyticsContext,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>> {\n let eventContext: AnalyticsContext | undefined = context;\n const normalized = resolveTrackEvent(eventName);\n let eventType: AnalyticsEventType;\n let properties: AnalyticsProperties;\n\n if (normalized.eventType !== \"analytics.custom\") {\n let normalizeResult: NormalizeResult;\n switch (normalized.eventType) {\n case \"analytics.page_view\": {\n const { result, context: ctx } = normalizePageView(eventPayload, eventContext);\n normalizeResult = result;\n eventContext = ctx;\n break;\n }\n case \"analytics.product_view\":\n normalizeResult = normalizeProductView(eventPayload);\n break;\n case \"analytics.collection_view\":\n normalizeResult = normalizeCollectionView(eventPayload);\n break;\n case \"analytics.search_performed\":\n normalizeResult = normalizeSearchPerformed(eventPayload);\n break;\n case \"analytics.lead_generated\":\n normalizeResult = normalizeLeadGenerated(eventPayload);\n break;\n case \"analytics.select_item\":\n normalizeResult = normalizeSelectItem(eventPayload);\n break;\n case \"analytics.add_to_cart\":\n normalizeResult = normalizeCartMutationEvent(\"analytics.add_to_cart\", eventPayload);\n break;\n case \"analytics.remove_from_cart\":\n normalizeResult = normalizeCartMutationEvent(\"analytics.remove_from_cart\", eventPayload);\n break;\n case \"analytics.view_cart\":\n normalizeResult = normalizeViewCart(eventPayload);\n break;\n case \"analytics.checkout_started\":\n normalizeResult = normalizeCheckoutStarted(eventPayload);\n break;\n case \"analytics.checkout_step_completed\":\n normalizeResult = normalizeCheckoutStepCompleted(eventPayload);\n break;\n default:\n return err(new NetworkError(`Unsupported event type: ${normalized.eventType}`));\n }\n if (normalizeResult.isErr()) {\n return err(normalizeResult.error);\n }\n ({ eventType, properties } = normalizeResult.value);\n } else {\n eventType = \"analytics.custom\";\n properties = {\n ...(isPlainObject(eventPayload) ? (eventPayload as AnalyticsProperties) : {}),\n eventName: normalized.customEventName ?? eventName,\n };\n }\n\n const normalizedContext = normalizeEventContext(eventContext);\n const resolvedAnalytics = getResolvedAnalyticsConfig() ?? buildDefaultResolvedAnalyticsConfig(getTrackingRuntime());\n if (!resolvedAnalytics.enabled) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track: analytics disabled, skipping\", eventType);\n }\n return ok(ACCEPTED_UNKNOWN_RESPONSE);\n }\n\n const trackingRuntime = getTrackingRuntime();\n const consentState = await resolveConsentState(normalizedContext.consentState);\n const event = buildCanonicalEvent(eventType, properties, normalizedContext, consentState);\n const shouldApplyGa4CampaignOverride = pendingGa4CampaignOverride && eventType === \"analytics.page_view\";\n const browserEvent = shouldApplyGa4CampaignOverride\n ? {\n ...event,\n properties: {\n ...event.properties,\n [INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY]: true,\n },\n }\n : event;\n\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track:\", {\n eventName,\n eventType,\n consentState,\n });\n }\n\n dispatchEventToBrowserRuntime(\n trackingRuntime,\n browserEvent,\n resolvedAnalytics,\n emitDiagnostic,\n scheduleBestEffort,\n consentManager,\n debug,\n (provider) => {\n if (shouldApplyGa4CampaignOverride && provider === \"gtm\") {\n pendingGa4CampaignOverride = false;\n }\n },\n );\n if (shouldApplyGa4CampaignOverride && !hasEnabledGtmAdapter(trackingRuntime, resolvedAnalytics)) {\n pendingGa4CampaignOverride = false;\n }\n\n if (!resolvedAnalytics.firstPartyEnabled) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] track: first-party disabled, skipping ingest\", eventType);\n }\n return ok(ACCEPTED_UNKNOWN_RESPONSE);\n }\n\n const outcome = await sendEventOutcome(event);\n if (outcome.result.isErr() && outcome.retryDisposition.retryable) {\n retryQueue.enqueue({\n event,\n queuedAt: Date.now(),\n ...(outcome.retryDisposition.notBefore !== undefined ? { notBefore: outcome.retryDisposition.notBefore } : {}),\n });\n }\n\n if (outcome.result.isOk() && retryQueue.read().length > 0) {\n flushRetryQueueInBackground();\n }\n\n return outcome.result;\n }\n\n const trackFn = Object.assign(track, {\n pageView(context?: AnalyticsContext) {\n return track(\"page_view\", context);\n },\n productView(\n product: AnalyticsProductLike,\n options?: { variant?: AnalyticsProductVariantLike | null },\n context?: AnalyticsContext,\n ) {\n const variant =\n product.variants?.find((entry) => entry.id === options?.variant?.id) ??\n options?.variant ??\n product.variants?.[0];\n const itemCategory = product.primaryCategory?.name ?? product.productType ?? undefined;\n const variantId = variant?.id;\n const props: PresetPropertiesByName<\"product_view\"> = {\n productId: product.id,\n ...(variantId ? { variantId } : {}),\n ...(product.title ? { productTitle: product.title, itemName: product.title } : {}),\n ...(variant?.title ? { variantTitle: variant.title, itemVariant: variant.title } : {}),\n ...(variant?.sku !== undefined ? { sku: variant.sku } : {}),\n ...(variant?.price\n ? { unitPrice: variant.price.amount, price: variant.price.amount, currency: variant.price.currency }\n : {}),\n ...(itemCategory ? { itemCategory } : {}),\n };\n return track(\"product_view\", props, context);\n },\n collectionView(collection: AnalyticsCollectionLike, context?: AnalyticsContext) {\n return track(\n \"collection_view\",\n {\n collectionId: collection.id,\n ...(collection.id ? { listId: collection.id } : {}),\n ...(collection.title ? { listName: collection.title } : {}),\n },\n context,\n );\n },\n viewCart(cart: AnalyticsCartLike, context?: AnalyticsContext) {\n return track(\n \"view_cart\",\n {\n cartId: cart.id,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n ...(cart.items\n ? {\n lineItems: cart.items.map((item) => ({\n itemId: item.variantId,\n ...(item.variant?.productId ? { productId: item.variant.productId } : {}),\n variantId: item.variantId,\n ...(item.variant?.sku !== undefined ? { sku: item.variant.sku } : {}),\n ...((item.variant?.productTitle ?? item.variant?.title)\n ? {\n itemName: item.variant?.productTitle ?? item.variant?.title ?? null,\n productTitle: item.variant?.productTitle ?? item.variant?.title ?? null,\n }\n : {}),\n ...(item.variant?.title ? { itemVariant: item.variant.title, variantTitle: item.variant.title } : {}),\n quantity: item.quantity,\n unitPrice: item.effectiveUnitPrice.amount,\n price: item.effectiveUnitPrice.amount,\n lineTotal: item.lineTotal.amount,\n })),\n }\n : {}),\n },\n context,\n );\n },\n selectItem(\n product: AnalyticsProductLike,\n options?: {\n variant?: AnalyticsProductVariantLike | null;\n listId?: string;\n listName?: string;\n index?: number;\n },\n context?: AnalyticsContext,\n ) {\n const props: AnalyticsProperties = { productId: product.id };\n const variant =\n product.variants?.find((entry) => entry.id === options?.variant?.id) ??\n options?.variant ??\n product.variants?.[0];\n const variantId = variant?.id;\n if (variantId) props.variantId = variantId;\n if (product.title) {\n props.productTitle = product.title;\n props.itemName = product.title;\n }\n if (variant?.title) {\n props.variantTitle = variant.title;\n props.itemVariant = variant.title;\n }\n if (variant?.sku !== undefined) props.sku = variant.sku;\n if (variant?.price) {\n props.unitPrice = variant.price.amount;\n props.price = variant.price.amount;\n props.currency = variant.price.currency;\n }\n if (options?.listId) props.listId = options.listId;\n if (options?.listName) props.listName = options.listName;\n if (options?.index !== undefined) props.index = options.index;\n const itemCategory = product.primaryCategory?.name ?? product.productType ?? undefined;\n if (itemCategory) props.itemCategory = itemCategory;\n return track(\"select_item\", props, context);\n },\n custom(eventName: string, properties?: AnalyticsProperties, context?: AnalyticsContext) {\n return track(eventName as AnalyticsTrackEventName, properties ?? {}, context);\n },\n } satisfies AnalyticsTrackHelpers) as AnalyticsTrackFn;\n\n const emit: AnalyticsEmitFn = (eventType, properties, context) => {\n void track(eventType as AnalyticsTrackEventName, properties, context);\n };\n\n return {\n operations: {\n consent: consentManager,\n init,\n track: trackFn,\n },\n emit,\n };\n}\n\n/**\n * Builds the canonical `analytics.checkout_completed` event properties from a confirmed purchase payload.\n * This is the single source of truth for how purchase data maps to event property keys.\n */\nexport function buildConfirmedPurchaseEventProperties(purchaseTracking: ConfirmedPurchaseTrackingPayload): {\n orderId: string;\n cartId: string;\n orderTotal: number;\n currency: string;\n numItems: number;\n lineItems: Array<{\n contentId: string;\n itemId: string;\n variantId: string | null;\n productId: string | null;\n sku: string | null;\n productTitle: string;\n variantTitle: string | null;\n quantity: number;\n unitPrice: number;\n lineTotal: number;\n }>;\n} {\n return {\n orderId: purchaseTracking.orderId,\n cartId: purchaseTracking.cartId,\n orderTotal: purchaseTracking.total.amount,\n currency: purchaseTracking.currency,\n numItems: purchaseTracking.numItems,\n lineItems: purchaseTracking.lineItems.map((item) => ({\n contentId: item.contentId,\n itemId: item.contentId,\n variantId: item.variantId,\n productId: item.productId,\n sku: item.sku,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n quantity: item.quantity,\n unitPrice: item.unitPrice.amount,\n lineTotal: item.lineTotal.amount,\n })),\n };\n}\n\nexport function dispatchConfirmedPurchaseBrowserEvent(\n client: StorefrontClientContext,\n purchaseTracking: ConfirmedPurchaseTrackingPayload,\n consentMgr: ConsentManager | null = null,\n): void {\n const trackingAttributionTtlMs = client.config.trackingAttributionTTL;\n const runtimeClient = client as AnalyticsRuntimeClient;\n const trackingRuntime = runtimeClient._analyticsRuntimeConfig ?? client.config.tracking ?? null;\n const resolvedAnalytics =\n runtimeClient._resolvedInitConfig?.analytics ?? buildDefaultResolvedAnalyticsConfig(trackingRuntime);\n if (!trackingRuntime || !resolvedAnalytics.enabled || (trackingRuntime.adapters?.length ?? 0) === 0) {\n return;\n }\n const runtime = trackingRuntime;\n\n function emitDiagnostic(diagnostic: AnalyticsDiagnostic): void {\n try {\n runtime.onDiagnostic?.(diagnostic);\n } catch {\n // Diagnostics are observer-only and must never affect storefront flows.\n }\n }\n\n function scheduleBestEffort(task: () => void | Promise<void>): void {\n Promise.resolve()\n .then(task)\n .catch(() => {\n // Best-effort background tasks must not surface to callers.\n });\n }\n\n async function resolveConsentState(): Promise<AnalyticsConsentState> {\n if (!runtime.resolveConsentState) {\n return consentMgr ? consentMgr.resolveConsentState() : \"unknown\";\n }\n\n try {\n return await runtime.resolveConsentState();\n } catch (error) {\n emitDiagnostic({\n target: \"consent\",\n status: \"error\",\n error: toError(error, \"Failed to resolve tracking consent state\"),\n });\n return \"unknown\";\n }\n }\n\n scheduleBestEffort(async () => {\n const normalizedContext = normalizeEventContext(undefined);\n const consentState = await resolveConsentState();\n const now = new Date();\n const event: AnalyticsBrowserEvent = {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n eventId: purchaseTracking.eventId,\n eventType: \"analytics.checkout_completed\",\n occurredAt: now.toISOString(),\n sessionId: resolveSessionId(now.getTime()),\n visitorId: getOrCreateVisitorId(),\n customerId: parseCustomerIdFromToken(client.getCustomerToken()),\n consentState,\n context: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n path: normalizePath(normalizedContext.path ?? \"/\"),\n },\n referrer: normalizedContext.referrer ?? null,\n utm: buildUtmPayload(normalizedContext, trackingAttributionTtlMs),\n clickIds: buildClickIdsPayload(normalizedContext, trackingAttributionTtlMs),\n device: {\n deviceType: normalizedContext.deviceType ?? \"unknown\",\n deviceOs: normalizedContext.deviceOs ?? null,\n deviceBrowser: normalizedContext.deviceBrowser ?? null,\n },\n properties: buildConfirmedPurchaseEventProperties(purchaseTracking),\n };\n\n dispatchEventToBrowserRuntime(\n runtime,\n event,\n resolvedAnalytics,\n emitDiagnostic,\n scheduleBestEffort,\n consentMgr,\n client.config.debug === true,\n );\n });\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_SESSION_KEY } from \"./storage.ts\";\nimport type { Customer, StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface CustomerData {\n id: string;\n name: string | null;\n email: string;\n emailVerified: boolean;\n}\n\ninterface CustomerRegisterResponse {\n customerRegister: {\n customer: CustomerData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerLoginResponse {\n customerLogin: {\n customer: CustomerData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerPasswordResetRequestResponse {\n customerPasswordResetRequest: {\n success: boolean;\n userErrors: UserError[];\n };\n}\n\ninterface CustomerPasswordResetResponse {\n customerPasswordReset: {\n success: boolean;\n userErrors: UserError[];\n };\n}\n\ninterface MeResponse {\n me: CustomerData | null;\n}\n\nconst CUSTOMER_FRAGMENT = `\n id\n name\n email\n emailVerified\n`;\n\nconst CUSTOMER_REGISTER_MUTATION = `\nmutation CustomerRegister($input: CustomerRegisterInput!) {\n customerRegister(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\n token\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_LOGIN_MUTATION = `\nmutation CustomerLogin($input: CustomerLoginInput!) {\n customerLogin(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\n token\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_PASSWORD_RESET_REQUEST_MUTATION = `\nmutation CustomerPasswordResetRequest($input: CustomerPasswordResetRequestInput!) {\n customerPasswordResetRequest(input: $input) {\n success\n userErrors { field message code }\n }\n}\n`;\n\nconst CUSTOMER_PASSWORD_RESET_MUTATION = `\nmutation CustomerPasswordReset($input: CustomerPasswordResetInput!) {\n customerPasswordReset(input: $input) {\n success\n userErrors { field message code }\n }\n}\n`;\n\nconst ME_QUERY = `\nquery Me {\n me { ${CUSTOMER_FRAGMENT} }\n}\n`;\n\nfunction mapCustomerData(data: CustomerData): Customer {\n return {\n id: data.id,\n name: data.name,\n email: data.email,\n emailVerified: data.emailVerified,\n };\n}\n\nfunction mapUserErrors(userErrors: UserError[]): ValidationError | null {\n if (userErrors.length === 0) return null;\n const messages = userErrors.map((e) => e.message).join(\"; \");\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\n\n/**\n * Customer auth operations. Note: `logout` and `isLoggedIn` are synchronous\n * (local token storage only) while all other operations are async and return\n * `Promise<Result<...>>`.\n */\nexport interface AuthOperations {\n /**\n * Register a customer account and store the returned auth token when the API returns one.\n *\n * @param input - Registration credentials and optional name.\n * @returns The registered customer and nullable token.\n */\n register(input: {\n email: string;\n password: string;\n name?: string;\n }): Promise<Result<{ customer: Customer; token: string | null }, StorefrontError>>;\n /**\n * Log in an existing customer and store the returned auth token.\n *\n * @param input - Customer login credentials.\n * @returns The authenticated customer and token.\n */\n login(input: {\n email: string;\n password: string;\n }): Promise<Result<{ customer: Customer; token: string }, StorefrontError>>;\n /**\n * Remove the stored customer auth token. Synchronous — no server-side session\n * invalidation occurs; only the local token is cleared.\n */\n logout(): void;\n /**\n * Request a password reset email for a customer account.\n *\n * @param email - Customer email address.\n * @returns Reset request success state.\n */\n requestPasswordReset(email: string): Promise<Result<{ success: boolean }, StorefrontError>>;\n /**\n * Reset a customer password with a reset token.\n *\n * @param input - Reset token and new password.\n * @returns Reset success state.\n */\n resetPassword(input: { token: string; newPassword: string }): Promise<Result<{ success: boolean }, StorefrontError>>;\n /**\n * Fetch the currently authenticated customer.\n *\n * @returns The signed-in customer, or `null` when unauthenticated.\n */\n me(): Promise<Result<Customer | null, StorefrontError>>;\n /**\n * Check whether a customer token is currently stored.\n *\n * @returns `true` when a customer session exists.\n */\n isLoggedIn(): boolean;\n}\n\nexport function createAuthOperations(client: StorefrontClientContext, storage: StorageAdapter): AuthOperations {\n return {\n async register(input) {\n const result = await client.mutate<CustomerRegisterResponse>({\n query: CUSTOMER_REGISTER_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerRegister;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Registration failed\", []));\n }\n\n if (payload.token) {\n storage.set(CUSTOMER_SESSION_KEY, payload.token);\n }\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n async login(input) {\n const result = await client.mutate<CustomerLoginResponse>({\n query: CUSTOMER_LOGIN_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerLogin;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer || !payload.token) {\n return err(new ValidationError(\"Login failed\", []));\n }\n\n storage.set(CUSTOMER_SESSION_KEY, payload.token);\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n logout() {\n storage.remove(CUSTOMER_SESSION_KEY);\n },\n\n async requestPasswordReset(email) {\n const result = await client.mutate<CustomerPasswordResetRequestResponse>({\n query: CUSTOMER_PASSWORD_RESET_REQUEST_MUTATION,\n variables: { input: { email } },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerPasswordResetRequest;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async resetPassword(input) {\n const result = await client.mutate<CustomerPasswordResetResponse>({\n query: CUSTOMER_PASSWORD_RESET_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerPasswordReset;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async me() {\n if (!storage.get(CUSTOMER_SESSION_KEY)) return ok(null);\n\n const result = await client.query<MeResponse>({ query: ME_QUERY }, { cache: false });\n if (result.isErr()) return err(result.error);\n\n return ok(result.value.me ? mapCustomerData(result.value.me) : null);\n },\n\n isLoggedIn() {\n return storage.get(CUSTOMER_SESSION_KEY) !== null;\n },\n };\n}\n","export const CART_ERROR_CODES = {\n required: \"CART_REQUIRED\",\n notFound: \"CART_NOT_FOUND\",\n marketInvalidated: \"CART_MARKET_INVALIDATED\",\n} as const;\n\nexport type CartErrorCode = (typeof CART_ERROR_CODES)[keyof typeof CART_ERROR_CODES];\n\nexport const CART_GONE_ERROR_CODES = [\n CART_ERROR_CODES.required,\n CART_ERROR_CODES.notFound,\n CART_ERROR_CODES.marketInvalidated,\n] as const;\n\nexport type CartGoneErrorCode = (typeof CART_GONE_ERROR_CODES)[number];\n\nexport function isCartGoneErrorCode(code: string | null | undefined): code is CartGoneErrorCode {\n return code != null && (CART_GONE_ERROR_CODES as readonly string[]).includes(code);\n}\n","import type { Collection, Product } from \"./types.ts\";\n\nfunction isAbsoluteUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value);\n}\n\nfunction toOrigin(endpoint: string): string | null {\n try {\n return new URL(endpoint).origin;\n } catch {\n return null;\n }\n}\n\nexport function resolveAssetUrl(url: string, endpoint: string): string {\n if (!url) {\n return url;\n }\n\n if (isAbsoluteUrl(url)) {\n return url;\n }\n\n const origin = toOrigin(endpoint);\n if (!origin) {\n return url;\n }\n\n try {\n return new URL(url, origin).toString();\n } catch {\n return url;\n }\n}\n\nexport function normalizeProductAssetUrls(product: Product, endpoint: string): Product {\n return {\n ...product,\n media: product.media.map((media) => ({\n ...media,\n url: resolveAssetUrl(media.url, endpoint),\n previewUrl: resolveAssetUrl(media.previewUrl, endpoint),\n })),\n variants: product.variants.map((variant) => ({\n ...variant,\n image: variant.image\n ? {\n ...variant.image,\n url: resolveAssetUrl(variant.image.url, endpoint),\n previewUrl: resolveAssetUrl(variant.image.previewUrl, endpoint),\n }\n : null,\n })),\n };\n}\n\nexport function normalizeCollectionAssetUrls(collection: Collection, endpoint: string): Collection {\n return {\n ...collection,\n imageAsset: collection.imageAsset\n ? {\n ...collection.imageAsset,\n url: resolveAssetUrl(collection.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(collection.imageAsset.previewUrl, endpoint),\n }\n : null,\n };\n}\n","import { CART_GONE_ERROR_CODES, isCartGoneErrorCode } from \"@ekomerc/cart-contract\";\nimport { StateError, ValidationError } from \"./errors.ts\";\nimport type { Address, Cart, CartStatus, Money, ProductVariant } from \"./types.ts\";\nimport { resolveAssetUrl } from \"./url.ts\";\n\nexport interface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\nexport interface CartItemData {\n id: string;\n variantId: string;\n quantity: number;\n priceAtAdd: Money;\n effectiveUnitPrice: Money;\n lineTotal: Money;\n taxAmount: Money;\n variant:\n | (Pick<\n ProductVariant,\n | \"id\"\n | \"productId\"\n | \"productTitle\"\n | \"title\"\n | \"sku\"\n | \"price\"\n | \"compareAtPrice\"\n | \"weight\"\n | \"weightUnit\"\n | \"requiresShipping\"\n | \"availableForSale\"\n | \"backInStockSubscriptionAvailable\"\n | \"quantity\"\n | \"selectedOptions\"\n | \"image\"\n | \"isOnSale\"\n | \"quantityPricing\"\n > & {})\n | null;\n}\n\nexport interface AppliedPromoCodeData {\n code: string;\n discountType: string;\n discountAmount: Money;\n description: string;\n}\n\nexport interface AppliedDiscountData {\n promotionId: string;\n discountClass: string;\n discountType: string;\n discountAmount: Money;\n description: string;\n isAutomatic: boolean;\n}\n\nexport interface CartMarketData {\n id: string;\n slug: string;\n currency: string;\n}\n\nexport interface CartData {\n id: string;\n token: string;\n status: CartStatus;\n items: CartItemData[];\n totalItems: number;\n totalPrice: Money;\n taxTotal: Money;\n shippingTotal: Money;\n total: Money;\n discountTotal: Money;\n appliedPromoCode: AppliedPromoCodeData | null;\n appliedDiscounts: AppliedDiscountData[];\n customerEmail: string | null;\n customerPhone: string | null;\n shippingAddress: Address | null;\n billingAddress: Address | null;\n paymentMethod: string | null;\n shippingRateId: string | null;\n notes: string | null;\n checkoutStartedAt?: string | null;\n checkoutExpiresAt?: string | null;\n createdAt: string;\n updatedAt: string;\n market?: CartMarketData | null;\n}\n\nexport const CART_FRAGMENT = `\n id\n token\n status\n items {\n id\n variantId\n quantity\n priceAtAdd { amount currency }\n effectiveUnitPrice { amount currency }\n lineTotal { amount currency }\n taxAmount { amount currency }\n variant {\n id\n productId\n productTitle\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions { id value position }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing { minQuantity price { amount currency } }\n }\n }\n totalItems\n totalPrice { amount currency }\n taxTotal { amount currency }\n shippingTotal { amount currency }\n total { amount currency }\n discountTotal { amount currency }\n appliedPromoCode {\n code\n discountType\n discountAmount { amount currency }\n description\n }\n appliedDiscounts {\n promotionId\n discountClass\n discountType\n discountAmount { amount currency }\n description\n isAutomatic\n }\n customerEmail\n customerPhone\n shippingAddress\n billingAddress\n paymentMethod\n shippingRateId\n notes\n checkoutStartedAt\n checkoutExpiresAt\n createdAt\n updatedAt\n market {\n id\n slug\n currency\n }\n`;\n\nexport function mapCartData(data: CartData, endpoint: string): Cart {\n return {\n id: data.id,\n token: data.token,\n status: data.status,\n items: data.items.map((item) => ({\n id: item.id,\n variantId: item.variantId,\n quantity: item.quantity,\n priceAtAdd: item.priceAtAdd,\n effectiveUnitPrice: item.effectiveUnitPrice,\n lineTotal: item.lineTotal,\n taxAmount: item.taxAmount,\n variant: item.variant\n ? {\n ...item.variant,\n image: item.variant.image\n ? {\n ...item.variant.image,\n url: resolveAssetUrl(item.variant.image.url, endpoint),\n previewUrl: resolveAssetUrl(item.variant.image.previewUrl, endpoint),\n }\n : null,\n }\n : null,\n })),\n totalItems: data.totalItems,\n totalPrice: data.totalPrice,\n taxTotal: data.taxTotal,\n shippingTotal: data.shippingTotal,\n total: data.total,\n discountTotal: data.discountTotal,\n appliedPromoCode: data.appliedPromoCode,\n appliedDiscounts: data.appliedDiscounts,\n customerEmail: data.customerEmail,\n customerPhone: data.customerPhone,\n shippingAddress: data.shippingAddress,\n billingAddress: data.billingAddress,\n paymentMethod: data.paymentMethod,\n shippingRateId: data.shippingRateId,\n notes: data.notes,\n checkoutStartedAt: data.checkoutStartedAt ?? null,\n checkoutExpiresAt: data.checkoutExpiresAt ?? null,\n createdAt: data.createdAt,\n updatedAt: data.updatedAt,\n market: data.market ?? null,\n };\n}\n\nexport function mapUserErrors(\n userErrors: UserError[],\n stateErrorCodes: string[] = [],\n cartStatus: CartStatus | null = null,\n): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n const stateErrorCodeSet = new Set(stateErrorCodes);\n const stateError = userErrors.find((e) => e.code !== null && stateErrorCodeSet.has(e.code));\n\n if (stateError) {\n return new StateError(messages, cartStatus ?? \"\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message, code: e.code })),\n );\n}\n\nexport const CART_GONE_CODES = CART_GONE_ERROR_CODES;\n\n/**\n * True when an error indicates the current cart is gone and should be discarded so the\n * caller can start fresh. Keys off the machine-readable userError code, never message text.\n */\nexport function isCartGoneError(error: unknown): boolean {\n return error instanceof ValidationError && error.userErrors.some((e) => isCartGoneErrorCode(e.code));\n}\n\nexport interface CartQueryResponse {\n cart: CartData | null;\n}\n\nexport const CART_QUERY = `\nquery Cart {\n cart {\n ${CART_FRAGMENT}\n }\n}\n`;\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type CartData, isCartGoneError, mapCartData, mapUserErrors, type UserError } from \"./cart-shared.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Cart, CartStatus, StorefrontClientContext } from \"./types.ts\";\n\ninterface CartMutationPayload {\n cart: CartData | null;\n userErrors: UserError[];\n}\n\ninterface CartMutationRunnerOptions {\n client: StorefrontClientContext;\n cache: CartSnapshotCache;\n}\n\ninterface RunCartMutationOptions {\n execute(): Promise<Result<CartMutationPayload, StorefrontError>>;\n missingCartMessage: string;\n stateErrorCodes?: string[];\n}\n\ninterface RunRecoveringAddMutationOptions extends RunCartMutationOptions {\n hasCartToken(): boolean;\n createCart(): Promise<Result<Cart, StorefrontError>>;\n}\n\ntype CartMutationOutcome =\n | { status: \"ok\"; cart: Cart }\n | { status: \"gone\"; error: StorefrontError }\n | { status: \"error\"; error: StorefrontError };\n\nexport interface CartMutationRunner {\n discardCart(): void;\n clearIfGone(error: StorefrontError): boolean;\n runCartMutation(options: RunCartMutationOptions): Promise<Result<Cart, StorefrontError>>;\n runRecoveringAddMutation(options: RunRecoveringAddMutationOptions): Promise<Result<Cart, StorefrontError>>;\n mapUserError(\n userErrors: UserError[],\n stateErrorCodes?: string[],\n cartStatus?: CartStatus | null,\n ): StorefrontError | null;\n}\n\nexport function createCartMutationRunner({ client, cache }: CartMutationRunnerOptions): CartMutationRunner {\n function discardCart(): void {\n client.clearCartToken();\n cache.clear();\n }\n\n function mapUserError(\n userErrors: UserError[],\n stateErrorCodes: string[] = [],\n cartStatus: CartStatus | null = null,\n ): StorefrontError | null {\n return mapUserErrors(userErrors, stateErrorCodes, cartStatus);\n }\n\n function clearIfGone(error: StorefrontError): boolean {\n if (!isCartGoneError(error)) {\n return false;\n }\n discardCart();\n return true;\n }\n\n async function executeCartMutation(options: RunCartMutationOptions): Promise<CartMutationOutcome> {\n const result = await options.execute();\n if (result.isErr()) {\n return { status: \"error\", error: result.error };\n }\n\n const payload = result.value;\n const userError = mapUserError(payload.userErrors, options.stateErrorCodes, payload.cart?.status ?? null);\n if (userError) {\n if (isCartGoneError(userError)) {\n return { status: \"gone\", error: userError };\n }\n return { status: \"error\", error: userError };\n }\n\n if (!payload.cart) {\n return { status: \"error\", error: new NotFoundError(options.missingCartMessage) };\n }\n\n return { status: \"ok\", cart: cache.set(mapCartData(payload.cart, client.config.endpoint)) };\n }\n\n async function runCartMutation(options: RunCartMutationOptions): Promise<Result<Cart, StorefrontError>> {\n const outcome = await executeCartMutation(options);\n if (outcome.status === \"ok\") {\n return ok(outcome.cart);\n }\n if (outcome.status === \"gone\") {\n clearIfGone(outcome.error);\n }\n return err(outcome.error);\n }\n\n async function runRecoveringAddMutation(\n options: RunRecoveringAddMutationOptions,\n ): Promise<Result<Cart, StorefrontError>> {\n if (options.hasCartToken()) {\n const existing = await executeCartMutation(options);\n if (existing.status === \"ok\") {\n return ok(existing.cart);\n }\n if (existing.status === \"error\") {\n return err(existing.error);\n }\n }\n\n discardCart();\n const created = await options.createCart();\n if (created.isErr()) {\n return err(created.error);\n }\n\n const retry = await executeCartMutation(options);\n if (retry.status === \"ok\") {\n return ok(retry.cart);\n }\n if (retry.status === \"gone\") {\n clearIfGone(retry.error);\n }\n return err(retry.error);\n }\n\n return {\n discardCart,\n clearIfGone,\n runCartMutation,\n runRecoveringAddMutation,\n mapUserError,\n };\n}\n","import { CART_QUERY, type CartQueryResponse, mapCartData } from \"./cart-shared.ts\";\nimport { CART_SESSION_KEY } from \"./storage.ts\";\nimport type { Cart, StorefrontClientContext } from \"./types.ts\";\n\nexport interface CartSnapshotCache {\n get(): Cart | null;\n set(cart: Cart): Cart;\n clear(): void;\n loadSnapshot(): Promise<Cart | null>;\n}\n\nexport function createCartSnapshotCache(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null },\n): CartSnapshotCache {\n let lastKnownCart: Cart | null = null;\n\n return {\n get() {\n return lastKnownCart;\n },\n set(cart: Cart): Cart {\n lastKnownCart = cart;\n return cart;\n },\n clear() {\n lastKnownCart = null;\n },\n async loadSnapshot(): Promise<Cart | null> {\n if (lastKnownCart) return lastKnownCart;\n\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n lastKnownCart = null;\n return null;\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n if (result.isErr()) return null;\n if (!result.value.cart) {\n lastKnownCart = null;\n return null;\n }\n\n lastKnownCart = mapCartData(result.value.cart, client.config.endpoint);\n return lastKnownCart;\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport { createCartMutationRunner } from \"./cart-mutation-runner.ts\";\nimport {\n CART_FRAGMENT,\n CART_QUERY,\n type CartData,\n type CartQueryResponse,\n mapCartData,\n mapUserErrors,\n type UserError,\n} from \"./cart-shared.ts\";\nimport { type CartSnapshotCache, createCartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { CART_SESSION_KEY } from \"./storage.ts\";\nimport { captureLandingTrackingAttribution } from \"./tracking-attribution.ts\";\nimport type { AnalyticsProperties } from \"./tracking-runtime.ts\";\nimport type { Cart, CartItem, StorefrontClientContext } from \"./types.ts\";\n\ninterface CartCreateResponse {\n cartCreate: {\n cart: CartData | null;\n token: string | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemAddResponse {\n cartItemAdd: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemUpdateResponse {\n cartItemUpdate: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartItemRemoveResponse {\n cartItemRemove: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartClearResponse {\n cartClear: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nconst CART_CREATE_MUTATION = `\nmutation CartCreate {\n cartCreate {\n cart {\n ${CART_FRAGMENT}\n }\n token\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_ADD_MUTATION = `\nmutation CartItemAdd($input: CartItemAddInput!) {\n cartItemAdd(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_UPDATE_MUTATION = `\nmutation CartItemUpdate($input: CartItemUpdateInput!) {\n cartItemUpdate(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_ITEM_REMOVE_MUTATION = `\nmutation CartItemRemove($input: CartItemRemoveInput!) {\n cartItemRemove(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_CLEAR_MUTATION = `\nmutation CartClear {\n cartClear {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_PROMO_CODE_APPLY_MUTATION = `\nmutation CartPromoCodeApply($input: CartPromoCodeApplyInput!) {\n cartPromoCodeApply(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CART_PROMO_CODE_REMOVE_MUTATION = `\nmutation CartPromoCodeRemove {\n cartPromoCodeRemove {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\ninterface CartPromoCodeApplyResponse {\n cartPromoCodeApply: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CartPromoCodeRemoveResponse {\n cartPromoCodeRemove: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nexport interface CartOperations {\n /**\n * Load the current cart from the stored cart token.\n *\n * @returns The current cart, or `null` when no cart exists.\n */\n get(): Promise<Result<Cart | null, StorefrontError>>;\n /**\n * Create a new active cart and persist its token.\n *\n * @returns The newly created cart.\n */\n create(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Add a product variant to the active cart.\n *\n * @param variantId - Product variant UUID.\n * @param quantity - Quantity to add.\n * @returns The updated cart.\n */\n addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n /**\n * Update the quantity of an existing cart item.\n *\n * @param variantId - Product variant UUID.\n * @param quantity - New quantity for the item.\n * @returns The updated cart.\n */\n updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove a product variant from the cart.\n *\n * @param variantId - Product variant UUID.\n * @returns The updated cart.\n */\n removeItem(variantId: string): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove all items from the active cart.\n *\n * @returns The emptied cart.\n */\n clear(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Apply a promo code to the active cart.\n *\n * @param code - Promo code to validate and apply.\n * @returns The updated cart with discount data.\n */\n applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>>;\n /**\n * Remove the currently applied promo code from the cart.\n *\n * @returns The updated cart.\n */\n removePromoCode(): Promise<Result<Cart, StorefrontError>>;\n}\n\nfunction buildCartItemProps(cart: Cart, item: CartItem | undefined, quantity: number): AnalyticsProperties {\n const props: AnalyticsProperties = {\n cartId: cart.id,\n quantity,\n itemsCount: cart.totalItems,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n };\n if (item) {\n const itemName =\n (item.variant as (typeof item.variant & { productTitle?: string | null }) | null)?.productTitle ??\n item.variant?.title ??\n undefined;\n const itemVariant = item.variant?.title ?? undefined;\n const unitPrice = item.effectiveUnitPrice.amount;\n const lineTotal = unitPrice * quantity;\n const lineItem: AnalyticsProperties = {\n itemId: item.variantId,\n variantId: item.variantId,\n quantity,\n unitPrice,\n price: unitPrice,\n lineTotal,\n };\n\n props.variantId = item.variantId;\n if (item.variant?.productId) {\n props.productId = item.variant.productId;\n lineItem.productId = item.variant.productId;\n }\n if (item.variant) {\n if (itemVariant !== undefined) {\n props.itemVariant = itemVariant;\n props.variantTitle = itemVariant;\n }\n props.sku = item.variant.sku;\n props.unitPrice = unitPrice;\n props.price = unitPrice;\n if (item.variant.sku !== undefined) {\n lineItem.sku = item.variant.sku;\n }\n if (itemVariant !== undefined) {\n lineItem.itemVariant = itemVariant;\n lineItem.variantTitle = itemVariant;\n }\n }\n if (itemName) {\n props.itemName = itemName;\n props.productTitle = itemName;\n lineItem.itemName = itemName;\n lineItem.productTitle = itemName;\n }\n props.itemId = item.variantId;\n props.lineTotal = lineTotal;\n props.lineItems = [lineItem];\n }\n return props;\n}\n\nexport function createCartOperations(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n emit?: AnalyticsEmitFn,\n snapshotCache?: CartSnapshotCache,\n): CartOperations {\n const cache = snapshotCache ?? createCartSnapshotCache(client, storage);\n const runner = createCartMutationRunner({ client, cache });\n\n function getTrackingAttribution() {\n return (\n captureLandingTrackingAttribution({\n ttlMs: client.config.trackingAttributionTTL,\n }) ?? undefined\n );\n }\n\n const operations: CartOperations = {\n async get(): Promise<Result<Cart | null, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n cache.clear();\n return ok(null);\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n if (result.isErr()) return err(result.error);\n if (!result.value.cart) {\n runner.discardCart();\n return ok(null);\n }\n return ok(cache.set(mapCartData(result.value.cart, client.config.endpoint)));\n },\n\n async create(): Promise<Result<Cart, StorefrontError>> {\n const result = await client.mutate<CartCreateResponse>({\n query: CART_CREATE_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart || !payload.token) {\n return err(new NotFoundError(\"Failed to create cart\"));\n }\n\n storage.set(CART_SESSION_KEY, payload.token);\n return ok(cache.set(mapCartData(payload.cart, client.config.endpoint)));\n },\n\n async addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const result = await runner.runRecoveringAddMutation({\n hasCartToken: () => storage.get(CART_SESSION_KEY) !== null,\n createCart: () => operations.create(),\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemAddResponse>({\n query: CART_ITEM_ADD_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemAdd);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit) {\n const item = cart.items.find((i) => i.variantId === variantId);\n emit(\"analytics.add_to_cart\", buildCartItemProps(cart, item, quantity));\n }\n return ok(cart);\n },\n\n async updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n const previousItem = previousCart?.items.find((i) => i.variantId === variantId);\n const previousQuantity = previousItem?.quantity;\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemUpdateResponse>({\n query: CART_ITEM_UPDATE_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemUpdate);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit && previousQuantity !== undefined) {\n const delta = quantity - previousQuantity;\n if (delta > 0) {\n const item = cart.items.find((i) => i.variantId === variantId);\n emit(\"analytics.add_to_cart\", buildCartItemProps(cart, item, delta));\n } else if (delta < 0) {\n const item = cart.items.find((i) => i.variantId === variantId) ?? previousItem;\n emit(\"analytics.remove_from_cart\", buildCartItemProps(cart, item, Math.abs(delta)));\n }\n }\n return ok(cart);\n },\n\n async removeItem(variantId: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n const previousItem = previousCart?.items.find((i) => i.variantId === variantId);\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartItemRemoveResponse>({\n query: CART_ITEM_REMOVE_MUTATION,\n variables: {\n input: {\n variantId,\n trackingAttribution: getTrackingAttribution(),\n },\n },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartItemRemove);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit && previousItem) {\n emit(\"analytics.remove_from_cart\", buildCartItemProps(cart, previousItem, previousItem.quantity));\n }\n return ok(cart);\n },\n\n async clear(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartClearResponse>({\n query: CART_CLEAR_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartClear);\n },\n });\n\n return result;\n },\n\n async applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartPromoCodeApplyResponse>({\n query: CART_PROMO_CODE_APPLY_MUTATION,\n variables: { input: { code } },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartPromoCodeApply);\n },\n });\n\n return result;\n },\n\n async removePromoCode(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n execute: async () => {\n const result = await client.mutate<CartPromoCodeRemoveResponse>({\n query: CART_PROMO_CODE_REMOVE_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.cartPromoCodeRemove);\n },\n });\n\n return result;\n },\n };\n\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Category, FlatCategory, PaginatedResult, Product, StorefrontClientContext } from \"./types.ts\";\nimport { normalizeProductAssetUrls, resolveAssetUrl } from \"./url.ts\";\n\nexport interface CategoryProductsOptions {\n first?: number;\n after?: string;\n includeDescendants?: boolean;\n}\n\ninterface CategoryImage {\n url: string;\n previewUrl: string;\n altText: string | null;\n width: number | null;\n height: number | null;\n}\n\ninterface RawCategory {\n id: string;\n name: string;\n handle: string;\n description: string | null;\n metaTitle: string | null;\n metaDescription: string | null;\n imageAsset: CategoryImage | null;\n parent: RawCategory | null;\n children: RawCategory[];\n ancestors: RawCategory[];\n productCount: number;\n}\n\ninterface CategoriesTreeQueryResponse {\n storefrontCategories: RawCategory[];\n}\n\ninterface CategoryQueryResponse {\n storefrontCategory: RawCategory | null;\n}\n\ninterface ProductEdge {\n node: Product;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CategoryWithProducts {\n id: string;\n products: ProductConnection;\n}\n\ninterface CategoryProductsQueryResponse {\n storefrontCategory: CategoryWithProducts | null;\n}\n\nconst CATEGORY_FIELDS = `\n id\n name\n handle\n description\n metaTitle\n metaDescription\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n productCount\n`;\n\nconst CATEGORIES_TREE_QUERY = `\nquery CategoriesTree {\n storefrontCategories {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n children {\n ${CATEGORY_FIELDS}\n }\n }\n }\n }\n }\n}\n`;\n\nconst CATEGORY_BY_ID_QUERY = `\nquery CategoryById($id: ID!) {\n storefrontCategory(id: $id) {\n ${CATEGORY_FIELDS}\n parent {\n ${CATEGORY_FIELDS}\n }\n children {\n ${CATEGORY_FIELDS}\n }\n ancestors {\n ${CATEGORY_FIELDS}\n }\n }\n}\n`;\n\nconst CATEGORY_BY_HANDLE_QUERY = `\nquery CategoryByHandle($handle: String!) {\n storefrontCategory(handle: $handle) {\n ${CATEGORY_FIELDS}\n parent {\n ${CATEGORY_FIELDS}\n }\n children {\n ${CATEGORY_FIELDS}\n }\n ancestors {\n ${CATEGORY_FIELDS}\n }\n }\n}\n`;\n\nconst CATEGORY_PRODUCTS_BY_ID_QUERY = `\nquery CategoryProductsById($id: ID!, $first: Int, $after: String, $includeDescendants: Boolean) {\n storefrontCategory(id: $id) {\n id\n products(first: $first, after: $after, includeDescendants: $includeDescendants) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nconst CATEGORY_PRODUCTS_BY_HANDLE_QUERY = `\nquery CategoryProductsByHandle($handle: String!, $first: Int, $after: String, $includeDescendants: Boolean) {\n storefrontCategory(handle: $handle) {\n id\n products(first: $first, after: $after, includeDescendants: $includeDescendants) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nfunction mapRawCategory(raw: RawCategory, endpoint: string): Category {\n return {\n id: raw.id,\n name: raw.name,\n handle: raw.handle,\n description: raw.description,\n metaTitle: raw.metaTitle,\n metaDescription: raw.metaDescription,\n imageAsset: raw.imageAsset\n ? {\n url: resolveAssetUrl(raw.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(raw.imageAsset.previewUrl, endpoint),\n altText: raw.imageAsset.altText,\n width: raw.imageAsset.width,\n height: raw.imageAsset.height,\n }\n : null,\n parent: raw.parent ? mapRawCategory(raw.parent, endpoint) : null,\n children: raw.children?.map((child) => mapRawCategory(child, endpoint)) ?? [],\n ancestors: raw.ancestors?.map((ancestor) => mapRawCategory(ancestor, endpoint)) ?? [],\n productCount: raw.productCount,\n };\n}\n\nfunction flattenTree(categories: Category[], parentId: string | null, depth: number): FlatCategory[] {\n const result: FlatCategory[] = [];\n for (const cat of categories) {\n result.push({\n id: cat.id,\n name: cat.name,\n handle: cat.handle,\n description: cat.description,\n metaTitle: cat.metaTitle,\n metaDescription: cat.metaDescription,\n imageUrl: cat.imageAsset?.url ?? null,\n parentId,\n depth,\n hasChildren: cat.children.length > 0,\n productCount: cat.productCount,\n });\n result.push(...flattenTree(cat.children, cat.id, depth + 1));\n }\n return result;\n}\n\nexport interface CategoriesOperations {\n listAll(): Promise<Result<FlatCategory[], StorefrontError>>;\n /**\n * Fetch the nested storefront category tree.\n *\n * @returns Categories with their child hierarchy.\n */\n tree(): Promise<Result<Category[], StorefrontError>>;\n /**\n * Fetch categories flattened into a parent-aware list.\n *\n * @returns Flat categories with depth and parent metadata.\n */\n flat(): Promise<Result<FlatCategory[], StorefrontError>>;\n /**\n * Fetch a single category by UUID.\n *\n * @param id - Category UUID.\n * @returns The matching category.\n */\n byId(id: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch a single category by handle.\n *\n * @param handle - Category handle.\n * @returns The matching category.\n */\n byHandle(handle: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch a single category by handle.\n *\n * @param handle - Category handle.\n * @returns The matching category.\n */\n get(handle: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch products assigned to a category.\n *\n * @param id - Category UUID.\n * @param options - Pagination and descendant-inclusion options.\n * @returns Paginated products for the category.\n */\n getProductsById(\n id: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n getProductsByHandle(\n handle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCategoriesOperations(client: StorefrontClientContext): CategoriesOperations {\n const operations: CategoriesOperations = {\n listAll: () => operations.flat(),\n async tree(): Promise<Result<Category[], StorefrontError>> {\n const result = await client.query<CategoriesTreeQueryResponse>({\n query: CATEGORIES_TREE_QUERY,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(result.value.storefrontCategories.map((category) => mapRawCategory(category, client.config.endpoint)));\n },\n\n async flat(): Promise<Result<FlatCategory[], StorefrontError>> {\n const result = await client.query<CategoriesTreeQueryResponse>({\n query: CATEGORIES_TREE_QUERY,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const tree = result.value.storefrontCategories.map((category) =>\n mapRawCategory(category, client.config.endpoint),\n );\n return ok(flattenTree(tree, null, 0));\n },\n\n async byId(id: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${id}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Category, StorefrontError>> {\n const result = await client.query<CategoryQueryResponse>({\n query: CATEGORY_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async getProductsById(\n id: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CategoryProductsQueryResponse>({\n query: CATEGORY_PRODUCTS_BY_ID_QUERY,\n variables: {\n id,\n first: options?.first,\n after: options?.after,\n ...(options?.includeDescendants !== undefined && { includeDescendants: options.includeDescendants }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${id}`));\n }\n\n const connection = result.value.storefrontCategory.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async getProductsByHandle(\n handle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CategoryProductsQueryResponse>({\n query: CATEGORY_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n handle,\n first: options?.first,\n after: options?.after,\n ...(options?.includeDescendants !== undefined && { includeDescendants: options.includeDescendants }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.storefrontCategory) {\n return err(new NotFoundError(`Category not found: ${handle}`));\n }\n\n const connection = result.value.storefrontCategory.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n };\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type ConfirmedPurchaseTrackingPayload, dispatchConfirmedPurchaseBrowserEvent } from \"./analytics.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport { NotFoundError, StorefrontError } from \"./errors.ts\";\nimport { CART_SESSION_KEY, getCheckoutLeadDispatchKey } from \"./storage.ts\";\nimport type { StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\nconst CHECKOUT_PURCHASE_DISPATCH_IDS_KEY = \"ekomerc_checkout_purchase_dispatch_ids\";\nconst PAYMENT_RETURN_STORAGE_KEY = \"ekomerc_checkout_payment_return\";\nconst MAX_STORED_PURCHASE_DISPATCH_IDS = 20;\nexport const PAYMENT_RETURN_TTL_MS = 24 * 60 * 60 * 1000;\n\nconst PAYMENT_REF_PATTERN = /^[23456789ABCDEFGHJKMNPQRSTUVWXYZ]{8}$/;\nconst PAYMENT_RETURN_PHASES = [\"redirecting\", \"session_unavailable\", \"checking\", \"pending\", \"failed\"] as const;\n\nexport type PaymentReturnPhase = (typeof PAYMENT_RETURN_PHASES)[number];\n\nexport interface PaymentRecoveryRecord {\n storeId: string;\n paymentRef: string;\n orderNumber: string | null;\n convertedCartToken: string | null;\n tracking: ConfirmedPurchaseTrackingPayload | null;\n phase: PaymentReturnPhase;\n createdAt: number;\n}\n\ninterface PaymentLifecycleContext {\n client: StorefrontClientContext;\n storage: StorageAdapter;\n cache: CartSnapshotCache;\n consentManager: ConsentManager | null;\n}\n\ninterface StoreIdentityResponse {\n store: { id: string } | null;\n}\n\nconst STORE_IDENTITY_QUERY = `\nquery PaymentLifecycleStoreIdentity {\n store { id }\n}\n`;\n\nexport function isPaymentRef(value: string): boolean {\n return PAYMENT_REF_PATTERN.test(value);\n}\n\nexport async function resolvePaymentStoreId(\n client: StorefrontClientContext,\n signal?: AbortSignal,\n): Promise<Result<string, StorefrontError>> {\n const result = await client.query<StoreIdentityResponse>({ query: STORE_IDENTITY_QUERY }, { cache: true, signal });\n if (result.isErr()) return err(result.error);\n if (!result.value.store?.id) return err(new NotFoundError(\"Store not found\"));\n return ok(result.value.store.id);\n}\n\nfunction isTrackingPayload(value: unknown): value is ConfirmedPurchaseTrackingPayload {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<ConfirmedPurchaseTrackingPayload>;\n return typeof candidate.orderId === \"string\" && candidate.orderId.length > 0;\n}\n\nfunction parseRecoveryRecord(raw: string): PaymentRecoveryRecord | null {\n try {\n const value: unknown = JSON.parse(raw);\n if (!value || typeof value !== \"object\") return null;\n const candidate = value as Partial<PaymentRecoveryRecord>;\n if (\n typeof candidate.storeId !== \"string\" ||\n typeof candidate.paymentRef !== \"string\" ||\n !isPaymentRef(candidate.paymentRef) ||\n (candidate.orderNumber !== null && typeof candidate.orderNumber !== \"string\") ||\n (candidate.convertedCartToken !== null && typeof candidate.convertedCartToken !== \"string\") ||\n (candidate.tracking !== null && !isTrackingPayload(candidate.tracking)) ||\n !PAYMENT_RETURN_PHASES.includes(candidate.phase as PaymentReturnPhase) ||\n typeof candidate.createdAt !== \"number\" ||\n !Number.isFinite(candidate.createdAt)\n ) {\n return null;\n }\n return candidate as PaymentRecoveryRecord;\n } catch {\n return null;\n }\n}\n\nfunction storageError(action: string, cause: unknown): StorefrontError {\n return new StorefrontError(`Could not ${action} payment recovery state`, \"STORAGE_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n });\n}\n\n/** Keeps pending attempts recoverable; a new cart supersedes a terminal failed attempt. */\nexport function readPaymentRecovery(\n storage: StorageAdapter,\n storeId: string,\n now = Date.now(),\n): Result<PaymentRecoveryRecord | null, StorefrontError> {\n let raw: string | null;\n let activeCartToken: string | null;\n try {\n raw = storage.get(PAYMENT_RETURN_STORAGE_KEY);\n activeCartToken = storage.get(CART_SESSION_KEY);\n } catch (cause) {\n return err(storageError(\"read\", cause));\n }\n if (!raw) return ok(null);\n\n const record = parseRecoveryRecord(raw);\n if (!record || now - record.createdAt > PAYMENT_RETURN_TTL_MS || record.createdAt > now) {\n clearPaymentRecovery(storage);\n return ok(null);\n }\n if (record.storeId !== storeId) return ok(null);\n if (record.phase === \"failed\" && activeCartToken && activeCartToken !== record.convertedCartToken) {\n clearPaymentRecovery(storage);\n return ok(null);\n }\n return ok(record);\n}\n\nexport function paymentRecoveryExists(storage: StorageAdapter): Result<boolean, StorefrontError> {\n try {\n return ok(storage.get(PAYMENT_RETURN_STORAGE_KEY) !== null);\n } catch (cause) {\n return err(storageError(\"read\", cause));\n }\n}\n\nexport function persistPaymentRecovery(\n storage: StorageAdapter,\n record: PaymentRecoveryRecord,\n): Result<void, StorefrontError> {\n const serialized = JSON.stringify(record);\n try {\n storage.set(PAYMENT_RETURN_STORAGE_KEY, serialized);\n if (storage.get(PAYMENT_RETURN_STORAGE_KEY) !== serialized) {\n return err(storageError(\"persist\", undefined));\n }\n } catch (cause) {\n return err(storageError(\"persist\", cause));\n }\n return ok(undefined);\n}\n\nexport function clearPaymentRecovery(storage: StorageAdapter): void {\n try {\n storage.remove(PAYMENT_RETURN_STORAGE_KEY);\n } catch {\n // Dismissal is intentionally best-effort because the public API is synchronous.\n }\n}\n\nfunction readHandledPurchaseDispatchIds(storage: StorageAdapter): string[] {\n const raw = storage.get(CHECKOUT_PURCHASE_DISPATCH_IDS_KEY);\n if (!raw) return [];\n\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed)\n ? parsed.filter((value): value is string => typeof value === \"string\" && value.length > 0)\n : [];\n } catch {\n return [];\n }\n}\n\nfunction dispatchPurchase(\n context: PaymentLifecycleContext,\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null,\n): void {\n if (!purchaseTracking) return;\n\n const tracking = { ...purchaseTracking, eventId: purchaseTracking.orderId };\n const handledIds = readHandledPurchaseDispatchIds(context.storage);\n if (handledIds.includes(tracking.eventId)) return;\n\n context.storage.set(\n CHECKOUT_PURCHASE_DISPATCH_IDS_KEY,\n JSON.stringify(\n [tracking.eventId, ...handledIds.filter((id) => id !== tracking.eventId)].slice(\n 0,\n MAX_STORED_PURCHASE_DISPATCH_IDS,\n ),\n ),\n );\n dispatchConfirmedPurchaseBrowserEvent(context.client, tracking, context.consentManager);\n}\n\nfunction clearConvertedCart(context: PaymentLifecycleContext, convertedCartToken: string | null): void {\n if (!convertedCartToken) return;\n context.storage.remove(getCheckoutLeadDispatchKey(convertedCartToken));\n if (context.storage.get(CART_SESSION_KEY) !== convertedCartToken) return;\n context.storage.remove(CART_SESSION_KEY);\n context.cache.clear();\n}\n\nexport function finalizeNonRedirectPayment(\n context: PaymentLifecycleContext,\n convertedCartToken: string,\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null,\n): void {\n clearConvertedCart(context, convertedCartToken);\n dispatchPurchase(context, purchaseTracking);\n}\n\nexport function finalizeRedirectPayment(context: PaymentLifecycleContext, record: PaymentRecoveryRecord): void {\n clearConvertedCart(context, record.convertedCartToken);\n dispatchPurchase(context, record.tracking);\n clearPaymentRecovery(context.storage);\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type {\n AnalyticsEmitFn,\n AnalyticsProperties,\n CheckoutStep,\n ConfirmedPurchaseTrackingPayload,\n} from \"./analytics.ts\";\nimport { createCartMutationRunner } from \"./cart-mutation-runner.ts\";\nimport { CART_FRAGMENT, type CartData, type UserError } from \"./cart-shared.ts\";\nimport { type CartSnapshotCache, createCartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport { NotFoundError, StateError, StorefrontError } from \"./errors.ts\";\nimport { finalizeNonRedirectPayment, persistPaymentRecovery, resolvePaymentStoreId } from \"./payment-lifecycle.ts\";\nimport { CART_SESSION_KEY, getCheckoutLeadDispatchKey } from \"./storage.ts\";\nimport type {\n Address,\n Cart,\n CartStatus,\n CheckoutCompletion,\n CheckoutData,\n CheckoutQuote,\n Money,\n Order,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ntype PaymentAction =\n | { kind: \"none\"; redirectUrl: null; paymentRef: null }\n | { kind: \"instructions\"; redirectUrl: null; paymentRef: null }\n | { kind: \"redirect\"; redirectUrl: string; paymentRef: string }\n | { kind: \"redirect_pending\"; redirectUrl: null; paymentRef: string };\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: Money;\n totalPrice: Money;\n taxAmount: Money;\n}\n\ninterface OrderData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n shippingAddress: unknown;\n billingAddress: unknown;\n subtotal: Money;\n shippingTotal: Money;\n shippingTaxAmount: Money;\n discountTotal: Money;\n taxTotal: Money;\n total: Money;\n note: string | null;\n items: OrderItemData[];\n createdAt: string;\n}\n\ninterface CheckoutStartResponse {\n checkoutStart: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CheckoutUpdateResponse {\n checkoutUpdate: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\ninterface PaymentInstructionsData {\n bankAccount: string;\n recipientName: string;\n referenceNumber: string;\n ipsQrCodeBase64: string;\n expiresAt: string;\n}\n\ninterface CheckoutConvertResponse {\n checkoutConvert: {\n order: OrderData | null;\n paymentAction: PaymentAction;\n paymentInstructions: PaymentInstructionsData | null;\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null;\n userErrors: UserError[];\n };\n}\n\ninterface CheckoutAbandonResponse {\n checkoutAbandon: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nfunction buildCheckoutLineItems(cart: Cart): AnalyticsProperties[\"lineItems\"] {\n return cart.items.map((item) => {\n const itemName =\n (item.variant as (typeof item.variant & { productTitle?: string | null }) | null)?.productTitle ??\n item.variant?.title ??\n undefined;\n const itemVariant = item.variant?.title ?? undefined;\n return {\n itemId: item.variantId,\n ...(item.variant?.productId ? { productId: item.variant.productId } : {}),\n variantId: item.variantId,\n ...(item.variant?.sku !== undefined ? { sku: item.variant.sku } : {}),\n ...(itemName ? { itemName, productTitle: itemName } : {}),\n ...(itemVariant ? { itemVariant, variantTitle: itemVariant } : {}),\n quantity: item.quantity,\n unitPrice: item.effectiveUnitPrice.amount,\n price: item.effectiveUnitPrice.amount,\n lineTotal: item.lineTotal.amount,\n };\n });\n}\n\nconst CHECKOUT_START_MUTATION = `\nmutation CheckoutStart {\n checkoutStart {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_UPDATE_MUTATION = `\nmutation CheckoutUpdate($input: CheckoutUpdateInput!) {\n checkoutUpdate(input: $input) {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_CONVERT_MUTATION = `\nmutation CheckoutConvert {\n checkoutConvert {\n order {\n id\n orderNumber\n status\n customerEmail\n customerPhone\n shippingAddress\n billingAddress\n subtotal { amount currency }\n shippingTotal { amount currency }\n shippingTaxAmount { amount currency }\n discountTotal { amount currency }\n taxTotal { amount currency }\n total { amount currency }\n note\n items {\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice { amount currency }\n totalPrice { amount currency }\n taxAmount { amount currency }\n }\n createdAt\n }\n paymentInstructions {\n bankAccount\n recipientName\n referenceNumber\n ipsQrCodeBase64\n expiresAt\n }\n paymentAction {\n kind\n redirectUrl\n paymentRef\n }\n purchaseTracking {\n eventId\n orderId\n cartId\n total { amount currency }\n currency\n numItems\n lineItems {\n contentId\n productId\n variantId\n sku\n productTitle\n variantTitle\n quantity\n unitPrice { amount currency }\n lineTotal { amount currency }\n }\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst CHECKOUT_QUOTE_QUERY = `\nquery CheckoutQuote($shippingRateId: ID, $paymentMethod: PaymentMethod) {\n checkoutQuote(shippingRateId: $shippingRateId, paymentMethod: $paymentMethod) {\n subtotal { amount currency }\n discountTotal { amount currency }\n shippingTotal { amount currency }\n paymentFee { amount currency }\n taxTotal { amount currency }\n total { amount currency }\n }\n}\n`;\n\nconst CHECKOUT_ABANDON_MUTATION = `\nmutation CheckoutAbandon {\n checkoutAbandon {\n cart {\n ${CART_FRAGMENT}\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nfunction mapOrderData(data: OrderData, paymentInstructions: PaymentInstructionsData | null): Order {\n return {\n id: data.id,\n orderNumber: data.orderNumber,\n email: data.customerEmail,\n phone: data.customerPhone,\n status: data.status,\n shippingAddress: data.shippingAddress as Address | null,\n subtotal: data.subtotal,\n shippingTotal: data.shippingTotal,\n shippingTaxAmount: data.shippingTaxAmount,\n discountTotal: data.discountTotal,\n taxTotal: data.taxTotal,\n total: data.total,\n note: data.note,\n items: data.items.map((item) => ({\n id: item.id,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n sku: item.sku,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.totalPrice,\n taxAmount: item.taxAmount,\n })),\n paymentInstructions: paymentInstructions ?? null,\n createdAt: data.createdAt,\n };\n}\n\nconst CHECKOUT_STATE_ERROR_CODES = [\"CART_NOT_IN_CHECKOUT\", \"CHECKOUT_START_ERROR\", \"CHECKOUT_ABANDON_ERROR\"];\n\nfunction checkCartIsInCheckout(status: CartStatus): Result<void, StateError> {\n if (status !== \"checkout\") {\n return err(\n new StateError(`Cart must be in 'checkout' state for this operation. Current state: '${status}'.`, status),\n );\n }\n return ok(undefined);\n}\n\nfunction hasHandledCheckoutLeadDispatch(storage: { get(key: string): string | null }, cartToken: string): boolean {\n return storage.get(getCheckoutLeadDispatchKey(cartToken)) === \"1\";\n}\n\nfunction markCheckoutLeadDispatchHandled(storage: { set(key: string, value: string): void }, cartToken: string): void {\n storage.set(getCheckoutLeadDispatchKey(cartToken), \"1\");\n}\n\nexport interface CheckoutOperations {\n /**\n * Start checkout for the current active cart.\n *\n * @returns The cart in checkout state.\n */\n start(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Update checkout customer, shipping, and payment details.\n *\n * @param data - Checkout fields to update.\n * @returns The updated checkout cart.\n */\n update(data: CheckoutData): Promise<Result<Cart, StorefrontError>>;\n /**\n * Complete checkout and convert the cart into an order.\n *\n * Redirect payments retain the converted cart as a recovery handle until status confirms payment.\n *\n * @returns The created order and the next payment action.\n */\n complete(options?: { navigate?: (url: string) => void }): Promise<Result<CheckoutCompletion, StorefrontError>>;\n /**\n * Abandon checkout and return the cart to an active state.\n *\n * @returns The reactivated cart.\n */\n abandon(): Promise<Result<Cart, StorefrontError>>;\n /**\n * Price the current cart as checkout would charge it, without saving the selection.\n * Omitted options fall back to the cart's saved shipping rate and payment method.\n *\n * @returns The quote, or `null` when there is no cart.\n */\n quote(selection?: {\n shippingRateId?: string;\n paymentMethod?: string;\n }): Promise<Result<CheckoutQuote | null, StorefrontError>>;\n}\n\nfunction isContactStepComplete(cart: Cart): boolean {\n return Boolean(cart.customerEmail && cart.shippingAddress);\n}\n\nfunction detectCheckoutStepAdvances(previousCart: Cart, nextCart: Cart, data: CheckoutData): CheckoutStep[] {\n const steps: CheckoutStep[] = [];\n if (\n (data.email !== undefined || data.phone !== undefined || data.shippingAddress !== undefined) &&\n !isContactStepComplete(previousCart) &&\n isContactStepComplete(nextCart)\n ) {\n steps.push(\"contact\");\n }\n if (data.shippingRateId !== undefined && previousCart.shippingRateId === null && nextCart.shippingRateId !== null) {\n steps.push(\"shipping\");\n }\n if (data.paymentMethod !== undefined && previousCart.paymentMethod === null && nextCart.paymentMethod !== null) {\n steps.push(\"payment\");\n }\n return steps;\n}\n\nexport function createCheckoutOperations(\n client: StorefrontClientContext,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n emit?: AnalyticsEmitFn,\n snapshotCache?: CartSnapshotCache,\n consentMgr: ConsentManager | null = null,\n): CheckoutOperations {\n const cache = snapshotCache ?? createCartSnapshotCache(client, storage);\n const runner = createCartMutationRunner({ client, cache });\n\n return {\n async start(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutStartResponse>({\n query: CHECKOUT_START_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutStart);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n if (emit) {\n emit(\"analytics.checkout_started\", {\n cartId: cart.id,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n lineItems: buildCheckoutLineItems(cart),\n });\n }\n return ok(cart);\n },\n\n async update(data: CheckoutData): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const previousCart = emit ? await cache.loadSnapshot() : null;\n\n const input: Record<string, unknown> = {};\n if (data.email !== undefined) input.customerEmail = data.email;\n if (data.phone !== undefined) input.customerPhone = data.phone;\n if (data.shippingAddress !== undefined) input.shippingAddress = data.shippingAddress;\n if (data.billingAddress !== undefined) input.billingAddress = data.billingAddress;\n if (data.notes !== undefined) input.notes = data.notes;\n if (data.emailMarketingConsent !== undefined) input.emailMarketingConsent = data.emailMarketingConsent;\n if (data.paymentMethod !== undefined) input.paymentMethod = data.paymentMethod;\n if (data.shippingRateId !== undefined) input.shippingRateId = data.shippingRateId;\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutUpdateResponse>({\n query: CHECKOUT_UPDATE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutUpdate);\n },\n });\n\n if (result.isErr()) {\n return result;\n }\n\n const cart = result.value;\n const stateCheck = checkCartIsInCheckout(cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n if (emit && previousCart) {\n const steps = detectCheckoutStepAdvances(previousCart, cart, data);\n for (const step of steps) {\n emit(\"analytics.checkout_step_completed\", {\n cartId: cart.id,\n step,\n cartValue: cart.total.amount,\n currency: cart.total.currency,\n itemsCount: cart.totalItems,\n lineItems: buildCheckoutLineItems(cart),\n });\n }\n\n if (\n !isContactStepComplete(previousCart) &&\n isContactStepComplete(cart) &&\n !hasHandledCheckoutLeadDispatch(storage, cart.token)\n ) {\n emit(\"analytics.lead_generated\", {\n leadType: \"checkout_lead\",\n source: \"checkout\",\n placement: \"checkout\",\n value: cart.total.amount,\n currency: cart.total.currency,\n });\n markCheckoutLeadDispatchHandled(storage, cart.token);\n }\n }\n return ok(cart);\n },\n\n async complete(options?: {\n navigate?: (url: string) => void;\n }): Promise<Result<CheckoutCompletion, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutConvertResponse>({\n query: CHECKOUT_CONVERT_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutConvert;\n const userError = runner.mapUserError(payload.userErrors, CHECKOUT_STATE_ERROR_CODES);\n if (userError && payload.paymentAction?.kind !== \"redirect_pending\") {\n runner.clearIfGone(userError);\n return err(userError);\n }\n\n if (!payload.order) {\n return err(new NotFoundError(\"Order not found\"));\n }\n\n const order = mapOrderData(payload.order, payload.paymentInstructions);\n if (payload.paymentAction.kind === \"none\") {\n finalizeNonRedirectPayment(\n { client, storage, cache, consentManager: consentMgr },\n token,\n payload.purchaseTracking,\n );\n return ok({ kind: \"placed\", order });\n }\n if (payload.paymentAction.kind === \"instructions\") {\n if (!order.paymentInstructions) return err(new NotFoundError(\"Payment instructions not found\"));\n finalizeNonRedirectPayment(\n { client, storage, cache, consentManager: consentMgr },\n token,\n payload.purchaseTracking,\n );\n return ok({ kind: \"instructions\", order, instructions: order.paymentInstructions });\n }\n\n const storeIdResult = await resolvePaymentStoreId(client);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const paymentRef = payload.paymentAction.paymentRef;\n const recoveryResult = persistPaymentRecovery(storage, {\n storeId: storeIdResult.value,\n paymentRef,\n orderNumber: order.orderNumber,\n convertedCartToken: token,\n tracking: payload.purchaseTracking\n ? { ...payload.purchaseTracking, eventId: payload.purchaseTracking.orderId }\n : null,\n phase: payload.paymentAction.kind === \"redirect\" ? \"redirecting\" : \"session_unavailable\",\n createdAt: Date.now(),\n });\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n\n if (payload.paymentAction.kind === \"redirect_pending\") {\n return ok({ kind: \"session_unavailable\", order, paymentRef });\n }\n\n try {\n if (options?.navigate) options.navigate(payload.paymentAction.redirectUrl);\n else if (typeof window !== \"undefined\") window.location.assign(payload.paymentAction.redirectUrl);\n } catch (cause) {\n return err(\n new StorefrontError(\"Could not navigate to the payment provider\", \"NAVIGATION_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n }),\n );\n }\n return ok({ kind: \"redirecting\", order, paymentRef });\n },\n\n async abandon(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_SESSION_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await runner.runCartMutation({\n missingCartMessage: \"Cart not found\",\n stateErrorCodes: CHECKOUT_STATE_ERROR_CODES,\n execute: async () => {\n const result = await client.mutate<CheckoutAbandonResponse>({\n query: CHECKOUT_ABANDON_MUTATION,\n });\n if (result.isErr()) {\n return err(result.error);\n }\n return ok(result.value.checkoutAbandon);\n },\n });\n\n return result;\n },\n\n async quote(selection = {}): Promise<Result<CheckoutQuote | null, StorefrontError>> {\n if (!storage.get(CART_SESSION_KEY)) return ok(null);\n const result = await client.query<{ checkoutQuote: CheckoutQuote | null }>(\n {\n query: CHECKOUT_QUOTE_QUERY,\n variables: {\n shippingRateId: selection.shippingRateId ?? null,\n paymentMethod: selection.paymentMethod ?? null,\n },\n },\n { cache: false },\n );\n return result.map((value) => value.checkoutQuote);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NetworkError, RateLimitError, type StorefrontError } from \"./errors.ts\";\nimport type { PaginatedResult } from \"./types.ts\";\n\n/** Sequentially collects bounded pages and honours Retry-After, with at most three throttle retries per page. */\nexport async function collectAllPages<T>(\n list: (options: { first: number; after?: string }) => Promise<Result<PaginatedResult<T>, StorefrontError>>,\n first = 100,\n): Promise<Result<T[], StorefrontError>> {\n const items: T[] = [];\n let after: string | undefined;\n for (;;) {\n let result = await list({ first, after });\n for (let retry = 0; result.isErr() && result.error instanceof RateLimitError && retry < 3; retry++) {\n const delay = result.error.retryAfterMs;\n await new Promise((resolve) => setTimeout(resolve, delay));\n result = await list({ first, after });\n }\n if (result.isErr()) return err(result.error);\n items.push(...result.value.items);\n if (!result.value.pageInfo.hasNextPage) return ok(items);\n const next = result.value.pageInfo.endCursor;\n if (!next || next === after) return err(new NetworkError(\"Pagination did not advance\"));\n after = next;\n }\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type { Collection, PaginatedResult, Product, StorefrontClientContext } from \"./types.ts\";\nimport { normalizeCollectionAssetUrls, normalizeProductAssetUrls, resolveAssetUrl } from \"./url.ts\";\n\nexport interface CollectionsListOptions {\n first?: number;\n after?: string;\n search?: string;\n}\n\nexport type CollectionProductSort = \"manual\" | \"best_selling\" | \"newest\" | \"price_asc\" | \"price_desc\";\n\nexport interface CollectionProductsOptions {\n first?: number;\n after?: string;\n sort?: CollectionProductSort;\n}\n\ninterface CollectionImage {\n url: string;\n previewUrl: string;\n altText: string | null;\n width: number | null;\n height: number | null;\n}\n\ninterface RawCollection {\n id: string;\n handle: string;\n title: string;\n description: string | null;\n type: string;\n sortOrder: string;\n metaTitle: string | null;\n metaDescription: string | null;\n productCount: number;\n imageAsset: CollectionImage | null;\n}\n\ninterface CollectionEdge {\n node: RawCollection;\n cursor: string;\n}\n\ninterface CollectionConnection {\n edges: CollectionEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CollectionsQueryResponse {\n collections: CollectionConnection;\n}\n\ninterface CollectionQueryResponse {\n collection: RawCollection | null;\n}\n\nfunction mapRawCollection(raw: RawCollection, endpoint: string): Collection {\n return {\n id: raw.id,\n handle: raw.handle,\n title: raw.title,\n description: raw.description,\n type: raw.type as Collection[\"type\"],\n sortOrder: raw.sortOrder as Collection[\"sortOrder\"],\n metaTitle: raw.metaTitle,\n metaDescription: raw.metaDescription,\n productCount: raw.productCount,\n imageAsset: raw.imageAsset\n ? {\n url: resolveAssetUrl(raw.imageAsset.url, endpoint),\n previewUrl: resolveAssetUrl(raw.imageAsset.previewUrl, endpoint),\n altText: raw.imageAsset.altText,\n width: raw.imageAsset.width,\n height: raw.imageAsset.height,\n }\n : null,\n };\n}\n\ninterface ProductEdge {\n node: Product;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface CollectionWithProducts {\n id: string;\n products: ProductConnection;\n}\n\ninterface CollectionProductsQueryResponse {\n collection: CollectionWithProducts | null;\n}\n\nconst COLLECTIONS_QUERY = `\nquery Collections($first: Int, $after: String, $search: String) {\n collections(first: $first, after: $after, search: $search) {\n edges {\n node {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst COLLECTION_BY_ID_QUERY = `\nquery CollectionById($id: ID!) {\n collection(id: $id) {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n}\n`;\n\nconst COLLECTION_BY_HANDLE_QUERY = `\nquery CollectionByHandle($handle: String!) {\n collection(handle: $handle) {\n id\n handle\n title\n description\n type\n sortOrder\n metaTitle\n metaDescription\n productCount\n imageAsset {\n url: gridUrl\n previewUrl: gridUrl\n altText\n width\n height\n }\n }\n}\n`;\n\nconst COLLECTION_PRODUCTS_BY_ID_QUERY = `\nquery CollectionProductsById($id: ID!, $first: Int, $after: String, $sort: CollectionSortOrder) {\n collection(id: $id) {\n id\n products(first: $first, after: $after, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nconst COLLECTION_PRODUCTS_BY_HANDLE_QUERY = `\nquery CollectionProductsByHandle($handle: String!, $first: Int, $after: String, $sort: CollectionSortOrder) {\n collection(handle: $handle) {\n id\n products(first: $first, after: $after, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n}\n`;\n\nexport interface CollectionsOperations {\n listAll(filter?: Pick<CollectionsListOptions, \"search\">): Promise<Result<Collection[], StorefrontError>>;\n /**\n * List collections with cursor pagination and optional search.\n *\n * @param options - Pagination and search options.\n * @returns Paginated storefront collections.\n */\n list(options?: CollectionsListOptions): Promise<Result<PaginatedResult<Collection>, StorefrontError>>;\n /**\n * Fetch a single collection by UUID.\n *\n * @param id - Collection UUID.\n * @returns The matching collection.\n */\n byId(id: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch a single collection by handle.\n *\n * @param handle - Collection handle.\n * @returns The matching collection.\n */\n byHandle(handle: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch a single collection by handle.\n *\n * @param handle - Collection handle.\n * @returns The matching collection.\n */\n get(handle: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch products that belong to a collection.\n *\n * @param id - Collection UUID.\n * @param options - Pagination and collection product options.\n * @returns Paginated products for the collection.\n */\n getProductsById(\n id: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n /**\n * Fetch products that belong to a collection by handle.\n *\n * @param handle - Collection handle.\n * @param options - Pagination and collection product options.\n * @returns Paginated products for the collection.\n */\n getProductsByHandle(\n handle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCollectionsOperations(client: StorefrontClientContext): CollectionsOperations {\n const operations: CollectionsOperations = {\n listAll: (filter) => collectAllPages((options) => operations.list({ ...options, ...filter })),\n async list(options?: CollectionsListOptions): Promise<Result<PaginatedResult<Collection>, StorefrontError>> {\n const result = await client.query<CollectionsQueryResponse>({\n query: COLLECTIONS_QUERY,\n variables: {\n first: options?.first,\n after: options?.after,\n search: options?.search,\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const connection = result.value.collections;\n return ok({\n items: connection.edges.map((edge) => mapRawCollection(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async byId(id: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${id}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Collection, StorefrontError>> {\n const result = await client.query<CollectionQueryResponse>({\n query: COLLECTION_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async getProductsById(\n id: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CollectionProductsQueryResponse>({\n query: COLLECTION_PRODUCTS_BY_ID_QUERY,\n variables: {\n id,\n first: options?.first,\n after: options?.after,\n ...(options?.sort !== undefined && { sort: options.sort }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${id}`));\n }\n\n const connection = result.value.collection.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async getProductsByHandle(\n handle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<CollectionProductsQueryResponse>({\n query: COLLECTION_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n handle,\n first: options?.first,\n after: options?.after,\n ...(options?.sort !== undefined && { sort: options.sort }),\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.collection) {\n return err(new NotFoundError(`Collection not found: ${handle}`));\n }\n\n const connection = result.value.collection.products;\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(edge.node, client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n };\n return operations;\n}\n","import {\n CONSENT_CATEGORIES,\n type ConsentCategory,\n getTrackingProviderRequiredConsent,\n TRACKING_PROVIDER_REQUIRED_CONSENT,\n type TrackingProvider,\n} from \"@ekomerc/tracking-policy\";\nimport { CONSENT_COOKIE_NAME } from \"./storage.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsBrowserAdapter,\n AnalyticsConsentState,\n} from \"./tracking-runtime.ts\";\n\nconst CONSENT_COOKIE_MAX_AGE = 365 * 24 * 60 * 60;\nconst CONSENT_BUFFER_MAX = 100;\n\nexport interface ConsentCategoryState {\n analytics_storage: AnalyticsConsentState;\n ad_storage: AnalyticsConsentState;\n ad_user_data: AnalyticsConsentState;\n ad_personalization: AnalyticsConsentState;\n}\n\nexport type { ConsentCategory };\n\nexport interface ConsentOperations {\n getState(): AnalyticsConsentState;\n getCategories(): ConsentCategoryState;\n grantAll(): void;\n denyAll(): void;\n grant(categories: ConsentCategory[]): void;\n deny(categories: ConsentCategory[]): void;\n update(state: Partial<ConsentCategoryState>): void;\n reset(): void;\n onChange(callback: (state: ConsentCategoryState) => void): () => void;\n}\n\nexport interface ConsentBufferEntry {\n adapter: AnalyticsBrowserAdapter;\n input: AnalyticsAdapterDispatchInput;\n}\n\nexport interface ConsentManager extends ConsentOperations {\n resolveConsentState(): AnalyticsConsentState;\n bufferDispatch(entry: ConsentBufferEntry): void;\n shouldBuffer(provider: TrackingProvider): boolean;\n shouldDispatch(provider: TrackingProvider): boolean;\n shouldDiscard(provider: TrackingProvider): boolean;\n}\n\ntype ConsentChangeCallback = (state: ConsentCategoryState) => void;\ntype ConsentBufferFlushCallback = (entries: ConsentBufferEntry[]) => void;\n\nconst COOKIE_KEY_MAP: Record<ConsentCategory, string> = {\n analytics_storage: \"as\",\n ad_storage: \"ads\",\n ad_user_data: \"aud\",\n ad_personalization: \"ap\",\n};\n\nconst COOKIE_KEY_REVERSE: Record<string, ConsentCategory> = {\n as: \"analytics_storage\",\n ads: \"ad_storage\",\n aud: \"ad_user_data\",\n ap: \"ad_personalization\",\n};\n\nconst COOKIE_VALUE_MAP: Record<AnalyticsConsentState, string> = {\n granted: \"g\",\n denied: \"d\",\n unknown: \"u\",\n};\n\nconst COOKIE_VALUE_REVERSE: Record<string, AnalyticsConsentState> = {\n g: \"granted\",\n d: \"denied\",\n u: \"unknown\",\n};\n\nfunction defaultCategoryState(): ConsentCategoryState {\n return {\n analytics_storage: \"unknown\",\n ad_storage: \"unknown\",\n ad_user_data: \"unknown\",\n ad_personalization: \"unknown\",\n };\n}\n\nfunction hasBrowserCookies(): boolean {\n return typeof document !== \"undefined\" && typeof document.cookie === \"string\";\n}\n\nfunction readConsentCookie(): ConsentCategoryState | null {\n if (!hasBrowserCookies()) return null;\n\n for (const pair of document.cookie.split(\";\")) {\n const [name, ...valueParts] = pair.trim().split(\"=\");\n if (name !== CONSENT_COOKIE_NAME) continue;\n\n const raw = valueParts.join(\"=\");\n if (!raw) return null;\n\n try {\n const decoded = decodeURIComponent(raw);\n const parsed = JSON.parse(decoded);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n\n const state = defaultCategoryState();\n for (const [shortKey, shortValue] of Object.entries(parsed)) {\n const category = COOKIE_KEY_REVERSE[shortKey];\n const consentValue = typeof shortValue === \"string\" ? COOKIE_VALUE_REVERSE[shortValue] : undefined;\n if (category && consentValue) {\n state[category] = consentValue;\n }\n }\n return state;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\nfunction writeConsentCookie(state: ConsentCategoryState): void {\n if (!hasBrowserCookies()) return;\n\n const compact: Record<string, string> = {};\n for (const category of CONSENT_CATEGORIES) {\n compact[COOKIE_KEY_MAP[category]] = COOKIE_VALUE_MAP[state[category]];\n }\n\n const value = encodeURIComponent(JSON.stringify(compact));\n // biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API not universally available\n document.cookie = `${CONSENT_COOKIE_NAME}=${value}; Max-Age=${CONSENT_COOKIE_MAX_AGE}; Path=/; SameSite=Lax`;\n}\n\nfunction clearConsentCookie(): void {\n if (!hasBrowserCookies()) return;\n // biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API not universally available\n document.cookie = `${CONSENT_COOKIE_NAME}=; Max-Age=0; Path=/; SameSite=Lax`;\n}\n\nexport function deriveOverallConsentState(state: ConsentCategoryState): AnalyticsConsentState {\n let hasUnknown = false;\n for (const category of CONSENT_CATEGORIES) {\n if (state[category] === \"denied\") return \"denied\";\n if (state[category] === \"unknown\") hasUnknown = true;\n }\n return hasUnknown ? \"unknown\" : \"granted\";\n}\n\n/**\n * Checks whether all required consent categories for a provider are granted.\n */\nexport function providerConsentGranted(provider: TrackingProvider, state: ConsentCategoryState): boolean {\n if (!(provider in TRACKING_PROVIDER_REQUIRED_CONSENT)) return true;\n const required = getTrackingProviderRequiredConsent(provider);\n return required.every((category) => state[category] === \"granted\");\n}\n\n/**\n * Checks whether any required consent category for a provider is denied.\n */\nexport function providerConsentDenied(provider: TrackingProvider, state: ConsentCategoryState): boolean {\n if (!(provider in TRACKING_PROVIDER_REQUIRED_CONSENT)) return false;\n const required = getTrackingProviderRequiredConsent(provider);\n return required.some((category) => state[category] === \"denied\");\n}\n\nexport interface ConsentManagerOptions {\n debug?: boolean;\n onBufferFlush?: ConsentBufferFlushCallback;\n}\n\n/**\n * Creates a consent manager that tracks per-category consent state, persists to a cookie,\n * and buffers adapter dispatch entries until consent is resolved.\n */\nexport function createConsentManager(options: ConsentManagerOptions = {}): ConsentManager {\n const debug = options.debug === true;\n let state: ConsentCategoryState = readConsentCookie() ?? defaultCategoryState();\n const listeners: Set<ConsentChangeCallback> = new Set();\n const buffer: ConsentBufferEntry[] = [];\n\n function debugLog(message: string, data?: unknown): void {\n if (!debug) return;\n // biome-ignore lint/suspicious/noConsole: debug logging\n if (data !== undefined) console.debug(`[ekomerc:consent] ${message}`, data);\n // biome-ignore lint/suspicious/noConsole: debug logging\n else console.debug(`[ekomerc:consent] ${message}`);\n }\n\n function notifyListeners(): void {\n const snapshot = { ...state };\n for (const listener of listeners) {\n try {\n listener(snapshot);\n } catch {\n // Listeners must not affect consent operations.\n }\n }\n }\n\n function processBuffer(): void {\n const toFlush: ConsentBufferEntry[] = [];\n const remaining: ConsentBufferEntry[] = [];\n\n for (const entry of buffer) {\n if (providerConsentGranted(entry.adapter.provider, state)) {\n toFlush.push(entry);\n debugLog(`buffer: flushing entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n } else if (providerConsentDenied(entry.adapter.provider, state)) {\n debugLog(`buffer: discarding entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n } else {\n remaining.push(entry);\n }\n }\n\n buffer.length = 0;\n buffer.push(...remaining);\n\n if (toFlush.length > 0 && options.onBufferFlush) {\n options.onBufferFlush(toFlush);\n }\n }\n\n function applyUpdate(updates: Partial<ConsentCategoryState>): void {\n let changed = false;\n for (const category of CONSENT_CATEGORIES) {\n const newValue = updates[category];\n if (newValue !== undefined && newValue !== state[category]) {\n state[category] = newValue;\n changed = true;\n }\n }\n\n if (!changed) return;\n\n debugLog(\"state changed\", { ...state });\n writeConsentCookie(state);\n notifyListeners();\n processBuffer();\n }\n\n if (debug) {\n debugLog(\"initialized\", { ...state, source: readConsentCookie() ? \"cookie\" : \"default\" });\n }\n\n return {\n getState(): AnalyticsConsentState {\n return deriveOverallConsentState(state);\n },\n\n getCategories(): ConsentCategoryState {\n return { ...state };\n },\n\n grantAll(): void {\n applyUpdate({\n analytics_storage: \"granted\",\n ad_storage: \"granted\",\n ad_user_data: \"granted\",\n ad_personalization: \"granted\",\n });\n },\n\n denyAll(): void {\n applyUpdate({\n analytics_storage: \"denied\",\n ad_storage: \"denied\",\n ad_user_data: \"denied\",\n ad_personalization: \"denied\",\n });\n },\n\n grant(categories: ConsentCategory[]): void {\n const updates: Partial<ConsentCategoryState> = {};\n for (const category of categories) {\n updates[category] = \"granted\";\n }\n applyUpdate(updates);\n },\n\n deny(categories: ConsentCategory[]): void {\n const updates: Partial<ConsentCategoryState> = {};\n for (const category of categories) {\n updates[category] = \"denied\";\n }\n applyUpdate(updates);\n },\n\n update(updates: Partial<ConsentCategoryState>): void {\n applyUpdate(updates);\n },\n\n reset(): void {\n state = defaultCategoryState();\n debugLog(\"reset to unknown\");\n clearConsentCookie();\n notifyListeners();\n // On reset, all buffered entries stay buffered (unknown state).\n },\n\n onChange(callback: ConsentChangeCallback): () => void {\n listeners.add(callback);\n return () => {\n listeners.delete(callback);\n };\n },\n\n resolveConsentState(): AnalyticsConsentState {\n return deriveOverallConsentState(state);\n },\n\n shouldBuffer(provider: TrackingProvider): boolean {\n return !providerConsentGranted(provider, state) && !providerConsentDenied(provider, state);\n },\n\n shouldDispatch(provider: TrackingProvider): boolean {\n return providerConsentGranted(provider, state);\n },\n\n shouldDiscard(provider: TrackingProvider): boolean {\n return providerConsentDenied(provider, state);\n },\n\n bufferDispatch(entry: ConsentBufferEntry): void {\n if (buffer.length >= CONSENT_BUFFER_MAX) {\n buffer.shift();\n debugLog(\"buffer: evicted oldest entry (cap reached)\");\n }\n buffer.push(entry);\n debugLog(`buffer: added entry for ${entry.adapter.provider}`, entry.input.event.eventType);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NotFoundError, type StorefrontError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type { PageInfo, PaginatedResult, StorefrontClientContext } from \"./types.ts\";\n\n/** Published TipTap content with safe HTML and plain text for alternate renderers. */\nexport interface RichText {\n html: string;\n json: unknown;\n text: string;\n}\n/** Optional merchant-authored metadata; callers choose their own defaults for missing values. */\nexport interface Seo {\n title: string | null;\n description: string | null;\n}\n/** A currently published page; drafts, scheduled pages and deleted pages are excluded. */\nexport interface Page {\n id: string;\n handle: string;\n title: string;\n content: RichText;\n seo: Seo;\n publishedAt: string;\n updatedAt: string;\n}\n/** A published legal-policy slot containing the extracted TipTap body. */\nexport interface Policy {\n id: string;\n slot: string;\n title: string;\n content: RichText;\n seo: Seo;\n updatedAt: string;\n}\n/** Resolved destination; resource handles reflect current publication and unavailable targets are omitted. */\nexport type MenuLinkTarget =\n | {\n kind: \"SYSTEM\";\n handle: null;\n systemRoute: \"HOME\" | \"CATALOG\" | \"COLLECTIONS\" | \"CART\" | \"CHECKOUT\";\n externalUrl: null;\n }\n | { kind: \"URL\"; handle: null; systemRoute: null; externalUrl: string }\n | {\n kind: \"PAGE\" | \"PRODUCT\" | \"COLLECTION\" | \"CATEGORY\" | \"POLICY\";\n handle: string;\n systemRoute: null;\n externalUrl: null;\n };\n/** Ordered menu entry with up to three levels of nested entries. */\nexport interface MenuItem {\n id: string;\n label: string;\n openInNewTab: boolean;\n target: MenuLinkTarget;\n items: MenuItem[];\n}\n/** A merchant menu with unavailable resource destinations filtered out. */\nexport interface Menu {\n id: string;\n handle: string;\n title: string;\n items: MenuItem[];\n}\n/** Cursor page request, capped at fifty results by the API. */\nexport interface PagesListOptions {\n first?: number;\n after?: string;\n}\n/** Read published pages; listAll crawls sequentially with bounded retries for throttling. */\nexport interface PagesOperations {\n get(handle: string): Promise<Result<Page, StorefrontError>>;\n list(options?: PagesListOptions): Promise<Result<PaginatedResult<Page>, StorefrontError>>;\n listAll(): Promise<Result<Page[], StorefrontError>>;\n}\n/** Read published legal policies in the platform’s stable slot order. */\nexport interface PoliciesOperations {\n get(slot: string): Promise<Result<Policy, StorefrontError>>;\n list(): Promise<Result<Policy[], StorefrontError>>;\n}\n/** Read a menu by handle with resolved, currently available destinations. */\nexport interface MenusOperations {\n get(handle: string): Promise<Result<Menu, StorefrontError>>;\n}\nconst CONTENT_FIELDS = `id title content { html json text } seo { title description } updatedAt`;\nconst PAGE_FIELDS = `${CONTENT_FIELDS} handle publishedAt`;\nconst PAGE_QUERY = `query Page($handle: String!) { page(handle: $handle) { ${PAGE_FIELDS} } }`;\nconst PAGES_QUERY = `query Pages($first: Int, $after: String) { pages(first: $first, after: $after) {\n edges { node { ${PAGE_FIELDS} } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor }\n} }`;\nconst POLICY_QUERY = `query Policy($slot: String!) { policy(slot: $slot) { ${CONTENT_FIELDS} slot } }`;\nconst POLICIES_QUERY = `query Policies { policies { ${CONTENT_FIELDS} slot } }`;\nconst MENU_ITEM_FIELDS = `id label openInNewTab target { kind handle systemRoute externalUrl }`;\nconst MENU_QUERY = `query Menu($handle: String!) { menu(handle: $handle) { id handle title\n items { ${MENU_ITEM_FIELDS} items { ${MENU_ITEM_FIELDS} items { ${MENU_ITEM_FIELDS} } } }\n} }`;\n\nexport function createPagesOperations(client: StorefrontClientContext): PagesOperations {\n const pages: PagesOperations = {\n async get(handle) {\n const result = await client.query<{ page: Page | null }>({ query: PAGE_QUERY, variables: { handle } });\n if (result.isErr()) return err(result.error);\n return result.value.page ? ok(result.value.page) : err(new NotFoundError(`Page not found: ${handle}`));\n },\n async list(options = {}) {\n const result = await client.query<{ pages: { edges: Array<{ node: Page }>; pageInfo: PageInfo } }>({\n query: PAGES_QUERY,\n variables: { ...options },\n });\n if (result.isErr()) return err(result.error);\n return ok({ items: result.value.pages.edges.map((edge) => edge.node), pageInfo: result.value.pages.pageInfo });\n },\n listAll: () => collectAllPages((options) => pages.list(options), 50),\n };\n return pages;\n}\nexport function createPoliciesOperations(client: StorefrontClientContext): PoliciesOperations {\n return {\n async get(slot) {\n const result = await client.query<{ policy: Policy | null }>({ query: POLICY_QUERY, variables: { slot } });\n if (result.isErr()) return err(result.error);\n return result.value.policy ? ok(result.value.policy) : err(new NotFoundError(`Policy not found: ${slot}`));\n },\n async list() {\n const result = await client.query<{ policies: Policy[] }>({ query: POLICIES_QUERY });\n return result.map((value) => value.policies);\n },\n };\n}\nexport function createMenusOperations(client: StorefrontClientContext): MenusOperations {\n return {\n async get(handle) {\n const result = await client.query<{ menu: Menu | null }>({ query: MENU_QUERY, variables: { handle } });\n if (result.isErr()) return err(result.error);\n return result.value.menu ? ok(result.value.menu) : err(new NotFoundError(`Menu not found: ${handle}`));\n },\n };\n}\n","export function getWindowObject(getWindow: (() => object | null) | undefined): object | null {\n if (getWindow) {\n return getWindow();\n }\n\n if (typeof window === \"undefined\") {\n return null;\n }\n\n return window;\n}\n\nexport function getNumberPropFromKeys(properties: Record<string, unknown>, keys: string[]): number | null {\n for (const key of keys) {\n const value = properties[key];\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n\n return null;\n}\n","import type { TrackingProvider } from \"@ekomerc/tracking-policy\";\nimport { getWindowObject } from \"./browser-helpers.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsBrowserAdapter,\n} from \"./tracking-runtime.ts\";\n\nconst DEBUG_DATA_LAYER_NAME = \"ekomercDebugDataLayer\";\n\ninterface DebugDataLayerEntry {\n timestamp: string;\n eventType: string;\n eventId: string;\n sessionId: string;\n visitorId: string;\n path: string;\n consentState: string;\n properties: Record<string, unknown>;\n}\n\ninterface DebugBrowserAdapterOptions {\n getWindow?: () => object | null;\n}\n\nfunction isLocalhost(): boolean {\n if (typeof window === \"undefined\") return false;\n const { hostname } = window.location;\n return hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n}\n\n/**\n * Creates a debug browser adapter that appends all analytics events to\n * `window.ekomercDebugDataLayer`. Only activates on localhost.\n */\nexport function createDebugBrowserAdapter(options: DebugBrowserAdapterOptions = {}): AnalyticsBrowserAdapter | null {\n if (!isLocalhost()) return null;\n\n return {\n provider: \"debug\" as TrackingProvider,\n dispatch(input: AnalyticsAdapterDispatchInput): AnalyticsAdapterOperationResult {\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n return { status: \"skipped\", reason: \"runtime_unavailable\" };\n }\n\n let dataLayer = Reflect.get(windowObject, DEBUG_DATA_LAYER_NAME) as DebugDataLayerEntry[] | undefined;\n if (!Array.isArray(dataLayer)) {\n dataLayer = [];\n Reflect.set(windowObject, DEBUG_DATA_LAYER_NAME, dataLayer);\n }\n\n const entry: DebugDataLayerEntry = {\n timestamp: input.event.occurredAt,\n eventType: input.event.eventType,\n eventId: input.event.eventId,\n sessionId: input.event.sessionId,\n visitorId: input.event.visitorId,\n path: input.event.context.path,\n consentState: input.event.consentState,\n properties: input.event.properties,\n };\n\n dataLayer.push(entry);\n\n // biome-ignore lint/suspicious/noConsole: dev-only debug adapter\n console.debug(\"[ekomerc:debug]\", entry.eventType, entry);\n\n return { status: \"success\" };\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { QueryCache } from \"./cache.ts\";\nimport {\n AuthError,\n GraphQLError,\n NetworkError,\n NotFoundError,\n RateLimitError,\n type StorefrontError,\n ValidationError,\n} from \"./errors.ts\";\n\nexport interface GraphQLRequest {\n query: string;\n variables?: Record<string, unknown>;\n operationName?: string;\n}\n\nexport interface GraphQLResponse<T = unknown> {\n data?: T;\n errors?: Array<{ message: string; path?: readonly (string | number)[] }>;\n}\n\nexport interface GraphQLClientConfig {\n endpoint: string;\n apiKey: string;\n getCartToken: () => string | null;\n getCustomerToken: () => string | null;\n getMarketSlug: () => string | null;\n cache: QueryCache;\n cacheTTL: number;\n}\n\nexport interface GraphQLClient {\n query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>>;\n mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>>;\n}\n\nfunction mapHttpError(status: number, body: string): StorefrontError {\n if (status === 401 || status === 403) {\n let message = \"Authentication failed\";\n try {\n const parsed = JSON.parse(body) as { error?: string; message?: string };\n message = parsed.error ?? parsed.message ?? message;\n } catch {\n // Use default message\n }\n return new AuthError(message);\n }\n\n if (status === 404) {\n return new NotFoundError(\"Resource not found\");\n }\n\n return new GraphQLError(`HTTP error ${status}`, [{ message: body }]);\n}\n\nfunction mapGraphQLErrors(errors: Array<{ message: string; path?: readonly (string | number)[] }>): StorefrontError {\n const messages = errors.map((e) => e.message).join(\"; \");\n return new GraphQLError(messages, errors);\n}\n\nfunction getCacheKey(request: GraphQLRequest): string {\n return JSON.stringify({\n query: request.query,\n variables: request.variables ?? {},\n operationName: request.operationName,\n });\n}\n\nexport function createGraphQLClient(config: GraphQLClientConfig): GraphQLClient {\n async function execute<T>(\n request: GraphQLRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Result<GraphQLResponse<T>, StorefrontError>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"x-storefront-key\": config.apiKey,\n };\n\n const cartToken = config.getCartToken();\n if (cartToken) {\n headers[\"x-cart-token\"] = cartToken;\n }\n\n const customerToken = config.getCustomerToken();\n if (customerToken) {\n headers.Authorization = `Bearer ${customerToken}`;\n }\n\n const marketSlug = config.getMarketSlug();\n if (marketSlug) {\n headers[\"x-market-slug\"] = marketSlug;\n }\n\n let response: Response;\n try {\n response = await fetch(config.endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n query: request.query,\n variables: request.variables,\n operationName: request.operationName,\n }),\n signal: options?.signal,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Network request failed\";\n return err(new NetworkError(message, { cause: error instanceof Error ? error : undefined }));\n }\n\n if (!response.ok) {\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const milliseconds =\n retryAfter && /^\\d+$/.test(retryAfter)\n ? Number(retryAfter) * 1000\n : Date.parse(retryAfter ?? \"\") - Date.now();\n return err(new RateLimitError(Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : 1000));\n }\n const body = await response.text().catch(() => \"\");\n return err(mapHttpError(response.status, body));\n }\n\n let json: GraphQLResponse<T>;\n try {\n json = (await response.json()) as GraphQLResponse<T>;\n } catch {\n return err(new GraphQLError(\"Invalid JSON response\", [{ message: \"Failed to parse response\" }]));\n }\n\n return ok(json);\n }\n\n return {\n async query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>> {\n const useCache = options?.cache !== false;\n const cacheKey = getCacheKey(request);\n\n if (useCache) {\n const cached = config.cache.get<T>(cacheKey);\n if (cached !== null) {\n return ok(cached);\n }\n }\n\n const result = await execute<T>(request, options);\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const response = result.value;\n\n if (response.errors && response.errors.length > 0) {\n return err(mapGraphQLErrors(response.errors));\n }\n\n if (!response.data) {\n return err(new GraphQLError(\"No data in response\", [{ message: \"Response has no data\" }]));\n }\n\n if (useCache) {\n config.cache.set(cacheKey, response.data, config.cacheTTL);\n }\n\n return ok(response.data);\n },\n\n async mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>> {\n const result = await execute<T>(request, options);\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const response = result.value;\n\n if (response.errors && response.errors.length > 0) {\n return err(mapGraphQLErrors(response.errors));\n }\n\n if (!response.data) {\n return err(new GraphQLError(\"No data in response\", [{ message: \"Response has no data\" }]));\n }\n\n return ok(response.data);\n },\n };\n}\n\n/**\n * Extract userErrors from mutation result and convert to ValidationError if present\n */\nexport function extractUserErrors<\n T extends { userErrors?: Array<{ field: string | null; message: string; code?: string | null }> },\n>(data: T, fieldName: keyof T): Result<Exclude<T[keyof T], undefined>, ValidationError> {\n const payload = data[fieldName];\n if (!payload || typeof payload !== \"object\") {\n return err(new ValidationError(\"Unexpected response format\", []));\n }\n\n const typedPayload = payload as {\n userErrors?: Array<{ field: string | null; message: string; code?: string | null }>;\n data?: unknown;\n };\n\n if (typedPayload.userErrors && typedPayload.userErrors.length > 0) {\n const messages = typedPayload.userErrors.map((e) => e.message).join(\"; \");\n return err(new ValidationError(messages, typedPayload.userErrors));\n }\n\n return ok(payload as Exclude<T[keyof T], undefined>);\n}\n","import {\n GTM_STANDARD_EVENTS,\n type GtmStandardEventName,\n getTrackingProviderDedupeConvention,\n getTrackingProviderEventName,\n getTrackingProviderSupportRule,\n} from \"@ekomerc/tracking-policy\";\nimport { getNumberPropFromKeys, getWindowObject } from \"./browser-helpers.ts\";\nimport type { ConsentCategoryState } from \"./consent.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsBrowserAdapter,\n AnalyticsConsentState,\n AnalyticsConsentUpdate,\n AnalyticsProperties,\n} from \"./tracking-runtime.ts\";\nimport { INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY } from \"./tracking-runtime.ts\";\nimport type { GtmBrowserTrackingConfig } from \"./types.ts\";\n\nconst DEFAULT_DATA_LAYER_NAME = \"dataLayer\";\nconst GTM_CONSENT_DEFAULT_STATE: GtmConsentModeUpdate = {\n analytics_storage: \"denied\",\n ad_storage: \"denied\",\n ad_user_data: \"denied\",\n ad_personalization: \"denied\",\n};\n\nexport type GtmConsentCommand = [\"consent\", \"default\" | \"update\", GtmConsentModeUpdate];\ntype GtmPushEntry = GtmConsentCommand | GtmDataLayerEvent;\n\ninterface GtmDataLayer {\n push(entry: GtmPushEntry): number;\n}\n\n/**\n * Namespaced GTM event names emitted by the storefront adapter.\n */\nexport type GtmNamespacedEventName = `ekomerc.${GtmStandardEventName}`;\n\nconst GTM_TRIGGER_EVENT_MAP = Object.fromEntries(\n GTM_STANDARD_EVENTS.map((name) => [name, `ekomerc.${name}` as const]),\n) as { readonly [K in GtmStandardEventName]: `ekomerc.${K}` };\n\n/**\n * GTM ecommerce item payload derived from storefront analytics properties.\n */\nexport interface GtmItem {\n item_id: string;\n item_name?: string;\n item_variant?: string | null;\n price?: number;\n item_list_id?: string;\n item_list_name?: string;\n index?: number;\n item_category?: string;\n product_id?: string;\n variant_id?: string;\n sku?: string | null;\n quantity: number;\n unit_price?: number;\n line_total?: number;\n currency?: string;\n}\n\n/**\n * GTM attribution payload copied from captured UTM and click ID data.\n */\nexport interface GtmAttributionPayload {\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_term: string | null;\n utm_content: string | null;\n gclid: string | null;\n gbraid: string | null;\n wbraid: string | null;\n fbclid: string | null;\n ttclid: string | null;\n}\n\n/**\n * GTM page context payload copied from the storefront analytics event.\n */\nexport interface GtmContextPayload {\n path: string;\n referrer: string | null;\n}\n\n/**\n * GTM `ekomerc` payload pushed alongside each `dataLayer` event.\n */\nexport interface GtmEcommercePayload {\n event_name: GtmNamespacedEventName;\n event_id: string;\n consent_state: AnalyticsConsentState;\n context: GtmContextPayload;\n attribution: GtmAttributionPayload;\n ga4_campaign_override_active?: boolean;\n lead_type?: string;\n lead_source?: string;\n placement?: string;\n currency?: string;\n value?: number;\n order_id?: string;\n cart_id?: string;\n quantity?: number;\n items_count?: number;\n search_term?: string;\n results_count?: number;\n items?: GtmItem[];\n}\n\n/**\n * Full object pushed to the configured GTM data layer.\n */\nexport interface GtmDataLayerEvent {\n event: GtmNamespacedEventName;\n ekomerc: GtmEcommercePayload;\n}\n\n/**\n * GTM consent-mode update payload derived from storefront consent state.\n */\nexport interface GtmConsentModeUpdate {\n analytics_storage: \"granted\" | \"denied\";\n ad_storage: \"granted\" | \"denied\";\n ad_user_data: \"granted\" | \"denied\";\n ad_personalization: \"granted\" | \"denied\";\n}\n\n/**\n * Optional runtime overrides for the GTM browser adapter.\n */\nexport interface GtmBrowserAdapterOptions {\n dataLayerName?: string;\n getWindow?: () => object | null;\n debug?: boolean;\n initialConsentState?: ConsentCategoryState;\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isGtmDataLayer(value: unknown): value is GtmDataLayer {\n return isObjectRecord(value) && typeof value.push === \"function\";\n}\n\nfunction getStringProp(properties: Record<string, unknown>, key: string): string | null {\n const value = properties[key];\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction getNumberProp(properties: Record<string, unknown>, key: string): number | null {\n const value = properties[key];\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction getAmountValue(properties: Record<string, unknown>, keys: string[]): number | null {\n return getNumberPropFromKeys(properties, keys);\n}\n\nfunction normalizeQuantity(value: number | null): number {\n if (value === null) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction resolveItemId(properties: Record<string, unknown>): string | null {\n return (\n getStringProp(properties, \"itemId\") ??\n getStringProp(properties, \"item_id\") ??\n getStringProp(properties, \"contentId\") ??\n getStringProp(properties, \"content_id\") ??\n getStringProp(properties, \"variantId\") ??\n getStringProp(properties, \"variant_id\") ??\n getStringProp(properties, \"sku\") ??\n getStringProp(properties, \"productId\") ??\n getStringProp(properties, \"product_id\") ??\n getStringProp(properties, \"id\")\n );\n}\n\nfunction resolveProductId(properties: Record<string, unknown>): string | null {\n return (\n getStringProp(properties, \"productId\") ?? getStringProp(properties, \"product_id\") ?? getStringProp(properties, \"id\")\n );\n}\n\nfunction buildItem(properties: Record<string, unknown>, currency: string): GtmItem | null {\n const itemId = resolveItemId(properties);\n if (!itemId) {\n return null;\n }\n\n const quantity = normalizeQuantity(getNumberProp(properties, \"quantity\"));\n const unitPrice = getAmountValue(properties, [\"unitPrice\", \"unit_price\", \"price\"]) ?? 0;\n const lineTotal = getAmountValue(properties, [\"lineTotal\", \"line_total\", \"total\"]) ?? unitPrice * quantity;\n\n const item: GtmItem = {\n item_id: itemId,\n quantity,\n };\n\n const itemName =\n getStringProp(properties, \"itemName\") ??\n getStringProp(properties, \"item_name\") ??\n getStringProp(properties, \"productTitle\");\n if (itemName) {\n item.item_name = itemName;\n }\n\n const itemVariant =\n getStringProp(properties, \"itemVariant\") ??\n getStringProp(properties, \"item_variant\") ??\n getStringProp(properties, \"variantTitle\");\n if (itemVariant || properties.itemVariant === null || properties.variantTitle === null) {\n item.item_variant = itemVariant;\n }\n\n if (unitPrice > 0) {\n item.price = unitPrice;\n item.unit_price = unitPrice;\n }\n\n if (lineTotal > 0) {\n item.line_total = lineTotal;\n }\n\n if (currency) {\n item.currency = currency;\n }\n\n const itemListId =\n getStringProp(properties, \"itemListId\") ??\n getStringProp(properties, \"item_list_id\") ??\n getStringProp(properties, \"listId\");\n if (itemListId) {\n item.item_list_id = itemListId;\n }\n\n const itemListName =\n getStringProp(properties, \"itemListName\") ??\n getStringProp(properties, \"item_list_name\") ??\n getStringProp(properties, \"listName\");\n if (itemListName) {\n item.item_list_name = itemListName;\n }\n\n const index = getNumberProp(properties, \"index\");\n if (index !== null) {\n item.index = Math.max(0, Math.floor(index));\n }\n\n const itemCategory = getStringProp(properties, \"itemCategory\") ?? getStringProp(properties, \"item_category\");\n if (itemCategory) {\n item.item_category = itemCategory;\n }\n\n const productId = resolveProductId(properties);\n if (productId) {\n item.product_id = productId;\n }\n\n const variantId = getStringProp(properties, \"variantId\") ?? getStringProp(properties, \"variant_id\");\n if (variantId) {\n item.variant_id = variantId;\n }\n\n const sku = getStringProp(properties, \"sku\");\n if (sku || properties.sku === null) {\n item.sku = sku;\n }\n\n return item;\n}\n\nfunction buildNormalizedItems(\n eventName: GtmStandardEventName,\n properties: AnalyticsProperties,\n currency: string,\n): GtmItem[] {\n const rawLineItems = properties.lineItems;\n if (Array.isArray(rawLineItems)) {\n const items: GtmItem[] = [];\n for (const lineItem of rawLineItems) {\n if (!isObjectRecord(lineItem)) {\n continue;\n }\n\n const mappedItem = buildItem(lineItem, currency);\n if (mappedItem) {\n items.push(mappedItem);\n }\n }\n\n if (items.length > 0) {\n return items;\n }\n }\n\n if (\n eventName === \"view_item\" ||\n eventName === \"select_item\" ||\n eventName === \"add_to_cart\" ||\n eventName === \"remove_from_cart\" ||\n eventName === \"view_cart\" ||\n eventName === \"begin_checkout\" ||\n eventName === \"purchase\"\n ) {\n const singleItem = buildItem(properties, currency);\n return singleItem ? [singleItem] : [];\n }\n\n return [];\n}\n\nfunction sumItemValue(items: GtmItem[]): number | null {\n if (items.length === 0) {\n return null;\n }\n\n let total = 0;\n let hasPricedItem = false;\n\n for (const item of items) {\n if (typeof item.line_total === \"number\" && Number.isFinite(item.line_total)) {\n total += item.line_total;\n hasPricedItem = true;\n } else if (typeof item.price === \"number\" && Number.isFinite(item.price)) {\n total += item.price * item.quantity;\n hasPricedItem = true;\n } else if (typeof item.unit_price === \"number\" && Number.isFinite(item.unit_price)) {\n total += item.unit_price * item.quantity;\n hasPricedItem = true;\n }\n }\n\n if (!hasPricedItem) {\n return null;\n }\n\n return Number.isFinite(total) ? total : null;\n}\n\nfunction buildAttributionPayload(input: AnalyticsAdapterDispatchInput): GtmAttributionPayload {\n return {\n utm_source: input.event.utm.source,\n utm_medium: input.event.utm.medium,\n utm_campaign: input.event.utm.campaign,\n utm_term: input.event.utm.term,\n utm_content: input.event.utm.content,\n gclid: input.event.clickIds.gclid,\n gbraid: input.event.clickIds.gbraid,\n wbraid: input.event.clickIds.wbraid,\n fbclid: input.event.clickIds.fbclid,\n ttclid: input.event.clickIds.ttclid,\n };\n}\n\nconst CHECKOUT_STEP_GTM_EVENT_MAP: Record<string, GtmNamespacedEventName | null> = {\n shipping: \"ekomerc.add_shipping_info\",\n payment: \"ekomerc.add_payment_info\",\n};\n\nfunction assignEcommerceFields(\n ekomerc: GtmEcommercePayload,\n properties: AnalyticsProperties,\n providerEventName: GtmStandardEventName,\n): void {\n const currency = getStringProp(properties, \"currency\") ?? \"\";\n const items = buildNormalizedItems(providerEventName, properties, currency);\n const itemValue = sumItemValue(items);\n const fallbackValue = getAmountValue(properties, [\"value\", \"total\", \"orderTotal\", \"cartValue\"]);\n const value = itemValue ?? fallbackValue;\n const quantity = getNumberProp(properties, \"quantity\");\n const itemsCount = getNumberPropFromKeys(properties, [\"itemsCount\", \"numItems\"]);\n\n if (currency) {\n ekomerc.currency = currency;\n }\n\n if (value !== null) {\n ekomerc.value = value;\n }\n\n const cartId = getStringProp(properties, \"cartId\");\n if (cartId) {\n ekomerc.cart_id = cartId;\n }\n\n const orderId = getStringProp(properties, \"orderId\");\n if (orderId) {\n ekomerc.order_id = orderId;\n }\n\n if (quantity !== null) {\n ekomerc.quantity = quantity;\n }\n\n if (itemsCount !== null) {\n ekomerc.items_count = itemsCount;\n } else if (items.length > 0) {\n ekomerc.items_count = items.reduce((sum, item) => sum + item.quantity, 0);\n }\n\n if (items.length > 0) {\n ekomerc.items = items;\n }\n}\n\nfunction assignLeadFields(ekomerc: GtmEcommercePayload, properties: AnalyticsProperties): void {\n const leadType = getStringProp(properties, \"leadType\") ?? getStringProp(properties, \"lead_type\");\n const leadSource = getStringProp(properties, \"source\") ?? getStringProp(properties, \"leadSource\");\n const placement = getStringProp(properties, \"placement\");\n const currency = getStringProp(properties, \"currency\") ?? \"\";\n const value = getAmountValue(properties, [\"value\"]);\n\n if (leadType) {\n ekomerc.lead_type = leadType;\n }\n if (leadSource) {\n ekomerc.lead_source = leadSource;\n }\n if (placement) {\n ekomerc.placement = placement;\n }\n if (currency) {\n ekomerc.currency = currency;\n }\n if (value !== null) {\n ekomerc.value = value;\n }\n}\n\nfunction buildCheckoutStepDataLayerEvent(input: AnalyticsAdapterDispatchInput): GtmDataLayerEvent | null {\n const step = getStringProp(input.event.properties, \"step\");\n const eventName = step ? (CHECKOUT_STEP_GTM_EVENT_MAP[step] ?? null) : null;\n if (!eventName) {\n return null;\n }\n\n const dedupe = getTrackingProviderDedupeConvention(\"gtm\");\n\n const ekomerc: GtmEcommercePayload = {\n event_name: eventName,\n event_id: input.event[dedupe.canonicalEventIdField],\n consent_state: input.event.consentState,\n context: {\n path: input.event.context.path,\n referrer: input.event.referrer,\n },\n attribution: buildAttributionPayload(input),\n };\n assignEcommerceFields(ekomerc, input.event.properties, eventName.replace(\"ekomerc.\", \"\") as GtmStandardEventName);\n\n return { event: eventName, ekomerc };\n}\n\n/**\n * Maps a storefront analytics event to a GTM `dataLayer.push()` payload.\n */\nexport function buildGtmDataLayerEvent(input: AnalyticsAdapterDispatchInput): GtmDataLayerEvent | null {\n if (input.event.eventType === \"analytics.checkout_step_completed\") {\n return buildCheckoutStepDataLayerEvent(input);\n }\n\n const providerEventName = getTrackingProviderEventName(\"gtm\", input.event.eventType);\n if (providerEventName === null) {\n return null;\n }\n\n const eventName = GTM_TRIGGER_EVENT_MAP[providerEventName];\n const dedupe = getTrackingProviderDedupeConvention(\"gtm\");\n\n const ekomerc: GtmEcommercePayload = {\n event_name: eventName,\n event_id: input.event[dedupe.canonicalEventIdField],\n consent_state: input.event.consentState,\n context: {\n path: input.event.context.path,\n referrer: input.event.referrer,\n },\n attribution: buildAttributionPayload(input),\n };\n\n if (\n providerEventName === \"page_view\" &&\n input.event.properties[INTERNAL_GA4_CAMPAIGN_OVERRIDE_ACTIVE_PROPERTY] === true\n ) {\n ekomerc.ga4_campaign_override_active = true;\n }\n\n if (providerEventName === \"search\") {\n const query = getStringProp(input.event.properties, \"query\");\n if (query) {\n ekomerc.search_term = query;\n }\n\n const resultsCount = getNumberProp(input.event.properties, \"resultsCount\");\n if (resultsCount !== null) {\n ekomerc.results_count = resultsCount;\n }\n }\n\n if (providerEventName === \"generate_lead\") {\n assignLeadFields(ekomerc, input.event.properties);\n } else if (providerEventName !== \"page_view\" && providerEventName !== \"search\") {\n assignEcommerceFields(ekomerc, input.event.properties, providerEventName);\n }\n\n return {\n event: eventName,\n ekomerc,\n };\n}\n\n/**\n * Converts storefront consent state into a GTM consent-mode update payload.\n * Accepts either an `AnalyticsConsentUpdate` (overall state) or a per-category `ConsentCategoryState`.\n */\nexport function buildGtmConsentModeUpdate(input: AnalyticsConsentUpdate | ConsentCategoryState): GtmConsentModeUpdate {\n if (\"consentState\" in input) {\n const consentValue = input.consentState === \"granted\" ? \"granted\" : \"denied\";\n return {\n analytics_storage: consentValue,\n ad_storage: consentValue,\n ad_user_data: consentValue,\n ad_personalization: consentValue,\n };\n }\n\n return {\n analytics_storage: input.analytics_storage === \"granted\" ? \"granted\" : \"denied\",\n ad_storage: input.ad_storage === \"granted\" ? \"granted\" : \"denied\",\n ad_user_data: input.ad_user_data === \"granted\" ? \"granted\" : \"denied\",\n ad_personalization: input.ad_personalization === \"granted\" ? \"granted\" : \"denied\",\n };\n}\n\nfunction getDataLayer(windowObject: object, dataLayerName: string): GtmDataLayer | null {\n const dataLayer = Reflect.get(windowObject, dataLayerName);\n if (isGtmDataLayer(dataLayer)) {\n return dataLayer;\n }\n\n if (dataLayer !== undefined && dataLayer !== null) {\n return null;\n }\n\n const initializedDataLayer: GtmPushEntry[] = [];\n if (!Reflect.set(windowObject, dataLayerName, initializedDataLayer)) {\n return null;\n }\n\n return initializedDataLayer;\n}\n\nfunction pushConsentCommand(\n windowObject: object,\n dataLayer: GtmDataLayer,\n mode: \"default\" | \"update\",\n consentUpdate: GtmConsentModeUpdate,\n): void {\n const gtag = Reflect.get(windowObject, \"gtag\");\n if (typeof gtag === \"function\") {\n gtag(\"consent\", mode, consentUpdate);\n return;\n }\n\n dataLayer.push([\"consent\", mode, consentUpdate]);\n}\n\nfunction runtimeUnavailable(): AnalyticsAdapterOperationResult {\n return {\n status: \"skipped\",\n reason: \"runtime_unavailable\",\n };\n}\n\n/**\n * Creates a GTM browser adapter that pushes storefront analytics events into `window.dataLayer`.\n */\nexport function createGtmBrowserAdapter(\n config: GtmBrowserTrackingConfig,\n options: GtmBrowserAdapterOptions = {},\n): AnalyticsBrowserAdapter | null {\n const supportRule = getTrackingProviderSupportRule(\"gtm\");\n const debug = options.debug === true;\n\n if (!supportRule.supportsBrowserDispatch || !config.enabled || !config.containerId) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM adapter not created:\", {\n supportsBrowserDispatch: supportRule.supportsBrowserDispatch,\n enabled: config.enabled,\n containerId: config.containerId ?? null,\n });\n }\n return null;\n }\n\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM adapter created:\", {\n containerId: config.containerId,\n dataLayerName: options.dataLayerName ?? DEFAULT_DATA_LAYER_NAME,\n });\n }\n\n const dataLayerName = options.dataLayerName ?? DEFAULT_DATA_LAYER_NAME;\n let consentDefaultsApplied = false;\n\n function applyConsentDefaults(windowObject: object, dataLayer: GtmDataLayer): void {\n if (consentDefaultsApplied) {\n return;\n }\n\n const defaultState = options.initialConsentState\n ? buildGtmConsentModeUpdate(options.initialConsentState)\n : GTM_CONSENT_DEFAULT_STATE;\n pushConsentCommand(windowObject, dataLayer, \"default\", defaultState);\n consentDefaultsApplied = true;\n }\n\n return {\n provider: \"gtm\",\n dispatch(input) {\n const payload = buildGtmDataLayerEvent(input);\n if (payload === null) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: no payload for event\", input.event.eventType);\n }\n return {\n status: \"success\",\n };\n }\n\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: window unavailable\");\n }\n return runtimeUnavailable();\n }\n\n const dataLayer = getDataLayer(windowObject, dataLayerName);\n if (!dataLayer) {\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dispatch: dataLayer unavailable\");\n }\n return runtimeUnavailable();\n }\n\n applyConsentDefaults(windowObject, dataLayer);\n dataLayer.push(payload);\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM dataLayer.push:\", payload);\n }\n return {\n status: \"success\",\n };\n },\n updateConsent(input) {\n if (!supportRule.requiresConsentBridge) {\n return {\n status: \"success\",\n };\n }\n\n const windowObject = getWindowObject(options.getWindow);\n if (!windowObject) {\n return runtimeUnavailable();\n }\n\n const dataLayer = getDataLayer(windowObject, dataLayerName);\n if (!dataLayer) {\n return runtimeUnavailable();\n }\n\n applyConsentDefaults(windowObject, dataLayer);\n const consentUpdate = buildGtmConsentModeUpdate(input);\n pushConsentCommand(windowObject, dataLayer, \"update\", consentUpdate);\n if (debug) {\n // biome-ignore lint/suspicious/noConsole: debug logging\n console.debug(\"[ekomerc:analytics] GTM consent update:\", consentUpdate);\n }\n return {\n status: \"success\",\n };\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport type { StorageAdapter, StorefrontClientContext } from \"./types.ts\";\n\n// GQL queries/mutations\n\nconst SIGNUP_OFFER_QUERY = `\nquery SignupOffer {\n signupOffer {\n id\n enabled\n headline\n body\n submitLabel\n successTitle\n successBody\n triggerDelaySeconds\n frequencyCapDays\n promotionSummary {\n promotionId\n discountType\n discountValue\n description\n }\n }\n}\n`;\n\nconst SIGNUP_OFFER_SUBSCRIBE_MUTATION = `\nmutation SignupOfferSubscribe($input: SignupOfferSubscribeInput!) {\n signupOfferSubscribe(input: $input) {\n success\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nconst BACK_IN_STOCK_SUBSCRIBE_MUTATION = `\nmutation BackInStockSubscribe($input: BackInStockSubscribeInput!) {\n backInStockSubscribe(input: $input) {\n success\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\n// Types\n\ninterface SignupOfferApiConfig {\n enabled: boolean;\n id: string;\n headline: string;\n body: string | null;\n submitLabel: string;\n successTitle: string;\n successBody: string | null;\n triggerDelaySeconds: number;\n frequencyCapDays: number;\n promotionSummary: {\n promotionId: string;\n discountType: string;\n discountValue: number;\n description: string | null;\n } | null;\n}\n\nexport interface SignupOfferConfig extends SignupOfferApiConfig {\n shouldShow: boolean;\n}\n\nexport interface SignupOfferLocalState {\n lastSeenAt: number | null;\n dismissedUntil: number | null;\n subscribed: boolean;\n}\n\nexport interface MarketingUserError {\n field: string[];\n message: string;\n code?: string;\n}\n\nexport interface BackInStockSubscribeResult {\n success: boolean;\n userErrors: MarketingUserError[];\n}\n\nexport interface MarketingOperations {\n getSignupOffer(): Promise<Result<SignupOfferConfig | null, StorefrontError>>;\n subscribeToSignupOffer(input: {\n email: string;\n pageUrl?: string;\n referrerUrl?: string;\n }): Promise<Result<{ success: boolean }, StorefrontError>>;\n backInStockSubscribe(input: {\n productId: string;\n variantId: string;\n email: string;\n }): Promise<Result<BackInStockSubscribeResult, StorefrontError>>;\n getSignupOfferState(offerId: string): SignupOfferLocalState;\n markSignupOfferSeen(input: { offerId: string; at?: number }): void;\n dismissSignupOffer(input: { offerId: string; until?: number }): void;\n clearSignupOfferState(offerId: string): void;\n}\n\n// Response types\n\ninterface SignupOfferQueryResponse {\n signupOffer: SignupOfferApiConfig | null;\n}\n\ninterface SignupOfferSubscribeResponse {\n signupOfferSubscribe: {\n success: boolean;\n userErrors: Array<{ field: string[]; message: string; code?: string }>;\n };\n}\n\ninterface BackInStockSubscribeResponse {\n backInStockSubscribe: {\n success: boolean;\n userErrors: MarketingUserError[];\n };\n}\n\n// Storage keys\n\nfunction stateKey(offerId: string): string {\n return `ekomerc:signup_offer:${offerId}:state`;\n}\n\nfunction parseState(raw: string | null): SignupOfferLocalState {\n if (!raw) return { lastSeenAt: null, dismissedUntil: null, subscribed: false };\n try {\n const parsed = JSON.parse(raw) as Partial<SignupOfferLocalState>;\n return {\n lastSeenAt: typeof parsed.lastSeenAt === \"number\" ? parsed.lastSeenAt : null,\n dismissedUntil: typeof parsed.dismissedUntil === \"number\" ? parsed.dismissedUntil : null,\n subscribed: parsed.subscribed === true,\n };\n } catch {\n return { lastSeenAt: null, dismissedUntil: null, subscribed: false };\n }\n}\n\nfunction computeShouldShow(\n client: StorefrontClientContext,\n config: SignupOfferApiConfig,\n localState: SignupOfferLocalState,\n): boolean {\n if (!config.enabled) return false;\n if (localState.subscribed) return false;\n\n if (client.getCustomerToken() !== null) return false;\n\n if (typeof window !== \"undefined\" && window.location.pathname.startsWith(\"/checkout\")) {\n return false;\n }\n\n const now = Date.now();\n\n if (localState.dismissedUntil !== null && now < localState.dismissedUntil) {\n return false;\n }\n\n if (localState.lastSeenAt !== null && config.frequencyCapDays > 0) {\n const capMs = config.frequencyCapDays * 24 * 60 * 60 * 1000;\n if (now - localState.lastSeenAt < capMs) {\n return false;\n }\n }\n\n return true;\n}\n\n// Factory\n\nexport function createMarketingOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n analyticsEmit: AnalyticsEmitFn | null = null,\n): MarketingOperations {\n let lastOfferId: string | null = null;\n\n return {\n async getSignupOffer(): Promise<Result<SignupOfferConfig | null, StorefrontError>> {\n const result = await client.query<SignupOfferQueryResponse>({ query: SIGNUP_OFFER_QUERY }, { cache: true });\n if (result.isErr()) return err(result.error);\n const offer = result.value.signupOffer;\n if (!offer) {\n lastOfferId = null;\n return ok(null);\n }\n\n lastOfferId = offer.id;\n const localState = parseState(storage.get(stateKey(offer.id)));\n return ok({\n ...offer,\n shouldShow: computeShouldShow(client, offer, localState),\n });\n },\n\n async subscribeToSignupOffer(input): Promise<Result<{ success: boolean }, StorefrontError>> {\n const result = await client.mutate<SignupOfferSubscribeResponse>({\n query: SIGNUP_OFFER_SUBSCRIBE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) return err(result.error);\n\n const subscriptionSucceeded = result.value.signupOfferSubscribe.success === true;\n\n if (subscriptionSucceeded && lastOfferId) {\n const nextState = parseState(storage.get(stateKey(lastOfferId)));\n nextState.subscribed = true;\n storage.set(stateKey(lastOfferId), JSON.stringify(nextState));\n }\n\n if (subscriptionSucceeded) {\n analyticsEmit?.(\"analytics.lead_generated\", {\n leadType: \"newsletter_signup\",\n source: \"signup_offer\",\n ...(lastOfferId ? { signupOfferId: lastOfferId } : {}),\n });\n }\n\n return ok({ success: subscriptionSucceeded });\n },\n\n async backInStockSubscribe(input): Promise<Result<BackInStockSubscribeResult, StorefrontError>> {\n const result = await client.mutate<BackInStockSubscribeResponse>({\n query: BACK_IN_STOCK_SUBSCRIBE_MUTATION,\n variables: { input },\n });\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.backInStockSubscribe;\n return ok({\n success: payload.success === true,\n userErrors: payload.userErrors ?? [],\n });\n },\n\n getSignupOfferState(offerId: string): SignupOfferLocalState {\n return parseState(storage.get(stateKey(offerId)));\n },\n\n markSignupOfferSeen(input: { offerId: string; at?: number }): void {\n const state = parseState(storage.get(stateKey(input.offerId)));\n state.lastSeenAt = input.at ?? Date.now();\n storage.set(stateKey(input.offerId), JSON.stringify(state));\n },\n\n dismissSignupOffer(input: { offerId: string; until?: number }): void {\n const state = parseState(storage.get(stateKey(input.offerId)));\n state.dismissedUntil = input.until ?? Number.MAX_SAFE_INTEGER;\n storage.set(stateKey(input.offerId), JSON.stringify(state));\n },\n\n clearSignupOfferState(offerId: string): void {\n storage.remove(stateKey(offerId));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { mapUserErrors, type UserError } from \"./cart-shared.ts\";\nimport type { CartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport type { ConsentManager } from \"./consent.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, StorefrontError as StorefrontSdkError } from \"./errors.ts\";\nimport {\n clearPaymentRecovery,\n finalizeRedirectPayment,\n isPaymentRef,\n type PaymentRecoveryRecord,\n paymentRecoveryExists,\n persistPaymentRecovery,\n readPaymentRecovery,\n resolvePaymentStoreId,\n} from \"./payment-lifecycle.ts\";\nimport type {\n AvailablePaymentMethod,\n Money,\n PaymentRedirectOutcome,\n PaymentReturnOutcome,\n PaymentReturnProgress,\n StorageAdapter,\n StorefrontClientContext,\n} from \"./types.ts\";\n\ninterface AvailablePaymentMethodData {\n method: string;\n displayName: string;\n presentation: AvailablePaymentMethod[\"presentation\"];\n additionalFee: Money;\n}\n\ninterface AvailablePaymentMethodsResponse {\n availablePaymentMethods: AvailablePaymentMethodData[];\n}\n\ninterface PaymentStatusResult {\n status: \"pending\" | \"paid\" | \"failed\";\n orderNumber: string;\n}\n\ninterface PaymentStatusResponse {\n paymentStatus: PaymentStatusResult | null;\n}\n\ntype PaymentAction =\n | { kind: \"none\"; redirectUrl: null; paymentRef: null }\n | { kind: \"redirect\"; redirectUrl: string; paymentRef: string }\n | { kind: \"redirect_pending\"; redirectUrl: null; paymentRef: string };\n\ninterface PaymentSessionCreateResponse {\n paymentSessionCreate: {\n paymentAction: PaymentAction;\n userErrors: UserError[];\n };\n}\n\nconst PAYMENT_POLL_LIMIT = 30;\nconst PAYMENT_POLL_INTERVAL_MS = 2_000;\nconst MAX_TRANSIENT_FAILURES = 4;\nconst MAX_TRANSIENT_BACKOFF_MS = 8_000;\n\nconst AVAILABLE_PAYMENT_METHODS_QUERY = `\nquery AvailablePaymentMethods {\n availablePaymentMethods {\n method\n displayName\n presentation\n additionalFee { amount currency }\n }\n}\n`;\n\nconst PAYMENT_STATUS_QUERY = `\nquery PaymentStatus($ref: ID!) {\n paymentStatus(ref: $ref) {\n status\n orderNumber\n }\n}\n`;\n\nconst PAYMENT_SESSION_CREATE_MUTATION = `\nmutation PaymentSessionCreate($ref: ID!) {\n paymentSessionCreate(ref: $ref) {\n paymentAction {\n kind\n redirectUrl\n paymentRef\n }\n userErrors {\n field\n message\n code\n }\n }\n}\n`;\n\nexport interface PaymentsOperations {\n /** Fetch payment methods currently available for checkout. */\n getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>>;\n resumeReturn(options?: {\n url?: string | URL;\n signal?: AbortSignal;\n onStateChange?: (state: PaymentReturnProgress) => void;\n }): Promise<Result<PaymentReturnOutcome, StorefrontError>>;\n retryRedirect(options?: {\n signal?: AbortSignal;\n navigate?: (url: string) => void;\n }): Promise<Result<PaymentRedirectOutcome, StorefrontError>>;\n clearReturn(): void;\n}\n\nfunction mapPaymentMethod(data: AvailablePaymentMethodData): AvailablePaymentMethod {\n return {\n method: data.method,\n displayName: data.displayName,\n presentation: data.presentation,\n additionalFee: data.additionalFee,\n };\n}\n\nfunction cancelledError(): StorefrontError {\n return new StorefrontSdkError(\"Payment return check was cancelled\", \"ABORTED\");\n}\n\nfunction waitFor(ms: number, signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted) return Promise.resolve(false);\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", abort);\n resolve(true);\n }, ms);\n function abort() {\n clearTimeout(timer);\n resolve(false);\n }\n signal?.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction resolveUrl(value?: string | URL): URL | null {\n if (value instanceof URL) return new URL(value.href);\n const fallback = typeof window !== \"undefined\" ? window.location.href : \"https://storefront.invalid/\";\n try {\n return new URL(value ?? fallback, fallback);\n } catch {\n return null;\n }\n}\n\nfunction readReturnRef(value?: string | URL): { ref: string | null; applicable: boolean } {\n const url = resolveUrl(value);\n if (!url || url.searchParams.get(\"payment\") !== \"return\") return { ref: null, applicable: false };\n const ref = url.searchParams.get(\"ref\");\n return { ref: ref && isPaymentRef(ref) ? ref : null, applicable: true };\n}\n\nfunction cleanBrowserReturnUrl(): void {\n if (typeof window === \"undefined\" || typeof window.history?.replaceState !== \"function\") return;\n const url = new URL(window.location.href);\n if (url.searchParams.get(\"payment\") !== \"return\") return;\n url.searchParams.delete(\"payment\");\n url.searchParams.delete(\"ref\");\n window.history.replaceState(window.history.state, \"\", `${url.pathname}${url.search}${url.hash}`);\n}\n\nfunction notify(callback: ((state: PaymentReturnProgress) => void) | undefined, state: PaymentReturnProgress): void {\n callback?.(state);\n}\n\nfunction updateRecovery(\n storage: StorageAdapter,\n record: PaymentRecoveryRecord | null,\n update: Partial<PaymentRecoveryRecord>,\n): Result<PaymentRecoveryRecord | null, StorefrontError> {\n if (!record) return ok(null);\n const next = { ...record, ...update };\n const result = persistPaymentRecovery(storage, next);\n return result.isErr() ? err(result.error) : ok(next);\n}\n\nfunction navigateTo(url: string, navigate?: (url: string) => void): Result<void, StorefrontError> {\n try {\n if (navigate) navigate(url);\n else if (typeof window !== \"undefined\") window.location.assign(url);\n return ok(undefined);\n } catch (cause) {\n return err(\n new StorefrontSdkError(\"Could not navigate to the payment provider\", \"NAVIGATION_ERROR\", {\n cause: cause instanceof Error ? cause : undefined,\n }),\n );\n }\n}\n\nexport function createPaymentsOperations(\n client: StorefrontClientContext,\n storage: StorageAdapter,\n cache: CartSnapshotCache,\n consentManager: ConsentManager | null,\n): PaymentsOperations {\n async function fetchPaymentStatus(\n ref: string,\n signal?: AbortSignal,\n ): Promise<Result<PaymentStatusResult, StorefrontError>> {\n const result = await client.query<PaymentStatusResponse>(\n { query: PAYMENT_STATUS_QUERY, variables: { ref } },\n { cache: false, signal },\n );\n if (result.isErr()) return err(result.error);\n if (!result.value.paymentStatus) return err(new NotFoundError(\"Payment not found\"));\n return ok(result.value.paymentStatus);\n }\n\n return {\n async getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>> {\n const result = await client.query<AvailablePaymentMethodsResponse>(\n { query: AVAILABLE_PAYMENT_METHODS_QUERY },\n { cache: true },\n );\n if (result.isErr()) return err(result.error);\n if (!result.value.availablePaymentMethods) {\n return err(new NotFoundError(\"Payment methods not available\"));\n }\n return ok(result.value.availablePaymentMethods.map(mapPaymentMethod));\n },\n\n async resumeReturn(options): Promise<Result<PaymentReturnOutcome, StorefrontError>> {\n const urlReturn = readReturnRef(options?.url);\n if (options?.url === undefined && urlReturn.applicable) cleanBrowserReturnUrl();\n\n const recoveryExists = paymentRecoveryExists(storage);\n if (recoveryExists.isErr()) return err(recoveryExists.error);\n if (!urlReturn.applicable && !recoveryExists.value) {\n const outcome = { kind: \"not_applicable\" } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n const storeIdResult = await resolvePaymentStoreId(client, options?.signal);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const recoveryResult = readPaymentRecovery(storage, storeIdResult.value);\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n let recovery = recoveryResult.value;\n const paymentRef = recovery?.paymentRef ?? urlReturn.ref;\n if (!paymentRef) {\n const outcome = { kind: \"not_applicable\" } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n if (recovery?.phase === \"session_unavailable\") {\n const outcome = {\n kind: \"session_unavailable\",\n paymentRef,\n orderNumber: recovery.orderNumber,\n } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n if (recovery?.phase === \"failed\" && recovery.orderNumber) {\n const outcome = { kind: \"failed\", paymentRef, orderNumber: recovery.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n notify(options?.onStateChange, {\n kind: \"checking\",\n paymentRef,\n orderNumber: recovery?.orderNumber ?? null,\n });\n const checkingResult = updateRecovery(storage, recovery, { phase: \"checking\" });\n if (checkingResult.isErr()) return err(checkingResult.error);\n recovery = checkingResult.value;\n\n let transientFailures = 0;\n let lastTransientError: StorefrontError | null = null;\n for (let attempt = 0; attempt < PAYMENT_POLL_LIMIT; attempt += 1) {\n if (options?.signal?.aborted) return err(cancelledError());\n const statusResult = await fetchPaymentStatus(paymentRef, options?.signal);\n if (statusResult.isErr()) {\n if (options?.signal?.aborted) return err(cancelledError());\n if (statusResult.error.code !== \"NETWORK_ERROR\") return err(statusResult.error);\n lastTransientError = statusResult.error;\n transientFailures += 1;\n if (transientFailures >= MAX_TRANSIENT_FAILURES) return err(lastTransientError);\n const continued = await waitFor(\n Math.min(1_000 * 2 ** (transientFailures - 1), MAX_TRANSIENT_BACKOFF_MS),\n options?.signal,\n );\n if (!continued) return err(cancelledError());\n continue;\n }\n\n transientFailures = 0;\n const status = statusResult.value;\n if (status.status === \"paid\") {\n if (recovery) finalizeRedirectPayment({ client, storage, cache, consentManager }, recovery);\n const outcome = { kind: \"paid\", paymentRef, orderNumber: status.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n if (status.status === \"failed\") {\n const failedResult = updateRecovery(storage, recovery, {\n phase: \"failed\",\n orderNumber: status.orderNumber,\n });\n if (failedResult.isErr()) return err(failedResult.error);\n const outcome = { kind: \"failed\", paymentRef, orderNumber: status.orderNumber } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n }\n\n const pendingResult = updateRecovery(storage, recovery, {\n phase: \"pending\",\n orderNumber: status.orderNumber,\n });\n if (pendingResult.isErr()) return err(pendingResult.error);\n recovery = pendingResult.value;\n notify(options?.onStateChange, {\n kind: \"checking\",\n paymentRef,\n orderNumber: status.orderNumber,\n });\n const continued = await waitFor(PAYMENT_POLL_INTERVAL_MS, options?.signal);\n if (!continued) return err(cancelledError());\n }\n\n const outcome = {\n kind: \"pending\",\n paymentRef,\n orderNumber: recovery?.orderNumber ?? null,\n reason: \"confirmation_timeout\",\n } as const;\n notify(options?.onStateChange, outcome);\n return ok(outcome);\n },\n\n async retryRedirect(options): Promise<Result<PaymentRedirectOutcome, StorefrontError>> {\n if (options?.signal?.aborted) return err(cancelledError());\n const storeIdResult = await resolvePaymentStoreId(client, options?.signal);\n if (storeIdResult.isErr()) return err(storeIdResult.error);\n const recoveryResult = readPaymentRecovery(storage, storeIdResult.value);\n if (recoveryResult.isErr()) return err(recoveryResult.error);\n const recovery = recoveryResult.value;\n if (!recovery || recovery.phase !== \"session_unavailable\") {\n return err(new StateError(\"Payment redirect can only be retried while its session is unavailable\", \"not_open\"));\n }\n\n const result = await client.mutate<PaymentSessionCreateResponse>(\n { query: PAYMENT_SESSION_CREATE_MUTATION, variables: { ref: recovery.paymentRef } },\n { signal: options?.signal },\n );\n if (result.isErr()) return err(result.error);\n const payload = result.value.paymentSessionCreate;\n const userError = mapUserErrors(payload.userErrors);\n if (payload.paymentAction.kind === \"redirect_pending\" || userError?.code === \"PAYMENT_SESSION_FAILED\") {\n const persisted = persistPaymentRecovery(storage, { ...recovery, phase: \"session_unavailable\" });\n if (persisted.isErr()) return err(persisted.error);\n return ok({\n kind: \"session_unavailable\",\n paymentRef: recovery.paymentRef,\n orderNumber: recovery.orderNumber,\n });\n }\n if (userError) return err(userError);\n if (\n payload.paymentAction.kind !== \"redirect\" ||\n payload.paymentAction.paymentRef !== recovery.paymentRef ||\n !isPaymentRef(payload.paymentAction.paymentRef)\n ) {\n return err(new StateError(\"Payment provider did not return a usable redirect\", \"session_unavailable\"));\n }\n\n const persisted = persistPaymentRecovery(storage, { ...recovery, phase: \"redirecting\" });\n if (persisted.isErr()) return err(persisted.error);\n const navigation = navigateTo(payload.paymentAction.redirectUrl, options?.navigate);\n if (navigation.isErr()) return err(navigation.error);\n return ok({\n kind: \"redirecting\",\n paymentRef: recovery.paymentRef,\n orderNumber: recovery.orderNumber,\n });\n },\n\n clearReturn(): void {\n clearPaymentRecovery(storage);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AnalyticsEmitFn } from \"./analytics.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { collectAllPages } from \"./list-all.ts\";\nimport type {\n DetailSection,\n DisplayIntent,\n PaginatedResult,\n Product,\n ProductFilter,\n ProductSortKey,\n StorefrontClientContext,\n} from \"./types.ts\";\nimport { normalizeProductAssetUrls } from \"./url.ts\";\n\ninterface RawDetailSection {\n id: string;\n title: string;\n sectionType: string;\n content: Record<string, unknown>;\n displayIntent: string;\n position: number;\n}\n\ntype RawProduct = Omit<Product, \"detailSections\"> & { detailSections: RawDetailSection[] };\n\nfunction mapDisplayIntent(raw: string): DisplayIntent {\n switch (raw) {\n case \"ACCORDION\":\n return \"ACCORDION\";\n case \"SPECIFICATIONS\":\n return \"SPECIFICATIONS\";\n case \"BOTH\":\n return \"BOTH\";\n default:\n return \"ACCORDION\";\n }\n}\n\nfunction mapDetailSection(raw: RawDetailSection): DetailSection {\n const base = {\n id: raw.id,\n title: raw.title,\n displayIntent: mapDisplayIntent(raw.displayIntent),\n position: raw.position,\n };\n switch (raw.sectionType) {\n case \"RICH_TEXT\":\n return { ...base, sectionType: \"RICH_TEXT\", content: { html: raw.content.html as string } };\n case \"BULLET_LIST\":\n return { ...base, sectionType: \"BULLET_LIST\", content: { items: raw.content.items as string[] } };\n case \"TABLE\":\n return { ...base, sectionType: \"TABLE\", content: { rows: raw.content.rows as [string, string][] } };\n default:\n return { ...base, sectionType: \"RICH_TEXT\", content: { html: \"\" } };\n }\n}\n\nfunction mapProduct(raw: RawProduct): Product {\n return { ...raw, detailSections: raw.detailSections.map(mapDetailSection) };\n}\n\nexport interface ProductsListOptions {\n first?: number;\n after?: string;\n filter?: ProductFilter;\n sort?: ProductSortKey;\n}\n\ninterface ProductEdge {\n node: RawProduct;\n cursor: string;\n}\n\ninterface ProductConnection {\n edges: ProductEdge[];\n pageInfo: {\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n startCursor: string | null;\n endCursor: string | null;\n };\n}\n\ninterface ProductsQueryResponse {\n products: ProductConnection;\n}\n\ninterface ProductQueryResponse {\n product: RawProduct | null;\n}\n\ninterface ProductsByHandlesQueryResponse {\n productsByHandles: (RawProduct | null)[];\n}\n\ninterface ProductsByIdsQueryResponse {\n productsByIds: (RawProduct | null)[];\n}\n\nconst PRODUCTS_QUERY = `\nquery Products($first: Int, $after: String, $filter: ProductFilter, $sort: ProductSortKey) {\n products(first: $first, after: $after, filter: $filter, sort: $sort) {\n edges {\n node {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n`;\n\nconst PRODUCT_BY_ID_QUERY = `\nquery ProductById($id: ID!) {\n product(id: $id) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCT_BY_HANDLE_QUERY = `\nquery ProductByHandle($handle: String!) {\n product(handle: $handle) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCTS_BY_HANDLES_QUERY = `\nquery ProductsByHandles($handles: [String!]!) {\n productsByHandles(handles: $handles) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nconst PRODUCTS_BY_IDS_QUERY = `\nquery ProductsByIds($ids: [ID!]!) {\n productsByIds(ids: $ids) {\n id\n handle\n title\n description\n shortDescription\n vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n options {\n id\n name\n position\n values {\n id\n value\n position\n }\n }\n variants {\n id\n title\n sku\n price { amount currency }\n compareAtPrice { amount currency }\n weight\n weightUnit\n requiresShipping\n availableForSale\n backInStockSubscriptionAvailable\n quantity\n selectedOptions {\n id\n value\n position\n }\n image {\n id\n url: gridUrl\n previewUrl: gridUrl\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price { amount currency }\n }\n }\n categories {\n id\n name\n handle\n description\n }\n primaryCategory {\n id\n name\n handle\n }\n tags {\n id\n name\n }\n detailSections {\n id\n title\n sectionType\n content\n displayIntent\n position\n }\n declaration {\n snapshotId\n declarationId\n productId\n variantId\n templateKey\n templateVersion\n language\n script\n templateName\n rows {\n key\n label\n value\n role\n }\n warnings {\n key\n label\n value\n }\n createdAt\n }\n }\n}\n`;\n\nexport interface ProductsOperations {\n listAll(filter?: ProductFilter): Promise<Result<Product[], StorefrontError>>;\n /**\n * List products with cursor pagination and optional filters.\n *\n * @param options - Pagination, search, and sort options.\n * @returns Paginated storefront products.\n */\n list(options?: ProductsListOptions): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n /**\n * Fetch a single product by UUID.\n *\n * @param id - Product UUID.\n * @returns The matching product.\n */\n byId(id: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch a single product by handle.\n *\n * @param handle - Product handle.\n * @returns The matching product.\n */\n byHandle(handle: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch a single product by handle.\n *\n * @param handle - Product handle.\n * @returns The matching product.\n */\n get(handle: string): Promise<Result<Product, StorefrontError>>;\n /**\n * Fetch multiple products by handle in request order.\n *\n * @param handles - Product handles to resolve.\n * @returns Products for each requested handle, with `null` for missing entries.\n */\n getByHandles(handles: string[]): Promise<Result<(Product | null)[], StorefrontError>>;\n /**\n * Fetch multiple products by UUID in request order.\n *\n * @param ids - Product UUIDs to resolve.\n * @returns Products for each requested UUID, with `null` for missing or inaccessible entries.\n */\n productsByIds(ids: string[]): Promise<Result<(Product | null)[], StorefrontError>>;\n}\n\nexport function createProductsOperations(client: StorefrontClientContext, emit?: AnalyticsEmitFn): ProductsOperations {\n const operations: ProductsOperations = {\n listAll: (filter) => collectAllPages((options) => operations.list({ ...options, filter })),\n async list(options?: ProductsListOptions): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const result = await client.query<ProductsQueryResponse>({\n query: PRODUCTS_QUERY,\n variables: {\n first: options?.first,\n after: options?.after,\n filter: options?.filter,\n sort: options?.sort,\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const connection = result.value.products;\n\n if (emit && options?.filter?.search) {\n emit(\"analytics.search_performed\", {\n query: options.filter.search,\n resultsCount: connection.edges.length,\n });\n }\n\n return ok({\n items: connection.edges.map((edge) => normalizeProductAssetUrls(mapProduct(edge.node), client.config.endpoint)),\n pageInfo: {\n hasNextPage: connection.pageInfo.hasNextPage,\n hasPreviousPage: connection.pageInfo.hasPreviousPage,\n startCursor: connection.pageInfo.startCursor,\n endCursor: connection.pageInfo.endCursor,\n },\n });\n },\n\n async byId(id: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_ID_QUERY,\n variables: { id },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${id}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async byHandle(handle: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${handle}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async get(handle: string): Promise<Result<Product, StorefrontError>> {\n const result = await client.query<ProductQueryResponse>({\n query: PRODUCT_BY_HANDLE_QUERY,\n variables: { handle },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.product) {\n return err(new NotFoundError(`Product not found: ${handle}`));\n }\n\n return ok(normalizeProductAssetUrls(mapProduct(result.value.product), client.config.endpoint));\n },\n\n async getByHandles(handles: string[]): Promise<Result<(Product | null)[], StorefrontError>> {\n if (handles.length === 0) {\n return ok([]);\n }\n\n const result = await client.query<ProductsByHandlesQueryResponse>({\n query: PRODUCTS_BY_HANDLES_QUERY,\n variables: { handles },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(\n result.value.productsByHandles.map((product) =>\n product ? normalizeProductAssetUrls(mapProduct(product), client.config.endpoint) : null,\n ),\n );\n },\n\n async productsByIds(ids: string[]): Promise<Result<(Product | null)[], StorefrontError>> {\n if (ids.length === 0) {\n return ok([]);\n }\n\n const result = await client.query<ProductsByIdsQueryResponse>({\n query: PRODUCTS_BY_IDS_QUERY,\n variables: { ids },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(\n result.value.productsByIds.map((product) =>\n product ? normalizeProductAssetUrls(mapProduct(product), client.config.endpoint) : null,\n ),\n );\n },\n };\n return operations;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Money, ShippingRate, StorefrontClientContext } from \"./types.ts\";\n\ninterface ShippingRateData {\n id: string;\n name: string;\n price: Money;\n minOrderAmount: Money | null;\n estimatedDaysMin: number | null;\n estimatedDaysMax: number | null;\n isFree: boolean;\n}\n\ninterface AvailableShippingRatesResponse {\n availableShippingRates: ShippingRateData[];\n}\n\nconst AVAILABLE_SHIPPING_RATES_QUERY = `\nquery AvailableShippingRates {\n availableShippingRates {\n id\n name\n price { amount currency }\n minOrderAmount { amount currency }\n estimatedDaysMin\n estimatedDaysMax\n isFree\n }\n}\n`;\n\nfunction mapShippingRate(data: ShippingRateData): ShippingRate {\n return {\n id: data.id,\n name: data.name,\n price: data.price,\n minOrderAmount: data.minOrderAmount,\n estimatedDaysMin: data.estimatedDaysMin,\n estimatedDaysMax: data.estimatedDaysMax,\n isFree: data.isFree,\n };\n}\n\nexport interface ShippingOperations {\n /**\n * Fetch shipping rates currently available for checkout.\n *\n * @returns Available shipping rates.\n */\n getAvailableRates(): Promise<Result<ShippingRate[], StorefrontError>>;\n}\n\nexport function createShippingOperations(client: StorefrontClientContext): ShippingOperations {\n return {\n async getAvailableRates(): Promise<Result<ShippingRate[], StorefrontError>> {\n const result = await client.query<AvailableShippingRatesResponse>(\n { query: AVAILABLE_SHIPPING_RATES_QUERY },\n { cache: false },\n );\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.availableShippingRates) {\n return err(new NotFoundError(\"Shipping rates not available\"));\n }\n\n return ok(result.value.availableShippingRates.map(mapShippingRate));\n },\n };\n}\n","import { err, ok } from \"neverthrow\";\nimport type { Store, StorefrontClientContext, StorefrontResult } from \"./types.ts\";\n\n/**\n * Store-level read operations exposed by the storefront SDK.\n */\nexport interface StoreOperations {\n get(options?: { cache?: boolean }): Promise<StorefrontResult<Store>>;\n}\n\ninterface StoreQueryResponse {\n store: Store;\n}\n\nconst STORE_QUERY = `\nquery Store {\n store {\n id\n name\n slug\n description\n currency\n timezone\n locale\n contactEmail\n contactPhone\n branding {\n tagline\n logoUrl\n socialLinks {\n instagram\n facebook\n tiktok\n twitter\n youtube\n }\n contactInfo {\n email\n phone\n address\n }\n }\n browserTrackingConfig {\n gtm {\n enabled\n containerId\n }\n }\n analytics {\n enabled\n firstPartyEnabled\n gtm {\n enabled\n containerId\n }\n }\n }\n}\n`;\n\nexport function createStoreOperations(client: StorefrontClientContext): StoreOperations {\n return {\n async get(options?: { cache?: boolean }): Promise<StorefrontResult<Store>> {\n const result = await client.query<StoreQueryResponse>(\n {\n query: STORE_QUERY,\n },\n options,\n );\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n return ok(result.value.store);\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { type AccountOperations, createAccountOperations } from \"./account.ts\";\nimport { type AnalyticsOperations, createAnalyticsOperations } from \"./analytics.ts\";\nimport { type AuthOperations, createAuthOperations } from \"./auth.ts\";\nimport { createQueryCache, type QueryCache } from \"./cache.ts\";\nimport { type CartOperations, createCartOperations } from \"./cart.ts\";\nimport { createCartSnapshotCache } from \"./cart-snapshot-cache.ts\";\nimport { type CategoriesOperations, createCategoriesOperations } from \"./categories.ts\";\nimport { type CheckoutOperations, createCheckoutOperations } from \"./checkout.ts\";\nimport { type CollectionsOperations, createCollectionsOperations } from \"./collections.ts\";\nimport { type ConsentBufferEntry, type ConsentManager, createConsentManager } from \"./consent.ts\";\nimport {\n createMenusOperations,\n createPagesOperations,\n createPoliciesOperations,\n type MenusOperations,\n type PagesOperations,\n type PoliciesOperations,\n} from \"./content.ts\";\nimport { createDebugBrowserAdapter } from \"./debug-browser-adapter.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { createGraphQLClient, type GraphQLClient, type GraphQLRequest } from \"./graphql-client.ts\";\nimport { createGtmBrowserAdapter } from \"./gtm-browser-adapter.ts\";\nimport { createMarketingOperations, type MarketingOperations } from \"./marketing.ts\";\nimport { createPaymentsOperations, type PaymentsOperations } from \"./payments.ts\";\nimport { createProductsOperations, type ProductsOperations } from \"./products.ts\";\nimport { createShippingOperations, type ShippingOperations } from \"./shipping.ts\";\nimport {\n CART_SESSION_KEY,\n CUSTOMER_SESSION_KEY,\n createDefaultAdapter,\n createNamespacedAdapter,\n getCheckoutLeadDispatchKey,\n getMarketStorageKey,\n getMarketStorageKeyByStoreId,\n isSandboxApiKey,\n} from \"./storage.ts\";\nimport { createStoreOperations, type StoreOperations } from \"./store.ts\";\nimport type {\n ResolvedStorefrontInitConfig,\n StorageAdapter,\n StorefrontAnalyticsInitConfig,\n StorefrontClientConfig,\n StorefrontClientContext,\n StorefrontInitOptions,\n} from \"./types.ts\";\n\nconst DEFAULT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport interface CacheHelpers {\n /**\n * Clear all cached query results for this client instance.\n */\n clear(): void;\n}\n\nexport interface StorefrontClient extends StorefrontClientContext {\n readonly cache: CacheHelpers;\n readonly products: ProductsOperations;\n readonly pages: PagesOperations;\n readonly policies: PoliciesOperations;\n readonly menus: MenusOperations;\n readonly store: StoreOperations;\n readonly collections: CollectionsOperations;\n readonly categories: CategoriesOperations;\n readonly cart: CartOperations;\n readonly checkout: CheckoutOperations;\n readonly payments: PaymentsOperations;\n readonly auth: AuthOperations;\n readonly account: AccountOperations;\n readonly shipping: ShippingOperations;\n readonly analytics: AnalyticsOperations;\n readonly marketing: MarketingOperations;\n\n init(options?: StorefrontInitOptions): Promise<Result<ResolvedStorefrontInitConfig, StorefrontError>>;\n}\n\ninterface InternalClient extends StorefrontClient {\n readonly _graphql: GraphQLClient;\n readonly _storage: StorageAdapter;\n readonly _queryCache: QueryCache;\n _analyticsRuntimeConfig: StorefrontAnalyticsInitConfig | null;\n _resolvedInitConfig: ResolvedStorefrontInitConfig | null;\n}\n\nexport type { AccountOperations } from \"./account.ts\";\nexport type { AnalyticsOperations } from \"./analytics.ts\";\nexport type { AuthOperations } from \"./auth.ts\";\nexport type { CartOperations } from \"./cart.ts\";\nexport type { CategoriesOperations } from \"./categories.ts\";\nexport type { CheckoutOperations } from \"./checkout.ts\";\nexport type { CollectionProductSort, CollectionsOperations } from \"./collections.ts\";\nexport type { MarketingOperations } from \"./marketing.ts\";\nexport type { PaymentsOperations } from \"./payments.ts\";\nexport type { ProductsOperations } from \"./products.ts\";\nexport type { ShippingOperations } from \"./shipping.ts\";\nexport type { StoreOperations } from \"./store.ts\";\n\n/**\n * Create a new Storefront SDK client\n *\n * @param config - Client configuration including endpoint, API key, and optional storage adapter\n * @returns A configured StorefrontClient instance\n *\n * @example\n * ```typescript\n * import { createStorefrontClient } from \"@ekomerc/storefront\";\n *\n * const client = createStorefrontClient({\n * endpoint: \"https://storefront-api.mystore.com/graphql\",\n * apiKey: \"sfk_abc123...\",\n * });\n *\n * // Query products\n * const result = await client.query({\n * query: `query { products { edges { node { id title } } } }`,\n * });\n *\n * if (result.isOk()) {\n * console.log(result.value);\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport function createStorefrontClient(config: StorefrontClientConfig): StorefrontClient {\n if (config.tracking) {\n // biome-ignore lint/suspicious/noConsole: SDK deprecation warning for consumers\n console.warn(\n \"[ekomerc] StorefrontClientConfig.tracking is deprecated. Pass analytics hooks to client.init({ analytics: ... }) instead.\",\n );\n }\n const rawStorage = config.storage ?? createDefaultAdapter();\n const storage = isSandboxApiKey(config.apiKey) ? createNamespacedAdapter(rawStorage, \"sandbox:\") : rawStorage;\n const queryCache = createQueryCache();\n const cacheTTL = config.cacheTTL ?? DEFAULT_CACHE_TTL;\n\n // Initially scoped to apiKey (storeId not yet known); migrated to storeId during init().\n let marketStorageKey = getMarketStorageKey(config.apiKey);\n\n const graphqlClient = createGraphQLClient({\n endpoint: config.endpoint,\n apiKey: config.apiKey,\n getCartToken: () => storage.get(CART_SESSION_KEY),\n getCustomerToken: () => storage.get(CUSTOMER_SESSION_KEY),\n getMarketSlug: () => storage.get(marketStorageKey),\n cache: queryCache,\n cacheTTL,\n });\n\n const client: InternalClient = {\n config,\n _graphql: graphqlClient,\n _storage: storage,\n _queryCache: queryCache,\n _analyticsRuntimeConfig: null,\n _resolvedInitConfig: null,\n\n cache: {\n clear(): void {\n queryCache.clear();\n },\n },\n\n // Placeholder - will be assigned below\n products: null as unknown as ProductsOperations,\n pages: null as unknown as PagesOperations,\n policies: null as unknown as PoliciesOperations,\n menus: null as unknown as MenusOperations,\n store: null as unknown as StoreOperations,\n collections: null as unknown as CollectionsOperations,\n categories: null as unknown as CategoriesOperations,\n cart: null as unknown as CartOperations,\n checkout: null as unknown as CheckoutOperations,\n payments: null as unknown as PaymentsOperations,\n auth: null as unknown as AuthOperations,\n account: null as unknown as AccountOperations,\n shipping: null as unknown as ShippingOperations,\n analytics: null as unknown as AnalyticsOperations,\n marketing: null as unknown as MarketingOperations,\n\n init: null as unknown as StorefrontClient[\"init\"],\n\n query<T>(\n request: GraphQLRequest,\n options?: { cache?: boolean; signal?: AbortSignal },\n ): Promise<Result<T, StorefrontError>> {\n return graphqlClient.query<T>(request, options);\n },\n\n mutate<T>(request: GraphQLRequest, options?: { signal?: AbortSignal }): Promise<Result<T, StorefrontError>> {\n return graphqlClient.mutate<T>(request, options);\n },\n\n getCartToken(): string | null {\n return storage.get(CART_SESSION_KEY);\n },\n\n setCartToken(token: string): void {\n storage.set(CART_SESSION_KEY, token);\n },\n\n clearCartToken(): void {\n const currentToken = storage.get(CART_SESSION_KEY);\n if (currentToken) {\n storage.remove(getCheckoutLeadDispatchKey(currentToken));\n }\n storage.remove(CART_SESSION_KEY);\n },\n\n getCustomerToken(): string | null {\n return storage.get(CUSTOMER_SESSION_KEY);\n },\n\n setCustomerToken(token: string): void {\n storage.set(CUSTOMER_SESSION_KEY, token);\n },\n\n clearCustomerToken(): void {\n storage.remove(CUSTOMER_SESSION_KEY);\n },\n\n getMarket(): string | null {\n return storage.get(marketStorageKey);\n },\n\n setMarket(slug: string): void {\n const current = storage.get(marketStorageKey);\n if (current !== slug) {\n storage.set(marketStorageKey, slug);\n client.clearCartToken();\n queryCache.clear();\n }\n },\n\n clearMarket(): void {\n const current = storage.get(marketStorageKey);\n if (current !== null) {\n storage.remove(marketStorageKey);\n client.clearCartToken();\n queryCache.clear();\n }\n },\n };\n\n // Consent manager and analytics must be created before cart/checkout so auto-tracking can emit events\n const hasCustomConsentResolver = Boolean(config.tracking?.resolveConsentState);\n let consentMgr: ConsentManager | null = null;\n let unsubConsentBridge: (() => void) | null = null;\n\n if (!hasCustomConsentResolver) {\n consentMgr = createConsentManager({\n debug: config.debug,\n onBufferFlush(entries: ConsentBufferEntry[]) {\n for (const entry of entries) {\n try {\n entry.adapter.dispatch(entry.input);\n } catch {\n // Best-effort flush — must not throw.\n }\n }\n },\n });\n }\n\n const { operations: analyticsController, emit: analyticsEmit } = createAnalyticsOperations(\n client,\n storage,\n consentMgr,\n );\n (client as { analytics: AnalyticsOperations }).analytics = analyticsController;\n\n // Create operations after client and analytics are created\n const cartCache = createCartSnapshotCache(client, storage);\n (client as { products: ProductsOperations }).products = createProductsOperations(client, analyticsEmit);\n (client as { store: StoreOperations }).store = createStoreOperations(client);\n (client as { collections: CollectionsOperations }).collections = createCollectionsOperations(client);\n (client as { categories: CategoriesOperations }).categories = createCategoriesOperations(client);\n (client as { pages: PagesOperations }).pages = createPagesOperations(client);\n (client as { policies: PoliciesOperations }).policies = createPoliciesOperations(client);\n (client as { menus: MenusOperations }).menus = createMenusOperations(client);\n (client as { cart: CartOperations }).cart = createCartOperations(client, storage, analyticsEmit, cartCache);\n (client as { checkout: CheckoutOperations }).checkout = createCheckoutOperations(\n client,\n storage,\n analyticsEmit,\n cartCache,\n consentMgr,\n );\n (client as { payments: PaymentsOperations }).payments = createPaymentsOperations(\n client,\n storage,\n cartCache,\n consentMgr,\n );\n (client as { auth: AuthOperations }).auth = createAuthOperations(client, storage);\n (client as { account: AccountOperations }).account = createAccountOperations(client, storage);\n (client as { shipping: ShippingOperations }).shipping = createShippingOperations(client);\n (client as { marketing: MarketingOperations }).marketing = createMarketingOperations(client, storage, analyticsEmit);\n client.init = async (options?: StorefrontInitOptions) => {\n client._analyticsRuntimeConfig = options?.analytics ?? null;\n\n const hasUserConsentResolver = Boolean(options?.analytics?.resolveConsentState);\n\n const storeResult = await client.store.get({ cache: false });\n if (storeResult.isErr()) {\n return err(storeResult.error);\n }\n\n // Migrate market slug from apiKey-scoped key to the canonical storeId-scoped key.\n const storeIdKey = getMarketStorageKeyByStoreId(storeResult.value.id);\n if (storeIdKey !== marketStorageKey) {\n const existing = storage.get(marketStorageKey);\n if (existing !== null) {\n storage.set(storeIdKey, existing);\n storage.remove(marketStorageKey);\n }\n marketStorageKey = storeIdKey;\n }\n\n const resolvedConfig: ResolvedStorefrontInitConfig = {\n analytics: {\n enabled: storeResult.value.analytics.enabled,\n firstPartyEnabled: storeResult.value.analytics.firstPartyEnabled,\n gtm: storeResult.value.analytics.gtm,\n },\n };\n\n const userAnalytics = options?.analytics ?? {};\n const userAdapters = userAnalytics.adapters ?? [];\n const hasUserGtmAdapter = userAdapters.some((a) => a.provider === \"gtm\");\n\n const autoAdapters = (() => {\n const adapters = [...userAdapters];\n if (!hasUserGtmAdapter) {\n const gtmAdapter = createGtmBrowserAdapter(resolvedConfig.analytics.gtm, {\n debug: config.debug,\n initialConsentState: consentMgr && !hasUserConsentResolver ? consentMgr.getCategories() : undefined,\n });\n if (gtmAdapter) adapters.push(gtmAdapter);\n }\n const debugAdapter = createDebugBrowserAdapter();\n if (debugAdapter) adapters.push(debugAdapter);\n return adapters;\n })();\n\n client._analyticsRuntimeConfig = {\n ...userAnalytics,\n adapters: autoAdapters,\n };\n client._resolvedInitConfig = resolvedConfig;\n analyticsController.init(resolvedConfig.analytics);\n\n if (consentMgr && !hasUserConsentResolver) {\n unsubConsentBridge?.();\n unsubConsentBridge = consentMgr.onChange(() => {\n for (const adapter of autoAdapters) {\n if (!adapter.updateConsent) continue;\n try {\n adapter.updateConsent({ consentState: consentMgr.getState() });\n } catch {\n // Best-effort consent bridge update.\n }\n }\n });\n }\n\n return ok(resolvedConfig);\n };\n\n return client;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport { StorefrontError } from \"./errors.ts\";\nimport type { Collection, CollectionSortOrder, Product, ProductSortKey } from \"./types.ts\";\n\n/** Sort modes supported by product feed descriptors. */\nexport type ProductFeedSort = \"manual\" | \"newest\" | \"oldest\" | \"title_asc\" | \"title_desc\";\n/** Sort modes supported by collection feed descriptors. */\nexport type CollectionFeedSort = \"manual\" | \"newest\" | \"oldest\" | \"title_asc\" | \"title_desc\";\ntype CollectionProductFeedSort = Extract<ProductFeedSort, \"manual\" | \"newest\">;\ntype CatalogProductFeedSort = Extract<ProductFeedSort, \"newest\" | \"title_asc\">;\n\n/** Stored product-feed descriptor that themes resolve through storefront GraphQL at render time. */\nexport type ProductFeedDescriptor =\n | {\n version: 1;\n source: \"manual\";\n limit: number;\n productIds: string[];\n sort: \"manual\";\n }\n | {\n version: 1;\n source: \"collection\";\n limit: number;\n collectionId: string;\n sort: CollectionProductFeedSort;\n }\n | {\n version: 1;\n source: \"category\";\n limit: number;\n categoryId: string;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"latest\";\n limit: number;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"all\";\n limit: number;\n sort: CatalogProductFeedSort;\n };\n\n/** Stored collection-feed descriptor that themes resolve through storefront GraphQL at render time. */\nexport type CollectionFeedDescriptor =\n | {\n version: 1;\n source: \"manual\";\n limit: number;\n collectionIds: string[];\n sort: \"manual\";\n }\n | {\n version: 1;\n source: \"latest\";\n limit: number;\n sort: \"newest\";\n }\n | {\n version: 1;\n source: \"all\";\n limit: number;\n sort: \"newest\";\n };\n\n/** Product-feed descriptor input, including future versions that resolve to an unsupported descriptor error. */\nexport type ProductFeedDescriptorInput = ProductFeedDescriptor | { version: number; [key: string]: unknown };\n/** Collection-feed descriptor input, including future versions that resolve to an unsupported descriptor error. */\nexport type CollectionFeedDescriptorInput = CollectionFeedDescriptor | { version: number; [key: string]: unknown };\n/** Minimal storefront client surface required to resolve theme commerce descriptors. */\nexport type CommerceDescriptorClient = Pick<StorefrontClient, \"products\" | \"collections\" | \"categories\">;\n\n/** Resolved product-feed payload returned to SDK-backed theme sections. */\nexport interface ProductFeedResult {\n version: 1;\n source: ProductFeedDescriptor[\"source\"];\n limit: number;\n products: Product[];\n collection: Collection | null;\n}\n\n/** Resolved collection-feed payload returned to SDK-backed theme sections. */\nexport interface CollectionFeedResult {\n version: 1;\n source: CollectionFeedDescriptor[\"source\"];\n limit: number;\n collections: Collection[];\n}\n\nexport class UnsupportedDescriptorError extends StorefrontError {\n constructor(kind: \"product_feed\" | \"collection_feed\", version: unknown) {\n super(`${kind} descriptor version is not supported: ${String(version)}`, \"UNSUPPORTED_DESCRIPTOR\");\n this.name = \"UnsupportedDescriptorError\";\n }\n}\n\nconst MAX_FEED_LIMIT = 50;\n\nfunction normalizeLimit(limit: number): number {\n if (!Number.isFinite(limit)) return 1;\n return Math.min(Math.max(1, Math.floor(limit)), MAX_FEED_LIMIT);\n}\n\nfunction isSupportedProductFeedDescriptor(value: ProductFeedDescriptorInput): value is ProductFeedDescriptor {\n if (value.version !== 1) return false;\n\n switch (value.source) {\n case \"manual\":\n return Array.isArray(value.productIds) && value.sort === \"manual\";\n case \"collection\":\n return typeof value.collectionId === \"string\" && (value.sort === \"manual\" || value.sort === \"newest\");\n case \"category\":\n return typeof value.categoryId === \"string\" && value.sort === \"newest\";\n case \"latest\":\n return value.sort === \"newest\";\n case \"all\":\n return value.sort === \"newest\" || value.sort === \"title_asc\";\n default:\n return false;\n }\n}\n\nfunction isSupportedCollectionFeedDescriptor(value: CollectionFeedDescriptorInput): value is CollectionFeedDescriptor {\n if (value.version !== 1) return false;\n\n switch (value.source) {\n case \"manual\":\n return Array.isArray(value.collectionIds) && value.sort === \"manual\";\n case \"latest\":\n return value.sort === \"newest\";\n case \"all\":\n return value.sort === \"newest\";\n default:\n return false;\n }\n}\n\nfunction compact<T>(values: Array<T | null>): T[] {\n return values.filter((value): value is T => value !== null);\n}\n\nfunction productSort(sort: CatalogProductFeedSort): ProductSortKey {\n switch (sort) {\n case \"title_asc\":\n return \"TITLE\";\n case \"newest\":\n return \"CREATED_AT\";\n default:\n return sort satisfies never;\n }\n}\n\nfunction collectionSort(sort: CollectionProductFeedSort): CollectionSortOrder {\n switch (sort) {\n case \"manual\":\n return \"manual\";\n case \"newest\":\n return \"newest\";\n default:\n return sort satisfies never;\n }\n}\n\nasync function resolveCollectionByIdOrNull(\n client: CommerceDescriptorClient,\n id: string,\n): Promise<Result<Collection | null, StorefrontError>> {\n const result = await client.collections.byId(id);\n if (result.isOk()) return ok(result.value);\n if (result.error.code === \"NOT_FOUND\") return ok(null);\n return err(result.error);\n}\n\n/** Resolve one collection descriptor id through storefront visibility rules. */\nexport async function resolveCollectionById(\n client: CommerceDescriptorClient,\n id: string | null | undefined,\n): Promise<Result<Collection | null, StorefrontError>> {\n if (!id) return ok(null);\n return resolveCollectionByIdOrNull(client, id);\n}\n\n/** Resolve a product-feed descriptor while preserving manual ordering and omitting inaccessible products. */\nexport async function resolveProductFeed(\n client: CommerceDescriptorClient,\n descriptor: ProductFeedDescriptorInput | null | undefined,\n): Promise<Result<ProductFeedResult | null, StorefrontError>> {\n if (!descriptor) return ok(null);\n if (!isSupportedProductFeedDescriptor(descriptor)) {\n return err(new UnsupportedDescriptorError(\"product_feed\", descriptor.version));\n }\n\n const limit = normalizeLimit(descriptor.limit);\n let productsResult: Result<Product[], StorefrontError>;\n let collection: Collection | null = null;\n\n switch (descriptor.source) {\n case \"manual\": {\n const result = await client.products.productsByIds(descriptor.productIds.slice(0, limit));\n if (result.isErr()) return err(result.error);\n productsResult = ok(compact(result.value));\n break;\n }\n case \"collection\": {\n const collectionResult = await resolveCollectionByIdOrNull(client, descriptor.collectionId);\n if (collectionResult.isErr()) return err(collectionResult.error);\n collection = collectionResult.value;\n if (!collection) {\n productsResult = ok([]);\n break;\n }\n const result = await client.collections.getProductsById(descriptor.collectionId, {\n first: limit,\n sort: collectionSort(descriptor.sort),\n });\n if (result.isErr()) return err(result.error);\n productsResult = ok(result.value.items);\n break;\n }\n case \"category\": {\n const result = await client.categories.getProductsById(descriptor.categoryId, {\n first: limit,\n includeDescendants: true,\n });\n if (result.isErr()) {\n if (result.error.code === \"NOT_FOUND\") {\n productsResult = ok([]);\n break;\n }\n return err(result.error);\n }\n productsResult = ok(result.value.items);\n break;\n }\n case \"latest\":\n case \"all\": {\n const result = await client.products.list({ first: limit, sort: productSort(descriptor.sort) });\n if (result.isErr()) return err(result.error);\n productsResult = ok(result.value.items);\n break;\n }\n default:\n return descriptor satisfies never;\n }\n\n return productsResult.map((products) => ({\n version: 1,\n source: descriptor.source,\n limit,\n products,\n collection,\n }));\n}\n\n/** Resolve a collection-feed descriptor while omitting inaccessible collections. */\nexport async function resolveCollectionFeed(\n client: CommerceDescriptorClient,\n descriptor: CollectionFeedDescriptorInput | null | undefined,\n): Promise<Result<CollectionFeedResult | null, StorefrontError>> {\n if (!descriptor) return ok(null);\n if (!isSupportedCollectionFeedDescriptor(descriptor)) {\n return err(new UnsupportedDescriptorError(\"collection_feed\", descriptor.version));\n }\n\n const limit = normalizeLimit(descriptor.limit);\n\n switch (descriptor.source) {\n case \"manual\": {\n const settled = await Promise.all(\n descriptor.collectionIds.slice(0, limit).map((id) => resolveCollectionByIdOrNull(client, id)),\n );\n const firstError = settled.find((result) => result.isErr());\n if (firstError?.isErr()) return err(firstError.error);\n return ok({\n version: 1,\n source: \"manual\",\n limit,\n collections: compact(settled.map((result) => (result.isOk() ? result.value : null))),\n });\n }\n case \"latest\":\n case \"all\": {\n const result = await client.collections.list({ first: limit });\n if (result.isErr()) return err(result.error);\n return ok({\n version: 1,\n source: descriptor.source,\n limit,\n collections: result.value.items,\n });\n }\n default:\n return descriptor satisfies never;\n }\n}\n\n/**\n * Deprecated compatibility alias for {@link resolveProductFeed}.\n *\n * @deprecated Use {@link resolveProductFeed}. This alias remains for existing async SDK callers.\n */\nexport const useProductFeed = resolveProductFeed;\n/**\n * Deprecated compatibility alias for {@link resolveCollectionById}.\n *\n * @deprecated Use {@link resolveCollectionById}. This alias remains for existing async SDK callers.\n */\nexport const useCollectionById = resolveCollectionById;\n/**\n * Deprecated compatibility alias for {@link resolveCollectionFeed}.\n *\n * @deprecated Use {@link resolveCollectionFeed}. This alias remains for existing async SDK callers.\n */\nexport const useCollectionFeed = resolveCollectionFeed;\n","import { err, ok, type Result } from \"neverthrow\";\nimport { NetworkError, type StorefrontError } from \"./errors.ts\";\nimport type { StorefrontClientConfig } from \"./types.ts\";\n\n/** Validated platform discovery metadata; the publishable key is safe to ship in the site. */\nexport interface SiteDiscovery extends Pick<StorefrontClientConfig, \"endpoint\" | \"apiKey\"> {\n siteId: string;\n primaryOrigin: string;\n urlTemplates: Record<string, string>;\n}\n\nfunction publicHttpUrl(value: unknown): value is string {\n if (typeof value !== \"string\") return false;\n try {\n const url = new URL(value);\n return [\"http:\", \"https:\"].includes(url.protocol) && !url.username && !url.password;\n } catch {\n return false;\n }\n}\n\n/** Reads platform discovery metadata; accepts only v1 responses carrying a live publishable key. */\nexport async function discoverSite(origin: string): Promise<Result<SiteDiscovery, StorefrontError>> {\n try {\n if (!publicHttpUrl(origin)) return err(new NetworkError(\"Invalid site origin\"));\n const response = await fetch(new URL(\"/.well-known/ekomerc/site.json\", origin));\n if (!response.ok) return err(new NetworkError(`Site discovery failed: HTTP ${response.status}`));\n const value: unknown = await response.json();\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return err(new NetworkError(\"Invalid site discovery response\"));\n const data = value as Record<string, unknown>;\n if (\n data.version !== 1 ||\n typeof data.siteId !== \"string\" ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(data.siteId) ||\n !publicHttpUrl(data.storefrontApiUrl) ||\n !publicHttpUrl(data.primaryOrigin) ||\n typeof data.publishableKey !== \"string\" ||\n !/^sfk_live_[a-zA-Z0-9]{28}$/.test(data.publishableKey) ||\n !data.urlTemplates ||\n typeof data.urlTemplates !== \"object\" ||\n Array.isArray(data.urlTemplates) ||\n !Object.values(data.urlTemplates).every((path) => typeof path === \"string\")\n ) {\n return err(new NetworkError(\"Invalid site discovery response\"));\n }\n return ok({\n siteId: data.siteId,\n endpoint: data.storefrontApiUrl,\n apiKey: data.publishableKey,\n primaryOrigin: data.primaryOrigin,\n urlTemplates: data.urlTemplates as Record<string, string>,\n });\n } catch (error) {\n return err(new NetworkError(\"Site discovery failed\", { cause: error instanceof Error ? error : undefined }));\n }\n}\n"],"mappings":"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"}