@ekomerc/storefront 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +237 -10
- package/dist/index.cjs +2840 -1810
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +667 -16
- package/dist/index.js +2841 -1811
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/cache.ts","../src/storage.ts","../src/account.ts","../src/auth.ts","../src/tracking-attribution.ts","../src/url.ts","../src/cart.ts","../src/categories.ts","../src/checkout.ts","../src/collections.ts","../src/graphql-client.ts","../src/payments.ts","../src/products.ts","../src/analytics.ts","../src/shipping.ts","../src/client.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\nexport const CART_TOKEN_KEY = \"ekomerc_cart_token\";\nexport const CUSTOMER_TOKEN_KEY = \"ekomerc_customer_token\";\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 localStorage !== \"undefined\") {\n return createLocalStorageAdapter();\n }\n return createMemoryAdapter();\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { AuthError, ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_TOKEN_KEY } from \"./storage.ts\";\nimport type {\n Customer,\n CustomerAddress,\n CustomerAddressInput,\n CustomerAddressUpdateInput,\n CustomerOrder,\n CustomerUpdateInput,\n PaginatedResult,\n StorageAdapter,\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: number;\n totalPrice: number;\n}\n\ninterface OrderNodeData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n subtotal: number;\n total: number;\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 postalCode: 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\n totalPrice\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\n total\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 postalCode\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: String!, $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: String!) {\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 postalCode: data.postalCode,\n phone: data.phone,\n isDefault: data.isDefault,\n createdAt: data.createdAt,\n };\n}\n\nfunction handleUserErrors(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 orders(args?: {\n first?: number;\n after?: string;\n last?: number;\n before?: string;\n }): Promise<Result<PaginatedResult<CustomerOrder>, StorefrontError>>;\n addresses(): Promise<Result<CustomerAddress[], StorefrontError>>;\n createAddress(input: CustomerAddressInput): Promise<Result<CustomerAddress, StorefrontError>>;\n updateAddress(\n addressId: string,\n input: CustomerAddressUpdateInput,\n ): Promise<Result<CustomerAddress, StorefrontError>>;\n deleteAddress(addressId: string): Promise<Result<string, StorefrontError>>;\n update(input: CustomerUpdateInput): Promise<Result<Customer, StorefrontError>>;\n}\n\nexport function createAccountOperations(client: StorefrontClient, storage: StorageAdapter): AccountOperations {\n function requireAuth(): Result<void, AuthError> {\n if (!storage.get(CUSTOMER_TOKEN_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 = handleUserErrors(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 = handleUserErrors(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 = handleUserErrors(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 = handleUserErrors(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","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_TOKEN_KEY } from \"./storage.ts\";\nimport type { Customer, StorageAdapter } 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 CustomerVerifyEmailResponse {\n customerVerifyEmail: {\n customer: CustomerData | null;\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 CUSTOMER_VERIFY_EMAIL_MUTATION = `\nmutation CustomerVerifyEmail($input: CustomerVerifyEmailInput!) {\n customerVerifyEmail(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\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 handleUserErrors(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 AuthOperations {\n register(input: {\n email: string;\n password: string;\n name?: string;\n }): Promise<Result<{ customer: Customer; token: string }, StorefrontError>>;\n login(input: {\n email: string;\n password: string;\n }): Promise<Result<{ customer: Customer; token: string }, StorefrontError>>;\n logout(): void;\n requestPasswordReset(email: string): Promise<Result<{ success: boolean }, StorefrontError>>;\n resetPassword(input: { token: string; newPassword: string }): Promise<Result<{ success: boolean }, StorefrontError>>;\n verifyEmail(token: string): Promise<Result<Customer, StorefrontError>>;\n me(): Promise<Result<Customer | null, StorefrontError>>;\n isLoggedIn(): boolean;\n}\n\nexport function createAuthOperations(client: StorefrontClient, 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 = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer || !payload.token) {\n return err(new ValidationError(\"Registration failed\", []));\n }\n\n storage.set(CUSTOMER_TOKEN_KEY, payload.token);\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 = handleUserErrors(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_TOKEN_KEY, payload.token);\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n logout() {\n storage.remove(CUSTOMER_TOKEN_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 = handleUserErrors(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 = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async verifyEmail(token) {\n const result = await client.mutate<CustomerVerifyEmailResponse>({\n query: CUSTOMER_VERIFY_EMAIL_MUTATION,\n variables: { input: { token } },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerVerifyEmail;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Email verification failed\", []));\n }\n\n return ok(mapCustomerData(payload.customer));\n },\n\n async me() {\n if (!storage.get(CUSTOMER_TOKEN_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_TOKEN_KEY) !== null;\n },\n };\n}\n","const TRACKING_SCHEMA_VERSION = 1 as const;\nconst TRACKING_ATTRIBUTION_STORAGE_KEY = \"srb_tracking_attribution\";\n\ninterface TrackingUtmSnapshot {\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\ninterface TrackingClickIdsSnapshot {\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\nexport interface TrackingAttributionSnapshot {\n schemaVersion: 1;\n capturedAt: string;\n utm: TrackingUtmSnapshot;\n clickIds: TrackingClickIdsSnapshot;\n}\n\nfunction hasBrowserContext(): boolean {\n return typeof window !== \"undefined\";\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 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 readStoredSnapshot(): TrackingAttributionSnapshot | null {\n if (!hasBrowserContext()) return null;\n\n try {\n return parseStoredSnapshot(window.localStorage.getItem(TRACKING_ATTRIBUTION_STORAGE_KEY));\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(): 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();\n}\n\nexport function getTrackingAttributionSnapshot(): TrackingAttributionSnapshot | null {\n return readStoredSnapshot();\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 })),\n variants: product.variants.map((variant) => ({\n ...variant,\n image: variant.image\n ? {\n ...variant.image,\n url: resolveAssetUrl(variant.image.url, 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 ? { ...collection.imageAsset, url: resolveAssetUrl(collection.imageAsset.url, endpoint) }\n : null,\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, ValidationError } from \"./errors.ts\";\nimport { CART_TOKEN_KEY } from \"./storage.ts\";\nimport { captureLandingTrackingAttribution } from \"./tracking-attribution.ts\";\nimport type { Address, Cart, CartStatus, ProductVariant } from \"./types.ts\";\nimport { resolveAssetUrl } from \"./url.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface CartItemData {\n id: string;\n variantId: string;\n quantity: number;\n priceAtAdd: number;\n effectiveUnitPrice: number;\n lineTotal: number;\n taxAmount: number;\n variant:\n | (Pick<\n ProductVariant,\n | \"id\"\n | \"title\"\n | \"sku\"\n | \"price\"\n | \"compareAtPrice\"\n | \"weight\"\n | \"weightUnit\"\n | \"requiresShipping\"\n | \"availableForSale\"\n | \"quantity\"\n | \"selectedOptions\"\n | \"image\"\n | \"isOnSale\"\n | \"quantityPricing\"\n > & {})\n | null;\n}\n\ninterface AppliedPromoCodeData {\n code: string;\n discountType: string;\n discountAmount: number;\n description: string;\n}\n\ninterface AppliedDiscountData {\n promotionId: string;\n discountClass: string;\n discountType: string;\n discountAmount: number;\n description: string;\n isAutomatic: boolean;\n}\n\ninterface CartData {\n id: string;\n token: string;\n status: CartStatus;\n items: CartItemData[];\n totalItems: number;\n totalPrice: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n discountTotal: number;\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}\n\ninterface CartQueryResponse {\n cart: CartData | null;\n}\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_FRAGMENT = `\n id\n token\n status\n items {\n id\n variantId\n quantity\n priceAtAdd\n effectiveUnitPrice\n lineTotal\n taxAmount\n variant {\n id\n title\n sku\n price\n compareAtPrice\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions { id value position }\n image {\n id\n url\n altText\n position\n }\n isOnSale\n quantityPricing { minQuantity price }\n }\n }\n totalItems\n totalPrice\n taxTotal\n shippingTotal\n total\n discountTotal\n appliedPromoCode {\n code\n discountType\n discountAmount\n description\n }\n appliedDiscounts {\n promotionId\n discountClass\n discountType\n discountAmount\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`;\n\nconst CART_QUERY = `\nquery Cart {\n cart {\n ${CART_FRAGMENT}\n }\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\nconst INVALID_CART_STATES: CartStatus[] = [\"checkout\", \"converted\", \"abandoned\", \"expired\"];\n\nfunction 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 ? { ...item.variant.image, url: resolveAssetUrl(item.variant.image.url, endpoint) }\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 };\n}\n\nfunction checkCartState(status: CartStatus): Result<void, StateError> {\n if (INVALID_CART_STATES.includes(status)) {\n return err(\n new StateError(\n `Cannot modify cart in '${status}' state. Cart operations are only allowed when cart is in 'active' state.`,\n status,\n ),\n );\n }\n return ok(undefined);\n}\n\nfunction handleUserErrors(userErrors: UserError[]): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n const stateError = userErrors.find((e) => e.code?.includes(\"STATE\") || e.message.includes(\"state\"));\n\n if (stateError) {\n return new StateError(messages, \"unknown\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\n\nexport interface CartOperations {\n get(): Promise<Result<Cart | null, StorefrontError>>;\n create(): Promise<Result<Cart, StorefrontError>>;\n addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>>;\n removeItem(variantId: string): Promise<Result<Cart, StorefrontError>>;\n clear(): Promise<Result<Cart, StorefrontError>>;\n applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>>;\n removePromoCode(): Promise<Result<Cart, StorefrontError>>;\n}\n\nexport function createCartOperations(\n client: StorefrontClient,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n): CartOperations {\n return {\n async get(): Promise<Result<Cart | null, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return ok(null);\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.cart) {\n storage.remove(CART_TOKEN_KEY);\n return ok(null);\n }\n\n return ok(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 = handleUserErrors(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_TOKEN_KEY, payload.token);\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartItemAddResponse>({\n query: CART_ITEM_ADD_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: captureLandingTrackingAttribution() ?? undefined,\n },\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemAdd;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartState(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartItemUpdateResponse>({\n query: CART_ITEM_UPDATE_MUTATION,\n variables: {\n input: {\n variantId,\n quantity,\n trackingAttribution: captureLandingTrackingAttribution() ?? undefined,\n },\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemUpdate;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartState(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async removeItem(variantId: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartItemRemoveResponse>({\n query: CART_ITEM_REMOVE_MUTATION,\n variables: {\n input: {\n variantId,\n trackingAttribution: captureLandingTrackingAttribution() ?? undefined,\n },\n },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemRemove;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartState(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async clear(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartClearResponse>({\n query: CART_CLEAR_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartClear;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartState(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartPromoCodeApplyResponse>({\n query: CART_PROMO_CODE_APPLY_MUTATION,\n variables: { input: { code } },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartPromoCodeApply;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async removePromoCode(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartPromoCodeRemoveResponse>({\n query: CART_PROMO_CODE_REMOVE_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartPromoCodeRemove;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Category, FlatCategory, PaginatedResult, Product } 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 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\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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 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\nfunction isGlobalId(value: string): boolean {\n if (!value.includes(\":\")) {\n try {\n const decoded = atob(value);\n return decoded.includes(\":\");\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport interface CategoriesOperations {\n tree(): Promise<Result<Category[], StorefrontError>>;\n flat(): Promise<Result<FlatCategory[], StorefrontError>>;\n get(idOrHandle: string): Promise<Result<Category, StorefrontError>>;\n getProducts(\n idOrHandle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCategoriesOperations(client: StorefrontClient): CategoriesOperations {\n return {\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 get(idOrHandle: string): Promise<Result<Category, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CategoryQueryResponse>({\n query: useId ? CATEGORY_BY_ID_QUERY : CATEGORY_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async getProducts(\n idOrHandle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CategoryProductsQueryResponse>({\n query: useId ? CATEGORY_PRODUCTS_BY_ID_QUERY : CATEGORY_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n ...(useId ? { id: idOrHandle } : { handle: idOrHandle }),\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: ${idOrHandle}`));\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}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, ValidationError } from \"./errors.ts\";\nimport { CART_TOKEN_KEY } from \"./storage.ts\";\nimport type { Address, Cart, CartStatus, CheckoutData, Order, ProductVariant } from \"./types.ts\";\nimport { resolveAssetUrl } from \"./url.ts\";\n\ninterface UserError {\n field: string | null;\n message: string;\n code: string | null;\n}\n\ninterface CartItemData {\n id: string;\n variantId: string;\n quantity: number;\n priceAtAdd: number;\n effectiveUnitPrice: number;\n lineTotal: number;\n taxAmount: number;\n variant:\n | (Pick<\n ProductVariant,\n | \"id\"\n | \"title\"\n | \"sku\"\n | \"price\"\n | \"compareAtPrice\"\n | \"weight\"\n | \"weightUnit\"\n | \"requiresShipping\"\n | \"availableForSale\"\n | \"quantity\"\n | \"selectedOptions\"\n | \"image\"\n | \"isOnSale\"\n | \"quantityPricing\"\n > & {})\n | null;\n}\n\ninterface AppliedPromoCodeData {\n code: string;\n discountType: string;\n discountAmount: number;\n description: string;\n}\n\ninterface AppliedDiscountData {\n promotionId: string;\n discountClass: string;\n discountType: string;\n discountAmount: number;\n description: string;\n isAutomatic: boolean;\n}\n\ninterface CartData {\n id: string;\n token: string;\n status: CartStatus;\n items: CartItemData[];\n totalItems: number;\n totalPrice: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n discountTotal: number;\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}\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\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: number;\n total: number;\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 paymentInstructions: PaymentInstructionsData | null;\n userErrors: UserError[];\n };\n}\n\ninterface CheckoutAbandonResponse {\n checkoutAbandon: {\n cart: CartData | null;\n userErrors: UserError[];\n };\n}\n\nconst CART_FRAGMENT = `\n id\n token\n status\n items {\n id\n variantId\n quantity\n priceAtAdd\n effectiveUnitPrice\n lineTotal\n taxAmount\n variant {\n id\n title\n sku\n price\n compareAtPrice\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions { id value position }\n image {\n id\n url\n altText\n position\n }\n isOnSale\n quantityPricing { minQuantity price }\n }\n }\n totalItems\n totalPrice\n taxTotal\n shippingTotal\n total\n discountTotal\n appliedPromoCode {\n code\n discountType\n discountAmount\n description\n }\n appliedDiscounts {\n promotionId\n discountClass\n discountType\n discountAmount\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`;\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\n total\n note\n items {\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice\n totalPrice\n }\n createdAt\n }\n paymentInstructions {\n bankAccount\n recipientName\n referenceNumber\n ipsQrCodeBase64\n expiresAt\n }\n userErrors {\n field\n message\n code\n }\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 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 ? { ...item.variant.image, url: resolveAssetUrl(item.variant.image.url, endpoint) }\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 };\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 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 paymentInstructions: paymentInstructions ?? null,\n createdAt: data.createdAt,\n };\n}\n\nfunction handleUserErrors(userErrors: UserError[]): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n\n const stateErrorCodes = [\"CART_NOT_IN_CHECKOUT\", \"CHECKOUT_START_ERROR\", \"CHECKOUT_ABANDON_ERROR\"];\n const stateError = userErrors.find(\n (e) => e.code?.includes(\"STATE\") || e.message.includes(\"state\") || (e.code && stateErrorCodes.includes(e.code)),\n );\n\n if (stateError) {\n return new StateError(messages, \"unknown\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\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\nexport interface CheckoutOperations {\n start(): Promise<Result<Cart, StorefrontError>>;\n update(data: CheckoutData): Promise<Result<Cart, StorefrontError>>;\n complete(): Promise<Result<Order, StorefrontError>>;\n abandon(): Promise<Result<Cart, StorefrontError>>;\n}\n\nexport function createCheckoutOperations(\n client: StorefrontClient,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n): CheckoutOperations {\n return {\n async start(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutStartResponse>({\n query: CHECKOUT_START_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutStart;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async update(data: CheckoutData): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\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 client.mutate<CheckoutUpdateResponse>({\n query: CHECKOUT_UPDATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutUpdate;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartIsInCheckout(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async complete(): Promise<Result<Order, StorefrontError>> {\n const token = storage.get(CART_TOKEN_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 = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.order) {\n return err(new NotFoundError(\"Order not found\"));\n }\n\n // Clear cart token on successful order creation\n storage.remove(CART_TOKEN_KEY);\n\n return ok(mapOrderData(payload.order, payload.paymentInstructions));\n },\n\n async abandon(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutAbandonResponse>({\n query: CHECKOUT_ABANDON_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutAbandon;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { Collection, PaginatedResult, Product } 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 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 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\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\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\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\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\n compareAtPrice\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\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\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\n compareAtPrice\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\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\nfunction isGlobalId(value: string): boolean {\n if (!value.includes(\":\")) {\n try {\n const decoded = atob(value);\n return decoded.includes(\":\");\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport interface CollectionsOperations {\n list(options?: CollectionsListOptions): Promise<Result<PaginatedResult<Collection>, StorefrontError>>;\n get(idOrHandle: string): Promise<Result<Collection, StorefrontError>>;\n getProducts(\n idOrHandle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCollectionsOperations(client: StorefrontClient): CollectionsOperations {\n return {\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 get(idOrHandle: string): Promise<Result<Collection, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CollectionQueryResponse>({\n query: useId ? COLLECTION_BY_ID_QUERY : COLLECTION_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async getProducts(\n idOrHandle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CollectionProductsQueryResponse>({\n query: useId ? COLLECTION_PRODUCTS_BY_ID_QUERY : COLLECTION_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n ...(useId ? { id: idOrHandle } : { handle: idOrHandle }),\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: ${idOrHandle}`));\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}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { QueryCache } from \"./cache.ts\";\nimport {\n AuthError,\n GraphQLError,\n NetworkError,\n NotFoundError,\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 cache: QueryCache;\n cacheTTL: number;\n}\n\nexport interface GraphQLClient {\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>>;\n mutate<T>(request: GraphQLRequest): 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>(request: GraphQLRequest): 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 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 });\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 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>(request: GraphQLRequest, options?: { cache?: boolean }): 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);\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): Promise<Result<T, StorefrontError>> {\n const result = await execute<T>(request);\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<T extends { userErrors?: Array<{ field: string | null; message: string }> }>(\n data: T,\n fieldName: keyof T,\n): 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 { userErrors?: Array<{ field: string | null; message: string }>; data?: unknown };\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 { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { AvailablePaymentMethod } from \"./types.ts\";\n\ninterface AvailablePaymentMethodData {\n method: string;\n displayName: string;\n additionalFee: number;\n}\n\ninterface AvailablePaymentMethodsResponse {\n availablePaymentMethods: AvailablePaymentMethodData[];\n}\n\nconst AVAILABLE_PAYMENT_METHODS_QUERY = `\nquery AvailablePaymentMethods {\n availablePaymentMethods {\n method\n displayName\n additionalFee\n }\n}\n`;\n\nfunction mapPaymentMethod(data: AvailablePaymentMethodData): AvailablePaymentMethod {\n return {\n method: data.method,\n displayName: data.displayName,\n additionalFee: data.additionalFee,\n };\n}\n\nexport interface PaymentsOperations {\n getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>>;\n}\n\nexport function createPaymentsOperations(client: StorefrontClient): PaymentsOperations {\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\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.availablePaymentMethods) {\n return err(new NotFoundError(\"Payment methods not available\"));\n }\n\n return ok(result.value.availablePaymentMethods.map(mapPaymentMethod));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { PaginatedResult, Product, ProductFilter, ProductSortKey } from \"./types.ts\";\nimport { normalizeProductAssetUrls } from \"./url.ts\";\n\nexport interface ProductsListOptions {\n first?: number;\n after?: string;\n filter?: ProductFilter;\n sort?: ProductSortKey;\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 ProductsQueryResponse {\n products: ProductConnection;\n}\n\ninterface ProductQueryResponse {\n product: Product | null;\n}\n\ninterface ProductsByHandlesQueryResponse {\n productsByHandles: (Product | 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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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\nconst PRODUCT_BY_ID_QUERY = `\nquery ProductById($id: ID!) {\n product(id: $id) {\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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\n }\n }\n categories {\n id\n name\n handle\n description\n }\n tags {\n id\n name\n }\n }\n}\n`;\n\nfunction isGlobalId(value: string): boolean {\n if (!value.includes(\":\")) {\n try {\n const decoded = atob(value);\n return decoded.includes(\":\");\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport interface ProductsOperations {\n list(options?: ProductsListOptions): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n get(idOrHandle: string): Promise<Result<Product, StorefrontError>>;\n getByHandles(handles: string[]): Promise<Result<(Product | null)[], StorefrontError>>;\n}\n\nexport function createProductsOperations(client: StorefrontClient): ProductsOperations {\n return {\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 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 get(idOrHandle: string): Promise<Result<Product, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<ProductQueryResponse>({\n query: useId ? PRODUCT_BY_ID_QUERY : PRODUCT_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\n }\n\n return ok(normalizeProductAssetUrls(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(product, client.config.endpoint) : null,\n ),\n );\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NetworkError } from \"./errors.ts\";\nimport { captureLandingTrackingAttribution, getTrackingAttributionSnapshot } from \"./tracking-attribution.ts\";\n\nconst ANALYTICS_PATH = \"/analytics/ingest\";\nconst VISITOR_COOKIE_NAME = \"srb_vid\";\nconst SESSION_STORAGE_KEY = \"srb_sid\";\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\nconst TRACKING_SCHEMA_VERSION = 1 as const;\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;\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 =\n | \"analytics.page_view\"\n | \"analytics.product_view\"\n | \"analytics.collection_view\"\n | \"analytics.search_performed\"\n | \"analytics.add_to_cart\"\n | \"analytics.remove_from_cart\"\n | \"analytics.checkout_started\"\n | \"analytics.checkout_step_completed\"\n | \"analytics.checkout_completed\"\n | \"analytics.custom\";\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 add_to_cart: \"analytics.add_to_cart\",\n remove_from_cart: \"analytics.remove_from_cart\",\n checkout_started: \"analytics.checkout_started\",\n checkout_step_completed: \"analytics.checkout_step_completed\",\n checkout_completed: \"analytics.checkout_completed\",\n} as const;\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 | \"add_to_cart\"\n | \"remove_from_cart\"\n | \"checkout_started\"\n | \"checkout_step_completed\"\n | \"checkout_completed\";\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 | string;\nexport type AnalyticsConsentState = \"granted\" | \"denied\" | \"unknown\";\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\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\nexport interface AnalyticsEventContextPayload {\n schemaVersion: 1;\n path: string;\n}\n\ntype PresetEventProperties = {\n page_view: {};\n product_view: {\n productId: string;\n variantId?: string | null;\n };\n collection_view: {\n collectionId: string;\n };\n search_performed: {\n query: string;\n resultsCount: number;\n };\n add_to_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n };\n remove_from_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n };\n checkout_started: {\n cartId: string;\n };\n checkout_step_completed: {\n cartId: string;\n step: CheckoutStep;\n };\n checkout_completed: {\n orderId: string;\n cartId: string;\n orderTotal: number;\n };\n};\n\ntype PresetPropertiesByName<T extends AnalyticsPresetEventName> = PresetEventProperties[T];\n\ninterface NormalizedPresetEvent {\n eventType: AnalyticsEventType;\n customEventName?: string;\n}\n\n/**\n * Primitive value allowed in analytics custom event properties.\n */\nexport type AnalyticsJsonPrimitive = string | number | boolean | null;\n\n/**\n * Recursive JSON value allowed in analytics custom event properties.\n */\nexport type AnalyticsJsonValue = AnalyticsJsonPrimitive | AnalyticsJsonValue[] | { [key: string]: AnalyticsJsonValue };\n\n/**\n * Generic analytics event property bag.\n */\nexport interface AnalyticsProperties {\n [key: string]: AnalyticsJsonValue;\n}\n\n/**\n * Optional context overrides for a tracking call.\n */\nexport interface AnalyticsContext {\n storeSlug?: string;\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 AnalyticsEvent {\n schemaVersion: 1;\n eventId: string;\n eventType: AnalyticsEventType | string;\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: {\n deviceType: string;\n deviceOs: string | null;\n deviceBrowser: string | null;\n };\n properties: AnalyticsProperties;\n}\n\ninterface AnalyticsIngestPayload {\n storeSlug: string;\n events: AnalyticsEvent[];\n}\n\ninterface AddToCartProperties {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n}\n\ninterface CheckoutCompletedProperties {\n orderId: string;\n cartId: string;\n orderTotal: number;\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\ninterface AnalyticsIngestErrorResponse {\n error?: string;\n details?: { message?: string }[];\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 getSessionId(nowMs: number): string {\n const existing = getSessionStorageState();\n const state = resolveSessionState(existing, nowMs);\n setSessionStorageState(state);\n return state.id;\n}\n\nfunction normalizeNumber(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction toCents(amount: number): number {\n return Math.max(0, Math.round(normalizeNumber(amount) * 100));\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 if (isUuid(value)) return value;\n\n if (value.startsWith(\"gid://\")) {\n const parts = value.split(\"/\");\n const candidate = parts[parts.length - 1];\n return candidate && isUuid(candidate) ? candidate : null;\n }\n\n try {\n const decoded = atob(value);\n const parts = decoded.split(\":\");\n const candidate = parts[parts.length - 1];\n return candidate && isUuid(candidate) ? candidate : null;\n } catch {\n return null;\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 parseStoreSlugFromBase(basePath: string | undefined): string | null {\n if (!basePath) return null;\n\n const segments = basePath.split(\"/\").filter(Boolean);\n if (segments.length < 2) return null;\n\n const [mode, slug] = segments;\n if (mode !== \"preview\" && mode !== \"live\") return null;\n return slug ?? null;\n}\n\nfunction parseStoreSlugFromHostname(hostname: string): string | null {\n if (hostname === \"localhost\") return null;\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(hostname)) return null;\n\n const [candidate] = hostname.split(\".\");\n if (!candidate || candidate === \"www\") return null;\n return candidate;\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): AnalyticsUtm {\n const persisted = getTrackingAttributionSnapshot();\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): AnalyticsClickIds {\n const persisted = getTrackingAttributionSnapshot();\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(storeFallback?: string): AnalyticsContext {\n const context: AnalyticsContext = {};\n const device = resolveDeviceInfo();\n\n const win = getWindow();\n if (win) {\n const { pathname, search, hostname } = 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.storeSlug = parseStoreSlugFromBase(pathname) ?? parseStoreSlugFromHostname(hostname) ?? undefined;\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 if (!context.storeSlug) {\n context.storeSlug = storeFallback;\n }\n\n context.deviceOs ??= null;\n context.deviceBrowser ??= null;\n\n return context;\n}\n\nfunction normalizeEventContext(\n context: AnalyticsContext | undefined,\n storeFallback?: string,\n): { context: AnalyticsContext; storeSlug: string | null } {\n const defaults = buildDefaultContext(storeFallback);\n const merged = { ...defaults, ...context };\n\n return {\n context: merged,\n storeSlug: merged.storeSlug ?? null,\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 isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\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\nexport interface AnalyticsOperations {\n /**\n * Track an analytics event.\n *\n * Supports preset event names (`page_view`, `product_view`, `add_to_cart`, etc.),\n * canonical names (`analytics.page_view`, ...), and custom events.\n *\n * Custom event names are sent as `analytics.custom` with `eventName` included in `properties`.\n *\n * @param eventName - Preset/event-name to track.\n * @param context - Optional per-call context overrides.\n * @returns Tracking result with ingest summary, or network/validation error.\n */\n track(eventName: \"page_view\", context?: AnalyticsContext): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a product page view.\n */\n track(\n eventName: \"product_view\",\n input: PresetPropertiesByName<\"product_view\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a collection page view.\n */\n track(\n eventName: \"collection_view\",\n input: PresetPropertiesByName<\"collection_view\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track search execution.\n */\n track(\n eventName: \"search_performed\",\n input: PresetPropertiesByName<\"search_performed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track adding items to cart.\n */\n track(\n eventName: \"add_to_cart\",\n input: PresetPropertiesByName<\"add_to_cart\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track removing items from cart.\n */\n track(\n eventName: \"remove_from_cart\",\n input: PresetPropertiesByName<\"remove_from_cart\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track checkout start.\n */\n track(\n eventName: \"checkout_started\",\n input: PresetPropertiesByName<\"checkout_started\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track checkout step completion.\n */\n track(\n eventName: \"checkout_step_completed\",\n input: PresetPropertiesByName<\"checkout_step_completed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track successful checkout completion.\n */\n track(\n eventName: \"checkout_completed\",\n input: PresetPropertiesByName<\"checkout_completed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a custom analytics event.\n *\n * Example:\n * `client.analytics.track(\"homepage.hero_clicked\", { section: \"hero\", position: 1 })`\n */\n track(\n eventName: string,\n properties: AnalyticsProperties,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n}\n\n/**\n * Create analytics operations bound to a StorefrontClient.\n */\nexport function createAnalyticsOperations(client: StorefrontClient): AnalyticsOperations {\n captureLandingTrackingAttribution();\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 configStoreSlug = client.config.storeSlug;\n\n async function sendEvent(\n eventType: string,\n properties: AnalyticsProperties,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>> {\n if (!endpoint) {\n return err(new NetworkError(\"Invalid storefront endpoint\"));\n }\n\n const resolved = normalizeEventContext(context, configStoreSlug);\n const storeSlug = resolved.storeSlug;\n const eventContext = resolved.context;\n\n if (!storeSlug) {\n return err(new NetworkError(\"Missing storeSlug. Provide storeSlug in client config or event context.\"));\n }\n\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 const event: AnalyticsEvent = {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n eventId: randomUuid(),\n eventType,\n occurredAt: nowIso,\n sessionId: eventContext.sessionId ?? getSessionId(now.getTime()),\n visitorId: eventContext.visitorId ?? getOrCreateVisitorId(),\n customerId: customerId ?? null,\n consentState: eventContext.consentState ?? \"unknown\",\n context: {\n schemaVersion: TRACKING_SCHEMA_VERSION,\n path: normalizePath(eventContext.path ?? \"/\"),\n },\n referrer: eventContext.referrer ?? null,\n utm: buildUtmPayload(eventContext),\n clickIds: buildClickIdsPayload(eventContext),\n device: {\n deviceType: eventContext.deviceType ?? \"unknown\",\n deviceOs: eventContext.deviceOs ?? null,\n deviceBrowser: eventContext.deviceBrowser ?? null,\n },\n properties,\n };\n\n const payload: AnalyticsIngestPayload = {\n storeSlug,\n events: [event],\n };\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(payload),\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 return err(new NetworkError(message));\n }\n\n const parsed = (await response.json()) as unknown;\n if (!isIngestResponse(parsed)) {\n return err(new NetworkError(\"Analytics response shape is invalid\"));\n }\n\n return ok(parsed);\n } catch (error) {\n return err(\n new NetworkError(\"Failed to send analytics event\", { cause: error instanceof Error ? error : undefined }),\n );\n }\n }\n\n async function track(\n eventName: AnalyticsTrackEventName,\n eventPayload?: AnalyticsProperties | PresetPropertiesByName<AnalyticsPresetEventName> | AnalyticsContext,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>> {\n const normalized = resolveTrackEvent(eventName);\n\n if (normalized.eventType !== \"analytics.custom\") {\n switch (normalized.eventType) {\n case \"analytics.page_view\": {\n const eventContext =\n context ?? (isPlainObject(eventPayload) ? (eventPayload as AnalyticsContext) : undefined);\n return sendEvent(\"analytics.page_view\", {}, eventContext);\n }\n\n case \"analytics.product_view\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"productId is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"product_view\">;\n const decodedProductId = decodeAnalyticsEntityId(payload.productId);\n if (!decodedProductId) {\n return err(new NetworkError(\"Invalid productId\"));\n }\n\n const decodedVariantId = decodeAnalyticsEntityId(payload.variantId);\n return sendEvent(\n \"analytics.product_view\",\n { productId: decodedProductId, variantId: decodedVariantId },\n context,\n );\n }\n\n case \"analytics.collection_view\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"collectionId is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"collection_view\">;\n const decodedCollectionId = decodeAnalyticsEntityId(payload.collectionId);\n if (!decodedCollectionId) {\n return err(new NetworkError(\"Invalid collectionId\"));\n }\n\n return sendEvent(\"analytics.collection_view\", { collectionId: decodedCollectionId }, context);\n }\n\n case \"analytics.search_performed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"query is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"search_performed\">;\n const trimmed = payload.query.trim();\n if (!trimmed) {\n return err(new NetworkError(\"query is required\"));\n }\n\n return sendEvent(\n \"analytics.search_performed\",\n { query: trimmed, resultsCount: Math.max(0, Math.floor(payload.resultsCount)) },\n context,\n );\n }\n\n case \"analytics.add_to_cart\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"add_to_cart\">;\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!cartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n return sendEvent(\n \"analytics.add_to_cart\",\n {\n cartId,\n quantity: Math.max(1, Math.floor(payload.quantity)),\n itemsCount: Math.max(0, Math.floor(payload.itemsCount)),\n cartValueCents: toCents(payload.cartValue),\n },\n context,\n );\n }\n\n case \"analytics.remove_from_cart\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"remove_from_cart\">;\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!cartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n return sendEvent(\n \"analytics.remove_from_cart\",\n {\n cartId,\n quantity: Math.max(1, Math.floor(payload.quantity)),\n itemsCount: Math.max(0, Math.floor(payload.itemsCount)),\n cartValueCents: toCents(payload.cartValue),\n },\n context,\n );\n }\n\n case \"analytics.checkout_started\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_started\">;\n const decodedCartId = decodeAnalyticsEntityId(payload.cartId);\n if (!decodedCartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n return sendEvent(\"analytics.checkout_started\", { cartId: decodedCartId }, context);\n }\n\n case \"analytics.checkout_step_completed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_step_completed\">;\n const decodedCartId = decodeAnalyticsEntityId(payload.cartId);\n if (!decodedCartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n return sendEvent(\"analytics.checkout_step_completed\", { cartId: decodedCartId, step: payload.step }, context);\n }\n\n case \"analytics.checkout_completed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid orderId or cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_completed\">;\n const orderId = decodeAnalyticsEntityId(payload.orderId);\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!orderId || !cartId) {\n return err(new NetworkError(\"Invalid orderId or cartId\"));\n }\n\n return sendEvent(\n \"analytics.checkout_completed\",\n {\n orderId,\n cartId,\n orderTotalCents: toCents(payload.orderTotal),\n },\n context,\n );\n }\n }\n }\n\n const properties = isPlainObject(eventPayload) ? eventPayload : {};\n return sendEvent(\n \"analytics.custom\",\n { ...properties, eventName: normalized.customEventName ?? eventName },\n context,\n );\n }\n\n return {\n track,\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { ShippingRate } from \"./types.ts\";\n\ninterface ShippingRateData {\n id: string;\n name: string;\n price: number;\n minOrderAmount: number | 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\n minOrderAmount\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 getAvailableRates(): Promise<Result<ShippingRate[], StorefrontError>>;\n}\n\nexport function createShippingOperations(client: StorefrontClient): 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: true },\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 type { Result } from \"neverthrow\";\nimport { type AccountOperations, createAccountOperations } from \"./account.ts\";\nimport { type AuthOperations, createAuthOperations } from \"./auth.ts\";\nimport { createQueryCache, type QueryCache } from \"./cache.ts\";\nimport { type CartOperations, createCartOperations } from \"./cart.ts\";\nimport { type CategoriesOperations, createCategoriesOperations } from \"./categories.ts\";\nimport { type CheckoutOperations, createCheckoutOperations } from \"./checkout.ts\";\nimport { type CollectionsOperations, createCollectionsOperations } from \"./collections.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { createGraphQLClient, type GraphQLClient, type GraphQLRequest } from \"./graphql-client.ts\";\nimport { createPaymentsOperations, type PaymentsOperations } from \"./payments.ts\";\nimport { createProductsOperations, type ProductsOperations } from \"./products.ts\";\nimport { createAnalyticsOperations, type AnalyticsOperations } from \"./analytics.ts\";\nimport { createShippingOperations, type ShippingOperations } from \"./shipping.ts\";\nimport { CART_TOKEN_KEY, CUSTOMER_TOKEN_KEY, createDefaultAdapter } from \"./storage.ts\";\nimport type { StorageAdapter, StorefrontClientConfig } from \"./types.ts\";\n\nconst DEFAULT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport interface CacheHelpers {\n clear(): void;\n}\n\nexport interface StorefrontClient {\n readonly config: StorefrontClientConfig;\n readonly cache: CacheHelpers;\n readonly products: ProductsOperations;\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\n /**\n * Execute a GraphQL query with optional caching\n */\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>>;\n\n /**\n * Execute a GraphQL mutation (never cached)\n */\n mutate<T>(request: GraphQLRequest): Promise<Result<T, StorefrontError>>;\n\n /**\n * Get the current cart token from storage\n */\n getCartToken(): string | null;\n\n /**\n * Set the cart token in storage\n */\n setCartToken(token: string): void;\n\n /**\n * Clear the cart token from storage\n */\n clearCartToken(): void;\n\n /**\n * Get the current customer JWT token from storage\n */\n getCustomerToken(): string | null;\n\n /**\n * Set the customer JWT token in storage\n */\n setCustomerToken(token: string): void;\n\n /**\n * Clear the customer JWT token from storage\n */\n clearCustomerToken(): void;\n}\n\ninterface InternalClient extends StorefrontClient {\n readonly _graphql: GraphQLClient;\n readonly _storage: StorageAdapter;\n readonly _queryCache: QueryCache;\n}\n\nexport type { AccountOperations } from \"./account.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 { PaymentsOperations } from \"./payments.ts\";\nexport type { AnalyticsOperations } from \"./analytics.ts\";\nexport type { ProductsOperations } from \"./products.ts\";\nexport type { ShippingOperations } from \"./shipping.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://api.mystore.com/storefront\",\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 const storage = config.storage ?? createDefaultAdapter();\n const queryCache = createQueryCache();\n const cacheTTL = config.cacheTTL ?? DEFAULT_CACHE_TTL;\n\n const graphqlClient = createGraphQLClient({\n endpoint: config.endpoint,\n apiKey: config.apiKey,\n getCartToken: () => storage.get(CART_TOKEN_KEY),\n getCustomerToken: () => storage.get(CUSTOMER_TOKEN_KEY),\n cache: queryCache,\n cacheTTL,\n });\n\n const client: InternalClient = {\n config,\n _graphql: graphqlClient,\n _storage: storage,\n _queryCache: queryCache,\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 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\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>> {\n return graphqlClient.query<T>(request, options);\n },\n\n mutate<T>(request: GraphQLRequest): Promise<Result<T, StorefrontError>> {\n return graphqlClient.mutate<T>(request);\n },\n\n getCartToken(): string | null {\n return storage.get(CART_TOKEN_KEY);\n },\n\n setCartToken(token: string): void {\n storage.set(CART_TOKEN_KEY, token);\n },\n\n clearCartToken(): void {\n storage.remove(CART_TOKEN_KEY);\n },\n\n getCustomerToken(): string | null {\n return storage.get(CUSTOMER_TOKEN_KEY);\n },\n\n setCustomerToken(token: string): void {\n storage.set(CUSTOMER_TOKEN_KEY, token);\n },\n\n clearCustomerToken(): void {\n storage.remove(CUSTOMER_TOKEN_KEY);\n },\n };\n\n // Create operations after client is created to avoid circular reference\n (client as { products: ProductsOperations }).products = createProductsOperations(client);\n (client as { collections: CollectionsOperations }).collections = createCollectionsOperations(client);\n (client as { categories: CategoriesOperations }).categories = createCategoriesOperations(client);\n (client as { cart: CartOperations }).cart = createCartOperations(client, storage);\n (client as { checkout: CheckoutOperations }).checkout = createCheckoutOperations(client, storage);\n (client as { payments: PaymentsOperations }).payments = createPaymentsOperations(client);\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 { analytics: AnalyticsOperations }).analytics = createAnalyticsOperations(client);\n\n return client;\n}\n"],"names":["handleUserErrors","ValidationError","err","AuthError","ok","TRACKING_SCHEMA_VERSION","hasBrowserContext","CART_FRAGMENT","mapCartData","StateError","NotFoundError","isGlobalId","GraphQLError","errors","NetworkError"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwFvB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwE5B,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwEhC,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/cache.ts","../src/storage.ts","../src/account.ts","../src/auth.ts","../src/url.ts","../src/cart-shared.ts","../src/tracking-attribution.ts","../src/cart.ts","../src/global-id.ts","../src/categories.ts","../src/analytics-retry-queue.ts","../../../shared/tracking-policy/src/policy.ts","../src/tracking-runtime.ts","../src/analytics.ts","../src/checkout.ts","../src/collections.ts","../src/graphql-client.ts","../src/payments.ts","../src/products.ts","../src/shipping.ts","../src/store.ts","../src/client.ts","../src/browser-helpers.ts","../src/gtm-browser-adapter.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\nexport const CART_TOKEN_KEY = \"ekomerc_cart_token\";\nexport const CUSTOMER_TOKEN_KEY = \"ekomerc_customer_token\";\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 localStorage !== \"undefined\") {\n return createLocalStorageAdapter();\n }\n return createMemoryAdapter();\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { AuthError, ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_TOKEN_KEY } from \"./storage.ts\";\nimport type {\n Customer,\n CustomerAddress,\n CustomerAddressInput,\n CustomerAddressUpdateInput,\n CustomerOrder,\n CustomerUpdateInput,\n PaginatedResult,\n StorageAdapter,\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: number;\n totalPrice: number;\n}\n\ninterface OrderNodeData {\n id: string;\n orderNumber: string;\n status: string;\n customerEmail: string;\n customerPhone: string | null;\n subtotal: number;\n total: number;\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\n totalPrice\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\n total\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: String!, $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: String!) {\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 handleUserErrors(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: StorefrontClient, storage: StorageAdapter): AccountOperations {\n function requireAuth(): Result<void, AuthError> {\n if (!storage.get(CUSTOMER_TOKEN_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 = handleUserErrors(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 = handleUserErrors(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 = handleUserErrors(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 = handleUserErrors(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","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { ValidationError } from \"./errors.ts\";\nimport { CUSTOMER_TOKEN_KEY } from \"./storage.ts\";\nimport type { Customer, StorageAdapter } 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 CustomerVerifyEmailResponse {\n customerVerifyEmail: {\n customer: CustomerData | null;\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 CUSTOMER_VERIFY_EMAIL_MUTATION = `\nmutation CustomerVerifyEmail($input: CustomerVerifyEmailInput!) {\n customerVerifyEmail(input: $input) {\n customer { ${CUSTOMER_FRAGMENT} }\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 handleUserErrors(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 AuthOperations {\n /**\n * Register a customer account and store the returned auth token.\n *\n * @param input - Registration credentials and optional name.\n * @returns The authenticated customer and token.\n */\n register(input: {\n email: string;\n password: string;\n name?: string;\n }): Promise<Result<{ customer: Customer; token: string }, 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.\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 * Verify a customer email address with a verification token.\n *\n * @param token - Verification token from email.\n * @returns The verified customer.\n */\n verifyEmail(token: string): Promise<Result<Customer, 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: StorefrontClient, 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 = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer || !payload.token) {\n return err(new ValidationError(\"Registration failed\", []));\n }\n\n storage.set(CUSTOMER_TOKEN_KEY, payload.token);\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 = handleUserErrors(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_TOKEN_KEY, payload.token);\n return ok({ customer: mapCustomerData(payload.customer), token: payload.token });\n },\n\n logout() {\n storage.remove(CUSTOMER_TOKEN_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 = handleUserErrors(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 = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n return ok({ success: payload.success });\n },\n\n async verifyEmail(token) {\n const result = await client.mutate<CustomerVerifyEmailResponse>({\n query: CUSTOMER_VERIFY_EMAIL_MUTATION,\n variables: { input: { token } },\n });\n\n if (result.isErr()) return err(result.error);\n\n const payload = result.value.customerVerifyEmail;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) return err(userError);\n\n if (!payload.customer) {\n return err(new ValidationError(\"Email verification failed\", []));\n }\n\n return ok(mapCustomerData(payload.customer));\n },\n\n async me() {\n if (!storage.get(CUSTOMER_TOKEN_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_TOKEN_KEY) !== null;\n },\n };\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 })),\n variants: product.variants.map((variant) => ({\n ...variant,\n image: variant.image\n ? {\n ...variant.image,\n url: resolveAssetUrl(variant.image.url, 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 ? { ...collection.imageAsset, url: resolveAssetUrl(collection.imageAsset.url, endpoint) }\n : null,\n };\n}\n","import type { Address, Cart, CartStatus, 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: number;\n effectiveUnitPrice: number;\n lineTotal: number;\n taxAmount: number;\n variant:\n | (Pick<\n ProductVariant,\n | \"id\"\n | \"title\"\n | \"sku\"\n | \"price\"\n | \"compareAtPrice\"\n | \"weight\"\n | \"weightUnit\"\n | \"requiresShipping\"\n | \"availableForSale\"\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: number;\n description: string;\n}\n\nexport interface AppliedDiscountData {\n promotionId: string;\n discountClass: string;\n discountType: string;\n discountAmount: number;\n description: string;\n isAutomatic: boolean;\n}\n\nexport interface CartData {\n id: string;\n token: string;\n status: CartStatus;\n items: CartItemData[];\n totalItems: number;\n totalPrice: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n discountTotal: number;\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}\n\nexport const CART_FRAGMENT = `\n id\n token\n status\n items {\n id\n variantId\n quantity\n priceAtAdd\n effectiveUnitPrice\n lineTotal\n taxAmount\n variant {\n id\n title\n sku\n price\n compareAtPrice\n weight\n weightUnit\n requiresShipping\n availableForSale\n quantity\n selectedOptions { id value position }\n image {\n id\n url\n altText\n position\n }\n isOnSale\n quantityPricing { minQuantity price }\n }\n }\n totalItems\n totalPrice\n taxTotal\n shippingTotal\n total\n discountTotal\n appliedPromoCode {\n code\n discountType\n discountAmount\n description\n }\n appliedDiscounts {\n promotionId\n discountClass\n discountType\n discountAmount\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`;\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 ? { ...item.variant.image, url: resolveAssetUrl(item.variant.image.url, endpoint) }\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 };\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\ninterface TrackingUtmSnapshot {\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\ninterface TrackingClickIdsSnapshot {\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\nexport interface TrackingAttributionSnapshot {\n schemaVersion: 1;\n capturedAt: string;\n utm: TrackingUtmSnapshot;\n clickIds: TrackingClickIdsSnapshot;\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\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\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 { err, ok, type Result } from \"neverthrow\";\nimport { CART_FRAGMENT, type CartData, mapCartData, type UserError } from \"./cart-shared.ts\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, ValidationError } from \"./errors.ts\";\nimport { CART_TOKEN_KEY } from \"./storage.ts\";\nimport { captureLandingTrackingAttribution } from \"./tracking-attribution.ts\";\nimport type { Cart } from \"./types.ts\";\n\ninterface CartQueryResponse {\n cart: CartData | null;\n}\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_QUERY = `\nquery Cart {\n cart {\n ${CART_FRAGMENT}\n }\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\nfunction handleUserErrors(userErrors: UserError[]): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n const stateError = userErrors.find((e) => e.code?.includes(\"STATE\") || e.message.includes(\"state\"));\n\n if (stateError) {\n return new StateError(messages, \"unknown\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\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 GID (global ID).\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 GID (global ID).\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 GID (global ID).\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\nexport function createCartOperations(\n client: StorefrontClient,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n): CartOperations {\n function getTrackingAttribution() {\n return (\n captureLandingTrackingAttribution({\n ttlMs: client.config.trackingAttributionTTL,\n }) ?? undefined\n );\n }\n\n return {\n async get(): Promise<Result<Cart | null, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return ok(null);\n }\n\n const result = await client.query<CartQueryResponse>({ query: CART_QUERY }, { cache: false });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.cart) {\n storage.remove(CART_TOKEN_KEY);\n return ok(null);\n }\n\n return ok(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 = handleUserErrors(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_TOKEN_KEY, payload.token);\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async addItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\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\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemAdd;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async updateItem(variantId: string, quantity: number): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\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\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemUpdate;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async removeItem(variantId: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\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\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartItemRemove;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async clear(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartClearResponse>({\n query: CART_CLEAR_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartClear;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async applyPromoCode(code: string): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartPromoCodeApplyResponse>({\n query: CART_PROMO_CODE_APPLY_MUTATION,\n variables: { input: { code } },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartPromoCodeApply;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async removePromoCode(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CartPromoCodeRemoveResponse>({\n query: CART_PROMO_CODE_REMOVE_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.cartPromoCodeRemove;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n };\n}\n","export function isGlobalId(value: string): boolean {\n if (!value.includes(\":\")) {\n try {\n const decoded = atob(value);\n return decoded.includes(\":\");\n } catch {\n return false;\n }\n }\n\n return false;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { isGlobalId } from \"./global-id.ts\";\nimport type { Category, FlatCategory, PaginatedResult, Product } 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 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\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: GID!) {\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: GID!, $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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 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 /**\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 GID or handle.\n *\n * @param idOrHandle - Category GID or handle.\n * @returns The matching category.\n */\n get(idOrHandle: string): Promise<Result<Category, StorefrontError>>;\n /**\n * Fetch products assigned to a category.\n *\n * @param idOrHandle - Category GID or handle.\n * @param options - Pagination and descendant-inclusion options.\n * @returns Paginated products for the category.\n */\n getProducts(\n idOrHandle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCategoriesOperations(client: StorefrontClient): CategoriesOperations {\n return {\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 get(idOrHandle: string): Promise<Result<Category, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CategoryQueryResponse>({\n query: useId ? CATEGORY_BY_ID_QUERY : CATEGORY_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\n }\n\n return ok(mapRawCategory(result.value.storefrontCategory, client.config.endpoint));\n },\n\n async getProducts(\n idOrHandle: string,\n options?: CategoryProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CategoryProductsQueryResponse>({\n query: useId ? CATEGORY_PRODUCTS_BY_ID_QUERY : CATEGORY_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n ...(useId ? { id: idOrHandle } : { handle: idOrHandle }),\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: ${idOrHandle}`));\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}\n","import type { StorageAdapter } from \"./types.ts\";\nimport type { AnalyticsBrowserEvent, AnalyticsDiagnostic } from \"./tracking-runtime.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","export const TRACKING_POLICY_EVENT_TYPES = [\n \"analytics.page_view\",\n \"analytics.product_view\",\n \"analytics.collection_view\",\n \"analytics.search_performed\",\n \"analytics.add_to_cart\",\n \"analytics.remove_from_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 \"add_to_cart\",\n \"remove_from_cart\",\n \"begin_checkout\",\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 \"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.add_to_cart\": \"add_to_cart\",\n \"analytics.remove_from_cart\": \"remove_from_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.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_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.add_to_cart\": \"AddToCart\",\n \"analytics.remove_from_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","import {\n providerSupportsTrackingEvent,\n type TrackingPolicyEventType,\n type TrackingProvider,\n} from \"@ekomerc/tracking-policy\";\n\nexport const TRACKING_SCHEMA_VERSION = 1 as const;\n\n/**\n * Consent states emitted with browser-side analytics events.\n */\nexport type AnalyticsConsentState = \"granted\" | \"denied\" | \"unknown\";\n\n/**\n * Runtime policies controlling how consent gates browser event dispatch.\n */\nexport type AnalyticsDispatchOnUnknownConsent = boolean;\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 dispatchOnUnknownConsent: AnalyticsDispatchOnUnknownConsent;\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 = void | { status: \"success\" } | 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 dispatchOnUnknownConsent?: AnalyticsDispatchOnUnknownConsent;\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 */\nexport function shouldDispatchForTrackingConsent(input: AnalyticsConsentUpdate): boolean {\n if (input.consentState === \"granted\") {\n return true;\n }\n\n if (input.consentState === \"denied\") {\n return false;\n }\n\n return input.dispatchOnUnknownConsent;\n}\n\n/**\n * Returns whether a provider can receive the requested event under the current consent policy.\n */\nexport function shouldDispatchBrowserAdapter(\n provider: TrackingProvider,\n eventType: TrackingPolicyEventType,\n consent: AnalyticsConsentUpdate,\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(consent)) {\n return { allowed: false, reason: \"consent_blocked\" };\n }\n\n return { allowed: true };\n}\n","import 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 { StorefrontClient } from \"./client.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 AnalyticsDispatchOnUnknownConsent,\n type AnalyticsProperties,\n type AnalyticsUtm,\n shouldDispatchBrowserAdapter,\n TRACKING_SCHEMA_VERSION,\n} from \"./tracking-runtime.ts\";\nimport type { ResolvedStorefrontAnalyticsConfig, StorageAdapter, StorefrontAnalyticsInitConfig } 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 AnalyticsDispatchOnUnknownConsent,\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 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 | \"add_to_cart\"\n | \"remove_from_cart\"\n | \"checkout_started\"\n | \"checkout_step_completed\"\n | \"checkout_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 add_to_cart: \"analytics.add_to_cart\",\n remove_from_cart: \"analytics.remove_from_cart\",\n checkout_started: \"analytics.checkout_started\",\n checkout_step_completed: \"analytics.checkout_step_completed\",\n checkout_completed: \"analytics.checkout_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 };\n collection_view: {\n collectionId: string;\n };\n search_performed: {\n query: string;\n resultsCount: number;\n };\n add_to_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n };\n remove_from_cart: {\n cartId: string;\n quantity: number;\n itemsCount: number;\n cartValue: number;\n };\n checkout_started: {\n cartId: string;\n };\n checkout_step_completed: {\n cartId: string;\n step: CheckoutStep;\n };\n checkout_completed: {\n orderId: string;\n cartId: string;\n orderTotal: number;\n };\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: number;\n lineTotal: number;\n}\n\nexport interface ConfirmedPurchaseTrackingPayload {\n eventId: string;\n orderId: string;\n cartId: string;\n total: 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 normalizeNumber(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction toCents(amount: number): number {\n return Math.max(0, Math.round(normalizeNumber(amount) * 100));\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 if (isUuid(value)) return value;\n\n if (value.startsWith(\"gid://\")) {\n const parts = value.split(\"/\");\n const candidate = parts[parts.length - 1];\n return candidate && isUuid(candidate) ? candidate : null;\n }\n\n try {\n const decoded = atob(value);\n const parts = decoded.split(\":\");\n const candidate = parts[parts.length - 1];\n return candidate && isUuid(candidate) ? candidate : null;\n } catch {\n return null;\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 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 dispatchOnUnknownConsent?: AnalyticsDispatchOnUnknownConsent;\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): void {\n const adapters = (runtime?.adapters ?? []).filter(\n (adapter) => adapter.provider !== \"gtm\" || resolvedAnalytics.gtm.enabled,\n );\n if (adapters.length === 0) {\n return;\n }\n\n const consent: AnalyticsConsentUpdate = {\n consentState: event.consentState,\n dispatchOnUnknownConsent: runtime?.dispatchOnUnknownConsent ?? true,\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 dispatchDecision = shouldDispatchBrowserAdapter(adapter.provider, event.eventType, consent);\n if (!dispatchDecision.allowed) {\n emitDiagnostic({\n target: \"adapter\",\n status: \"skipped\",\n provider: adapter.provider,\n event,\n reason: dispatchDecision.reason,\n });\n continue;\n }\n\n try {\n const result = await adapter.dispatch({ event, consent });\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 } 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\nfunction shouldMirrorEventToBrowserRuntime(eventType: AnalyticsEventType): boolean {\n // Generic track(\"checkout_completed\") remains ingest-only.\n return eventType !== \"analytics.checkout_completed\";\n}\n\nexport interface AnalyticsOperations {\n /**\n * Track an analytics event.\n *\n * Supports preset event names (`page_view`, `product_view`, `add_to_cart`, etc.),\n * canonical names (`analytics.page_view`, ...), and custom events.\n *\n * Custom event names are sent as `analytics.custom` with `eventName` included in `properties`.\n *\n * @param eventName - Preset/event-name to track.\n * @param context - Optional per-call context overrides.\n * @returns Tracking result with ingest summary, or network/validation error.\n */\n track(eventName: \"page_view\", context?: AnalyticsContext): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a product page view.\n */\n track(\n eventName: \"product_view\",\n input: PresetPropertiesByName<\"product_view\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a collection page view.\n */\n track(\n eventName: \"collection_view\",\n input: PresetPropertiesByName<\"collection_view\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track search execution.\n */\n track(\n eventName: \"search_performed\",\n input: PresetPropertiesByName<\"search_performed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track adding items to cart.\n */\n track(\n eventName: \"add_to_cart\",\n input: PresetPropertiesByName<\"add_to_cart\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track removing items from cart.\n */\n track(\n eventName: \"remove_from_cart\",\n input: PresetPropertiesByName<\"remove_from_cart\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track checkout start.\n */\n track(\n eventName: \"checkout_started\",\n input: PresetPropertiesByName<\"checkout_started\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track checkout step completion.\n */\n track(\n eventName: \"checkout_step_completed\",\n input: PresetPropertiesByName<\"checkout_step_completed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track successful checkout completion.\n */\n track(\n eventName: \"checkout_completed\",\n input: PresetPropertiesByName<\"checkout_completed\">,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n /**\n * Track a custom analytics event.\n *\n * Example:\n * `client.analytics.track(\"homepage.hero_clicked\", { section: \"hero\", position: 1 })`\n */\n track(\n eventName: string,\n properties: AnalyticsProperties,\n context?: AnalyticsContext,\n ): Promise<Result<AnalyticsIngestResponse, StorefrontError>>;\n}\n\ninterface AnalyticsController extends AnalyticsOperations {\n init(input?: ResolvedStorefrontAnalyticsConfig | AnalyticsInitOptions): void;\n}\n\ninterface AnalyticsRuntimeClient extends StorefrontClient {\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(\n input && typeof input === \"object\" && \"enabled\" in input && \"dispatchOnUnknownConsent\" in input && \"gtm\" in input,\n );\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 dispatchOnUnknownConsent: runtime?.dispatchOnUnknownConsent ?? 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(client: StorefrontClient, storage: StorageAdapter): AnalyticsController {\n const trackingAttributionTtlMs = client.config.trackingAttributionTTL;\n const runtimeClient = client as AnalyticsRuntimeClient;\n let lifecycleFlushListenersRegistered = 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 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 \"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 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 captureLandingTrackingAttribution({ ttlMs: trackingAttributionTtlMs });\n if (getTrackingRuntime()?.stripUrl !== false) {\n stripLandingTrackingAttributionFromUrl();\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 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 switch (normalized.eventType) {\n case \"analytics.page_view\": {\n eventType = \"analytics.page_view\";\n properties = {};\n eventContext = eventContext ?? (isPlainObject(eventPayload) ? (eventPayload as AnalyticsContext) : undefined);\n break;\n }\n\n case \"analytics.product_view\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"productId is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"product_view\">;\n const decodedProductId = decodeAnalyticsEntityId(payload.productId);\n if (!decodedProductId) {\n return err(new NetworkError(\"Invalid productId\"));\n }\n\n const decodedVariantId = decodeAnalyticsEntityId(payload.variantId);\n eventType = \"analytics.product_view\";\n properties = { productId: decodedProductId, variantId: decodedVariantId };\n break;\n }\n\n case \"analytics.collection_view\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"collectionId is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"collection_view\">;\n const decodedCollectionId = decodeAnalyticsEntityId(payload.collectionId);\n if (!decodedCollectionId) {\n return err(new NetworkError(\"Invalid collectionId\"));\n }\n\n eventType = \"analytics.collection_view\";\n properties = { collectionId: decodedCollectionId };\n break;\n }\n\n case \"analytics.search_performed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"query is required\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"search_performed\">;\n const trimmed = payload.query.trim();\n if (!trimmed) {\n return err(new NetworkError(\"query is required\"));\n }\n\n eventType = \"analytics.search_performed\";\n properties = { query: trimmed, resultsCount: Math.max(0, Math.floor(payload.resultsCount)) };\n break;\n }\n\n case \"analytics.add_to_cart\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"add_to_cart\">;\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!cartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n eventType = \"analytics.add_to_cart\";\n properties = {\n cartId,\n quantity: Math.max(1, Math.floor(payload.quantity)),\n itemsCount: Math.max(0, Math.floor(payload.itemsCount)),\n cartValueCents: toCents(payload.cartValue),\n };\n break;\n }\n\n case \"analytics.remove_from_cart\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"remove_from_cart\">;\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!cartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n eventType = \"analytics.remove_from_cart\";\n properties = {\n cartId,\n quantity: Math.max(1, Math.floor(payload.quantity)),\n itemsCount: Math.max(0, Math.floor(payload.itemsCount)),\n cartValueCents: toCents(payload.cartValue),\n };\n break;\n }\n\n case \"analytics.checkout_started\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_started\">;\n const decodedCartId = decodeAnalyticsEntityId(payload.cartId);\n if (!decodedCartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n eventType = \"analytics.checkout_started\";\n properties = { cartId: decodedCartId };\n break;\n }\n\n case \"analytics.checkout_step_completed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_step_completed\">;\n const decodedCartId = decodeAnalyticsEntityId(payload.cartId);\n if (!decodedCartId) {\n return err(new NetworkError(\"Invalid cartId\"));\n }\n\n eventType = \"analytics.checkout_step_completed\";\n properties = { cartId: decodedCartId, step: payload.step };\n break;\n }\n\n case \"analytics.checkout_completed\": {\n if (!isPlainObject(eventPayload)) {\n return err(new NetworkError(\"Invalid orderId or cartId\"));\n }\n\n const payload = eventPayload as PresetPropertiesByName<\"checkout_completed\">;\n const orderId = decodeAnalyticsEntityId(payload.orderId);\n const cartId = decodeAnalyticsEntityId(payload.cartId);\n if (!orderId || !cartId) {\n return err(new NetworkError(\"Invalid orderId or cartId\"));\n }\n\n eventType = \"analytics.checkout_completed\";\n properties = {\n orderId,\n cartId,\n orderTotalCents: toCents(payload.orderTotal),\n };\n break;\n }\n }\n } else {\n eventType = \"analytics.custom\";\n properties = {\n ...(isPlainObject(eventPayload) ? eventPayload : {}),\n eventName: normalized.customEventName ?? eventName,\n };\n }\n\n const normalizedContext = normalizeEventContext(eventContext);\n const resolvedAnalytics = getResolvedAnalyticsConfig() ?? buildDefaultResolvedAnalyticsConfig(getTrackingRuntime());\n if (!resolvedAnalytics.enabled) {\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 if (shouldMirrorEventToBrowserRuntime(event.eventType)) {\n dispatchEventToBrowserRuntime(trackingRuntime, event, resolvedAnalytics, emitDiagnostic, scheduleBestEffort);\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 return {\n init,\n track,\n };\n}\n\nexport function dispatchConfirmedPurchaseBrowserEvent(\n client: StorefrontClient,\n purchaseTracking: ConfirmedPurchaseTrackingPayload,\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 \"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 function buildLineItemsPayload(lineItems: ConfirmedPurchaseTrackingLineItem[]): AnalyticsProperties[\"lineItems\"] {\n return lineItems.map((item) => ({\n id: item.contentId,\n content_id: item.contentId,\n productId: item.productId,\n variantId: item.variantId,\n sku: item.sku,\n productTitle: item.productTitle,\n variantTitle: item.variantTitle,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n unitPriceCents: toCents(item.unitPrice),\n lineTotal: item.lineTotal,\n lineTotalCents: toCents(item.lineTotal),\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: {\n orderId: purchaseTracking.orderId,\n cartId: purchaseTracking.cartId,\n orderTotalCents: toCents(purchaseTracking.total),\n totalCents: toCents(purchaseTracking.total),\n currency: purchaseTracking.currency,\n numItems: purchaseTracking.numItems,\n lineItems: buildLineItemsPayload(purchaseTracking.lineItems),\n },\n };\n\n dispatchEventToBrowserRuntime(runtime, event, resolvedAnalytics, emitDiagnostic, scheduleBestEffort);\n });\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { dispatchConfirmedPurchaseBrowserEvent, type ConfirmedPurchaseTrackingPayload } from \"./analytics.ts\";\nimport { CART_FRAGMENT, type CartData, mapCartData, type UserError } from \"./cart-shared.ts\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError, StateError, ValidationError } from \"./errors.ts\";\nimport { CART_TOKEN_KEY } from \"./storage.ts\";\nimport type { Address, Cart, CartStatus, CheckoutData, Order } from \"./types.ts\";\n\ninterface OrderItemData {\n id: string;\n productTitle: string;\n variantTitle: string | null;\n sku: string | null;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\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: number;\n total: number;\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 paymentInstructions: PaymentInstructionsData | null;\n purchaseTracking: ConfirmedPurchaseTrackingPayload | null;\n userErrors: UserError[];\n };\n}\n\nconst CHECKOUT_PURCHASE_DISPATCH_IDS_KEY = \"ekomerc_checkout_purchase_dispatch_ids\";\nconst MAX_STORED_PURCHASE_DISPATCH_IDS = 20;\n\ninterface CheckoutAbandonResponse {\n checkoutAbandon: {\n cart: CartData | null;\n userErrors: UserError[];\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\n total\n note\n items {\n id\n productTitle\n variantTitle\n sku\n quantity\n unitPrice\n totalPrice\n }\n createdAt\n }\n paymentInstructions {\n bankAccount\n recipientName\n referenceNumber\n ipsQrCodeBase64\n expiresAt\n }\n purchaseTracking {\n eventId\n orderId\n cartId\n total\n currency\n numItems\n lineItems {\n contentId\n productId\n variantId\n sku\n productTitle\n variantTitle\n quantity\n unitPrice\n lineTotal\n }\n }\n userErrors {\n field\n message\n code\n }\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 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 paymentInstructions: paymentInstructions ?? null,\n createdAt: data.createdAt,\n };\n}\n\nfunction handleUserErrors(userErrors: UserError[]): ValidationError | StateError | null {\n if (userErrors.length === 0) return null;\n\n const messages = userErrors.map((e) => e.message).join(\"; \");\n\n const stateErrorCodes = [\"CART_NOT_IN_CHECKOUT\", \"CHECKOUT_START_ERROR\", \"CHECKOUT_ABANDON_ERROR\"];\n const stateError = userErrors.find(\n (e) => e.code?.includes(\"STATE\") || e.message.includes(\"state\") || (e.code && stateErrorCodes.includes(e.code)),\n );\n\n if (stateError) {\n return new StateError(messages, \"unknown\");\n }\n\n return new ValidationError(\n messages,\n userErrors.map((e) => ({ field: e.field, message: e.message })),\n );\n}\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 readHandledPurchaseDispatchIds(storage: { get(key: string): string | null }): string[] {\n const raw = storage.get(CHECKOUT_PURCHASE_DISPATCH_IDS_KEY);\n if (!raw) {\n return [];\n }\n\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n return parsed.filter((value): value is string => typeof value === \"string\" && value.length > 0);\n } catch {\n return [];\n }\n}\n\nfunction hasHandledPurchaseDispatch(storage: { get(key: string): string | null }, eventId: string): boolean {\n return readHandledPurchaseDispatchIds(storage).includes(eventId);\n}\n\nfunction markPurchaseDispatchHandled(\n storage: { get(key: string): string | null; set(key: string, value: string): void },\n eventId: string,\n): void {\n const next = [eventId, ...readHandledPurchaseDispatchIds(storage).filter((value) => value !== eventId)].slice(\n 0,\n MAX_STORED_PURCHASE_DISPATCH_IDS,\n );\n storage.set(CHECKOUT_PURCHASE_DISPATCH_IDS_KEY, JSON.stringify(next));\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 * @returns The created order.\n */\n complete(): Promise<Result<Order, 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\nexport function createCheckoutOperations(\n client: StorefrontClient,\n storage: { get(key: string): string | null; set(key: string, value: string): void; remove(key: string): void },\n): CheckoutOperations {\n return {\n async start(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutStartResponse>({\n query: CHECKOUT_START_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutStart;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async update(data: CheckoutData): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\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 client.mutate<CheckoutUpdateResponse>({\n query: CHECKOUT_UPDATE_MUTATION,\n variables: { input },\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutUpdate;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n const stateCheck = checkCartIsInCheckout(payload.cart.status);\n if (stateCheck.isErr()) {\n return err(stateCheck.error);\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n\n async complete(): Promise<Result<Order, StorefrontError>> {\n const token = storage.get(CART_TOKEN_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 = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.order) {\n return err(new NotFoundError(\"Order not found\"));\n }\n\n // Clear cart token on successful order creation\n storage.remove(CART_TOKEN_KEY);\n if (payload.purchaseTracking) {\n const confirmedPurchaseTracking: ConfirmedPurchaseTrackingPayload = {\n ...payload.purchaseTracking,\n eventId: payload.purchaseTracking.orderId,\n };\n if (!hasHandledPurchaseDispatch(storage, confirmedPurchaseTracking.eventId)) {\n markPurchaseDispatchHandled(storage, confirmedPurchaseTracking.eventId);\n dispatchConfirmedPurchaseBrowserEvent(client, confirmedPurchaseTracking);\n }\n }\n\n return ok(mapOrderData(payload.order, payload.paymentInstructions));\n },\n\n async abandon(): Promise<Result<Cart, StorefrontError>> {\n const token = storage.get(CART_TOKEN_KEY);\n if (!token) {\n return err(new NotFoundError(\"No cart exists. Call cart.create() first.\"));\n }\n\n const result = await client.mutate<CheckoutAbandonResponse>({\n query: CHECKOUT_ABANDON_MUTATION,\n });\n\n if (result.isErr()) {\n return err(result.error);\n }\n\n const payload = result.value.checkoutAbandon;\n const userError = handleUserErrors(payload.userErrors);\n if (userError) {\n return err(userError);\n }\n\n if (!payload.cart) {\n return err(new NotFoundError(\"Cart not found\"));\n }\n\n return ok(mapCartData(payload.cart, client.config.endpoint));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { isGlobalId } from \"./global-id.ts\";\nimport type { Collection, PaginatedResult, Product } 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 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 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\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: GID!) {\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\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\n altText\n width\n height\n }\n }\n}\n`;\n\nconst COLLECTION_PRODUCTS_BY_ID_QUERY = `\nquery CollectionProductsById($id: GID!, $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\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\n compareAtPrice\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\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\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\n compareAtPrice\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\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 /**\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 GID or handle.\n *\n * @param idOrHandle - Collection GID or handle.\n * @returns The matching collection.\n */\n get(idOrHandle: string): Promise<Result<Collection, StorefrontError>>;\n /**\n * Fetch products that belong to a collection.\n *\n * @param idOrHandle - Collection GID or handle.\n * @param options - Pagination and collection product options.\n * @returns Paginated products for the collection.\n */\n getProducts(\n idOrHandle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>>;\n}\n\nexport function createCollectionsOperations(client: StorefrontClient): CollectionsOperations {\n return {\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 get(idOrHandle: string): Promise<Result<Collection, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CollectionQueryResponse>({\n query: useId ? COLLECTION_BY_ID_QUERY : COLLECTION_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\n }\n\n const collection = mapRawCollection(result.value.collection, client.config.endpoint);\n return ok(normalizeCollectionAssetUrls(collection, client.config.endpoint));\n },\n\n async getProducts(\n idOrHandle: string,\n options?: CollectionProductsOptions,\n ): Promise<Result<PaginatedResult<Product>, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<CollectionProductsQueryResponse>({\n query: useId ? COLLECTION_PRODUCTS_BY_ID_QUERY : COLLECTION_PRODUCTS_BY_HANDLE_QUERY,\n variables: {\n ...(useId ? { id: idOrHandle } : { handle: idOrHandle }),\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: ${idOrHandle}`));\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}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { QueryCache } from \"./cache.ts\";\nimport {\n AuthError,\n GraphQLError,\n NetworkError,\n NotFoundError,\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 cache: QueryCache;\n cacheTTL: number;\n}\n\nexport interface GraphQLClient {\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>>;\n mutate<T>(request: GraphQLRequest): 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>(request: GraphQLRequest): 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 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 });\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 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>(request: GraphQLRequest, options?: { cache?: boolean }): 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);\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): Promise<Result<T, StorefrontError>> {\n const result = await execute<T>(request);\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<T extends { userErrors?: Array<{ field: string | null; message: string }> }>(\n data: T,\n fieldName: keyof T,\n): 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 { userErrors?: Array<{ field: string | null; message: string }>; data?: unknown };\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 { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { AvailablePaymentMethod } from \"./types.ts\";\n\ninterface AvailablePaymentMethodData {\n method: string;\n displayName: string;\n additionalFee: number;\n}\n\ninterface AvailablePaymentMethodsResponse {\n availablePaymentMethods: AvailablePaymentMethodData[];\n}\n\nconst AVAILABLE_PAYMENT_METHODS_QUERY = `\nquery AvailablePaymentMethods {\n availablePaymentMethods {\n method\n displayName\n additionalFee\n }\n}\n`;\n\nfunction mapPaymentMethod(data: AvailablePaymentMethodData): AvailablePaymentMethod {\n return {\n method: data.method,\n displayName: data.displayName,\n additionalFee: data.additionalFee,\n };\n}\n\nexport interface PaymentsOperations {\n /**\n * Fetch payment methods currently available for checkout.\n *\n * @returns Available storefront payment methods.\n */\n getAvailableMethods(): Promise<Result<AvailablePaymentMethod[], StorefrontError>>;\n}\n\nexport function createPaymentsOperations(client: StorefrontClient): PaymentsOperations {\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\n if (result.isErr()) {\n return err(result.error);\n }\n\n if (!result.value.availablePaymentMethods) {\n return err(new NotFoundError(\"Payment methods not available\"));\n }\n\n return ok(result.value.availablePaymentMethods.map(mapPaymentMethod));\n },\n };\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport { isGlobalId } from \"./global-id.ts\";\nimport type { DetailSection, DisplayIntent, PaginatedResult, Product, ProductFilter, ProductSortKey } 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\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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 }\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: GID!) {\n product(id: $id) {\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\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 }\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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 }\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 vendor\n productType\n metaTitle\n metaDescription\n publishedAt\n createdAt\n availableForSale\n media {\n id\n url\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\n compareAtPrice\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\n altText\n position\n }\n isOnSale\n quantityPricing {\n minQuantity\n price\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 }\n}\n`;\n\nexport interface ProductsOperations {\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 GID or handle.\n *\n * @param idOrHandle - Product GID or handle.\n * @returns The matching product.\n */\n get(idOrHandle: 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\nexport function createProductsOperations(client: StorefrontClient): ProductsOperations {\n return {\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 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 get(idOrHandle: string): Promise<Result<Product, StorefrontError>> {\n const useId = isGlobalId(idOrHandle);\n\n const result = await client.query<ProductQueryResponse>({\n query: useId ? PRODUCT_BY_ID_QUERY : PRODUCT_BY_HANDLE_QUERY,\n variables: useId ? { id: idOrHandle } : { handle: idOrHandle },\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: ${idOrHandle}`));\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}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { NotFoundError } from \"./errors.ts\";\nimport type { ShippingRate } from \"./types.ts\";\n\ninterface ShippingRateData {\n id: string;\n name: string;\n price: number;\n minOrderAmount: number | 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\n minOrderAmount\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: StorefrontClient): 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: true },\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 { StorefrontClient } from \"./client.ts\";\nimport type { StorefrontResult, Store } 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 logoUrl\n contactEmail\n contactPhone\n trackingDispatchOnUnknownConsent\n browserTrackingConfig {\n gtm {\n enabled\n containerId\n }\n }\n analytics {\n enabled\n dispatchOnUnknownConsent\n gtm {\n enabled\n containerId\n }\n }\n socialLinks\n }\n}\n`;\n\nexport function createStoreOperations(client: StorefrontClient): 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 AuthOperations, createAuthOperations } from \"./auth.ts\";\nimport { createQueryCache, type QueryCache } from \"./cache.ts\";\nimport { type CartOperations, createCartOperations } from \"./cart.ts\";\nimport { type CategoriesOperations, createCategoriesOperations } from \"./categories.ts\";\nimport { type CheckoutOperations, createCheckoutOperations } from \"./checkout.ts\";\nimport { type CollectionsOperations, createCollectionsOperations } from \"./collections.ts\";\nimport type { StorefrontError } from \"./errors.ts\";\nimport { createGraphQLClient, type GraphQLClient, type GraphQLRequest } from \"./graphql-client.ts\";\nimport { createPaymentsOperations, type PaymentsOperations } from \"./payments.ts\";\nimport { createProductsOperations, type ProductsOperations } from \"./products.ts\";\nimport { createAnalyticsOperations, type AnalyticsOperations } from \"./analytics.ts\";\nimport { createShippingOperations, type ShippingOperations } from \"./shipping.ts\";\nimport { createStoreOperations, type StoreOperations } from \"./store.ts\";\nimport { CART_TOKEN_KEY, CUSTOMER_TOKEN_KEY, createDefaultAdapter } from \"./storage.ts\";\nimport type {\n ResolvedStorefrontInitConfig,\n StorageAdapter,\n StorefrontAnalyticsInitConfig,\n StorefrontClientConfig,\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 {\n readonly config: StorefrontClientConfig;\n readonly cache: CacheHelpers;\n readonly products: ProductsOperations;\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\n init(options?: StorefrontInitOptions): Promise<Result<ResolvedStorefrontInitConfig, StorefrontError>>;\n\n /**\n * Execute a GraphQL query with optional caching\n */\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>>;\n\n /**\n * Execute a GraphQL mutation (never cached)\n */\n mutate<T>(request: GraphQLRequest): Promise<Result<T, StorefrontError>>;\n\n /**\n * Get the current cart token from storage\n */\n getCartToken(): string | null;\n\n /**\n * Set the cart token in storage\n */\n setCartToken(token: string): void;\n\n /**\n * Clear the cart token from storage\n */\n clearCartToken(): void;\n\n /**\n * Get the current customer JWT token from storage\n */\n getCustomerToken(): string | null;\n\n /**\n * Set the customer JWT token in storage\n */\n setCustomerToken(token: string): void;\n\n /**\n * Clear the customer JWT token from storage\n */\n clearCustomerToken(): void;\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 { 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 { PaymentsOperations } from \"./payments.ts\";\nexport type { AnalyticsOperations } from \"./analytics.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://api.mystore.com/storefront\",\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 const storage = config.storage ?? createDefaultAdapter();\n const queryCache = createQueryCache();\n const cacheTTL = config.cacheTTL ?? DEFAULT_CACHE_TTL;\n\n const graphqlClient = createGraphQLClient({\n endpoint: config.endpoint,\n apiKey: config.apiKey,\n getCartToken: () => storage.get(CART_TOKEN_KEY),\n getCustomerToken: () => storage.get(CUSTOMER_TOKEN_KEY),\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 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\n init: null as unknown as StorefrontClient[\"init\"],\n\n query<T>(request: GraphQLRequest, options?: { cache?: boolean }): Promise<Result<T, StorefrontError>> {\n return graphqlClient.query<T>(request, options);\n },\n\n mutate<T>(request: GraphQLRequest): Promise<Result<T, StorefrontError>> {\n return graphqlClient.mutate<T>(request);\n },\n\n getCartToken(): string | null {\n return storage.get(CART_TOKEN_KEY);\n },\n\n setCartToken(token: string): void {\n storage.set(CART_TOKEN_KEY, token);\n },\n\n clearCartToken(): void {\n storage.remove(CART_TOKEN_KEY);\n },\n\n getCustomerToken(): string | null {\n return storage.get(CUSTOMER_TOKEN_KEY);\n },\n\n setCustomerToken(token: string): void {\n storage.set(CUSTOMER_TOKEN_KEY, token);\n },\n\n clearCustomerToken(): void {\n storage.remove(CUSTOMER_TOKEN_KEY);\n },\n };\n\n // Create operations after client is created to avoid circular reference\n (client as { products: ProductsOperations }).products = createProductsOperations(client);\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 { cart: CartOperations }).cart = createCartOperations(client, storage);\n (client as { checkout: CheckoutOperations }).checkout = createCheckoutOperations(client, storage);\n (client as { payments: PaymentsOperations }).payments = createPaymentsOperations(client);\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 const analytics = createAnalyticsOperations(client, storage);\n (client as { analytics: AnalyticsOperations }).analytics = analytics;\n client.init = async (options?: StorefrontInitOptions) => {\n client._analyticsRuntimeConfig = options?.analytics ?? null;\n\n const storeResult = await client.store.get({ cache: false });\n if (storeResult.isErr()) {\n return err(storeResult.error);\n }\n\n const resolvedConfig: ResolvedStorefrontInitConfig = {\n analytics: {\n enabled: storeResult.value.analytics.enabled,\n dispatchOnUnknownConsent: storeResult.value.analytics.dispatchOnUnknownConsent,\n gtm: storeResult.value.analytics.gtm,\n },\n };\n\n client._analyticsRuntimeConfig = {\n ...(options?.analytics ?? {}),\n dispatchOnUnknownConsent: resolvedConfig.analytics.dispatchOnUnknownConsent,\n };\n client._resolvedInitConfig = resolvedConfig;\n analytics.init(resolvedConfig.analytics);\n\n return ok(resolvedConfig);\n };\n\n return client;\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 {\n type GtmStandardEventName,\n getTrackingProviderDedupeConvention,\n getTrackingProviderEventName,\n getTrackingProviderSupportRule,\n} from \"@ekomerc/tracking-policy\";\nimport { getNumberPropFromKeys, getWindowObject } from \"./browser-helpers.ts\";\nimport type {\n AnalyticsAdapterDispatchInput,\n AnalyticsAdapterOperationResult,\n AnalyticsBrowserAdapter,\n AnalyticsConsentState,\n AnalyticsConsentUpdate,\n AnalyticsProperties,\n} from \"./tracking-runtime.ts\";\nimport type { GtmBrowserTrackingConfig } from \"./types.ts\";\n\nconst DEFAULT_CURRENCY = \"RSD\";\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 = {\n page_view: \"ekomerc.page_view\",\n view_item: \"ekomerc.view_item\",\n view_item_list: \"ekomerc.view_item_list\",\n search: \"ekomerc.search\",\n add_to_cart: \"ekomerc.add_to_cart\",\n remove_from_cart: \"ekomerc.remove_from_cart\",\n begin_checkout: \"ekomerc.begin_checkout\",\n purchase: \"ekomerc.purchase\",\n} as const satisfies Record<GtmStandardEventName, GtmNamespacedEventName>;\n\n/**\n * GTM ecommerce item payload derived from storefront analytics properties.\n */\nexport interface GtmItem {\n product_id: string;\n variant_id?: string;\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 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}\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 centsToCurrencyUnits(valueInCents: number | null): number | null {\n if (valueInCents === null) {\n return null;\n }\n\n return valueInCents / 100;\n}\n\nfunction getDinarValue(properties: Record<string, unknown>, dinarKeys: string[], centsKeys: string[]): number | null {\n const valueInDinars = getNumberPropFromKeys(properties, dinarKeys);\n if (valueInDinars !== null) {\n return valueInDinars;\n }\n\n return centsToCurrencyUnits(getNumberPropFromKeys(properties, centsKeys));\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 resolveProductId(properties: Record<string, unknown>): string | null {\n return (\n getStringProp(properties, \"productId\") ??\n getStringProp(properties, \"product_id\") ??\n getStringProp(properties, \"contentId\") ??\n getStringProp(properties, \"content_id\") ??\n getStringProp(properties, \"id\") ??\n getStringProp(properties, \"item_id\")\n );\n}\n\nfunction buildItem(properties: Record<string, unknown>, currency: string): GtmItem | null {\n const productId = resolveProductId(properties);\n if (!productId) {\n return null;\n }\n\n const quantity = normalizeQuantity(getNumberProp(properties, \"quantity\"));\n const unitPrice =\n getDinarValue(\n properties,\n [\"unitPrice\", \"unit_price\", \"price\"],\n [\"unitPriceCents\", \"unit_price_cents\", \"priceCents\"],\n ) ?? 0;\n const lineTotal =\n getDinarValue(\n properties,\n [\"lineTotal\", \"line_total\", \"total\"],\n [\"lineTotalCents\", \"line_total_cents\", \"totalCents\"],\n ) ?? unitPrice * quantity;\n\n const item: GtmItem = {\n product_id: productId,\n quantity,\n unit_price: unitPrice,\n line_total: lineTotal,\n currency,\n };\n\n const variantId = getStringProp(properties, \"variantId\") ?? getStringProp(properties, \"variant_id\");\n if (variantId) {\n item.variant_id = variantId;\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 === \"add_to_cart\" ||\n eventName === \"remove_from_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 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\n/**\n * Maps a storefront analytics event to a GTM `dataLayer.push()` payload.\n */\nexport function buildGtmDataLayerEvent(input: AnalyticsAdapterDispatchInput): GtmDataLayerEvent | null {\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 (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 !== \"page_view\" && providerEventName !== \"search\") {\n const currency = getStringProp(input.event.properties, \"currency\") ?? DEFAULT_CURRENCY;\n const value = getDinarValue(\n input.event.properties,\n [\"value\", \"total\", \"orderTotal\", \"cartValue\"],\n [\"priceCents\", \"cartValueCents\", \"totalCents\", \"orderTotalCents\"],\n );\n const quantity = getNumberProp(input.event.properties, \"quantity\");\n const itemsCount = getNumberPropFromKeys(input.event.properties, [\"itemsCount\", \"numItems\"]);\n const items = buildNormalizedItems(providerEventName, input.event.properties, currency);\n\n ekomerc.currency = currency;\n\n if (value !== null) {\n ekomerc.value = value;\n }\n\n const cartId = getStringProp(input.event.properties, \"cartId\");\n if (cartId) {\n ekomerc.cart_id = cartId;\n }\n\n const orderId = getStringProp(input.event.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.length;\n }\n\n if (items.length > 0) {\n ekomerc.items = items;\n }\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 */\nexport function buildGtmConsentModeUpdate({ consentState }: AnalyticsConsentUpdate): GtmConsentModeUpdate {\n const consentValue = consentState === \"granted\" ? \"granted\" : \"denied\";\n\n return {\n analytics_storage: consentValue,\n ad_storage: consentValue,\n ad_user_data: consentValue,\n ad_personalization: consentValue,\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 if (!supportRule.supportsBrowserDispatch || !config.enabled || !config.containerId) {\n return null;\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 pushConsentCommand(windowObject, dataLayer, \"default\", GTM_CONSENT_DEFAULT_STATE);\n consentDefaultsApplied = true;\n }\n\n return {\n provider: \"gtm\",\n dispatch(input) {\n const payload = buildGtmDataLayerEvent(input);\n if (payload === null) {\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 dataLayer.push(payload);\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 pushConsentCommand(windowObject, dataLayer, \"update\", buildGtmConsentModeUpdate(input));\n return {\n status: \"success\",\n };\n },\n };\n}\n"],"names":["handleUserErrors","ValidationError","err","AuthError","ok","TRACKING_SCHEMA_VERSION","hasBrowserContext","StateError","NotFoundError","isPlainObject","NetworkError","GraphQLError","errors","getWindow"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgGvB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgF5B,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFhC,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
|