@shoppexio/storefront 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../sdk/src/core/errors.ts","../../sdk/src/core/config.ts","../../sdk/src/core/cache.ts","../../sdk/src/core/client.ts","../../sdk/src/core/endpoint.ts","../../sdk/src/modules/store.ts","../../sdk/src/modules/products.ts","../../sdk/src/utils/storage.ts","../../sdk/src/modules/cart.ts","../../sdk/src/modules/checkout.ts","../../sdk/src/modules/affiliates.ts","../../sdk/src/modules/coupons.ts","../../sdk/src/modules/reviews.ts","../../sdk/src/modules/search.ts","../../sdk/src/modules/invoices.ts","../../sdk/src/modules/pages.ts","../../contracts/src/navigation.ts","../../sdk/src/modules/navigation.ts","../../sdk/src/modules/analytics.ts","../../sdk/src/utils/format.ts","../../sdk/src/modules/theme.ts","../../sdk/src/index.ts"],"sourcesContent":["/**\n * SDK Error Classes\n */\n\nexport class ShoppexError extends Error {\n public readonly code: string;\n public readonly statusCode?: number;\n\n constructor(message: string, code: string, statusCode?: number) {\n super(message);\n this.name = 'ShoppexError';\n this.code = code;\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, ShoppexError.prototype);\n }\n}\n\nexport class NotInitializedError extends ShoppexError {\n constructor() {\n super(\n 'SDK not initialized. Call shoppex.init() first.',\n 'NOT_INITIALIZED'\n );\n this.name = 'NotInitializedError';\n Object.setPrototypeOf(this, NotInitializedError.prototype);\n }\n}\n\nexport class NetworkError extends ShoppexError {\n constructor(message: string, statusCode?: number) {\n super(message, 'NETWORK_ERROR', statusCode);\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\nexport class ValidationError extends ShoppexError {\n public readonly invalidFields?: string[];\n\n constructor(message: string, invalidFields?: string[]) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n this.invalidFields = invalidFields;\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class CartError extends ShoppexError {\n constructor(message: string) {\n super(message, 'BASKET_ERROR');\n this.name = 'CartError';\n Object.setPrototypeOf(this, CartError.prototype);\n }\n}\n","/**\n * SDK Configuration Management\n */\n\nimport type { ShoppexConfig, ShoppexInitOptions } from '../types';\nimport { NotInitializedError } from './errors';\n\nexport const DEFAULT_API_BASE_URL = 'https://api.shoppex.io';\n\nlet currentConfig: ShoppexConfig | null = null;\nlet cachedShopId: string | null = null;\n\nexport const DEFAULT_CHECKOUT_BASE_URL = 'https://checkout.shoppex.io';\n\nexport function initConfig(\n storeSlug: string,\n options?: ShoppexInitOptions\n): ShoppexConfig {\n // Reset cached shop id on every init to avoid cross-store leakage\n // when the SDK is re-initialized with a different slug.\n cachedShopId = null;\n\n currentConfig = {\n storeSlug,\n locale: options?.locale,\n currency: options?.currency,\n apiBaseUrl: options?.apiBaseUrl ?? DEFAULT_API_BASE_URL,\n checkoutBaseUrl: options?.checkoutBaseUrl ?? DEFAULT_CHECKOUT_BASE_URL,\n };\n return currentConfig;\n}\n\nexport function getConfig(): ShoppexConfig {\n if (!currentConfig) {\n throw new NotInitializedError();\n }\n return currentConfig;\n}\n\nexport function isInitialized(): boolean {\n return currentConfig !== null;\n}\n\nexport function resetConfig(): void {\n currentConfig = null;\n cachedShopId = null;\n}\n\nexport function setShopId(shopId: string): void {\n cachedShopId = shopId;\n}\n\nexport function getShopId(): string | null {\n return cachedShopId;\n}\n","/**\n * In-memory cache with pending request deduplication.\n */\n\nexport interface CacheEntry<T> {\n data: T;\n expiresAt: number;\n updatedAt: number;\n ttl: number;\n}\n\nexport interface CacheOptions {\n ttl: number;\n staleWhileRevalidate?: boolean;\n}\n\nexport interface CacheStats {\n hits: number;\n misses: number;\n pendingRequests: number;\n entries: number;\n}\n\nconst cache = new Map<string, CacheEntry<unknown>>();\nconst pending = new Map<string, Promise<unknown>>();\n\nconst stats = {\n hits: 0,\n misses: 0,\n};\n\nfunction isExpired(entry: CacheEntry<unknown>): boolean {\n return Date.now() > entry.expiresAt;\n}\n\nexport function getCacheStats(): CacheStats {\n return {\n hits: stats.hits,\n misses: stats.misses,\n pendingRequests: pending.size,\n entries: cache.size,\n };\n}\n\nexport function clearCache(): void {\n cache.clear();\n pending.clear();\n}\n\nexport function invalidateCache(prefixOrKey: string): void {\n for (const key of cache.keys()) {\n if (key === prefixOrKey || key.startsWith(prefixOrKey)) {\n cache.delete(key);\n }\n }\n}\n\nexport function setCacheEntry<T>(key: string, data: T, ttl: number): void {\n const now = Date.now();\n cache.set(key, {\n data,\n ttl,\n updatedAt: now,\n expiresAt: now + ttl,\n });\n}\n\nexport function getCacheEntry<T>(key: string): CacheEntry<T> | null {\n const entry = cache.get(key) as CacheEntry<T> | undefined;\n if (!entry) return null;\n return entry;\n}\n\nexport async function getOrFetch<T>(\n key: string,\n fetcher: () => Promise<T>,\n options: CacheOptions,\n shouldCache: (value: T) => boolean = () => true\n): Promise<T> {\n const entry = getCacheEntry<T>(key);\n\n if (entry && !isExpired(entry)) {\n stats.hits += 1;\n return entry.data;\n }\n\n if (entry && options.staleWhileRevalidate) {\n stats.hits += 1;\n if (!pending.has(key)) {\n const refreshPromise = (async () => {\n try {\n const data = await fetcher();\n if (shouldCache(data)) {\n setCacheEntry(key, data, options.ttl);\n }\n return data;\n } finally {\n pending.delete(key);\n }\n })();\n pending.set(key, refreshPromise as Promise<unknown>);\n }\n return entry.data;\n }\n\n if (pending.has(key)) {\n return pending.get(key) as Promise<T>;\n }\n\n stats.misses += 1;\n const promise = (async () => {\n try {\n const data = await fetcher();\n if (shouldCache(data)) {\n setCacheEntry(key, data, options.ttl);\n }\n return data;\n } finally {\n pending.delete(key);\n }\n })();\n\n pending.set(key, promise as Promise<unknown>);\n return promise;\n}\n","/**\n * HTTP Client for SDK\n *\n * IMPORTANT: No credentials! SDK runs on external domains,\n * and CORS with wildcard origin doesn't allow credentials.\n * All endpoints are public storefront endpoints.\n */\n\nimport type { ApiResponse, SDKResponse } from '../types';\nimport { getConfig } from './config';\nimport { NetworkError } from './errors';\nimport { getOrFetch, type CacheOptions } from './cache';\n\nconst DEFAULT_TIMEOUT = 10000;\nconst MAX_RETRIES = 2;\n\ninterface RequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n body?: unknown;\n timeout?: number;\n retries?: number;\n baseUrl?: string;\n cache?: (CacheOptions & { key?: string }) | false;\n}\n\ninterface ParsedResponsePayload {\n data: unknown | null;\n rawText: string | null;\n}\n\nasync function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function request<T>(\n endpoint: string,\n options: RequestOptions = {}\n): Promise<SDKResponse<T>> {\n const config = options.baseUrl ? null : getConfig();\n const {\n method = 'GET',\n body,\n timeout = DEFAULT_TIMEOUT,\n retries,\n baseUrl,\n cache,\n } = options;\n const retryCount =\n retries ?? (method === 'GET' ? MAX_RETRIES : 0);\n\n const apiBaseUrl = baseUrl ?? config?.apiBaseUrl ?? '';\n const url = `${apiBaseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n\n let lastError: Error | null = null;\n\n const executeRequest = async (): Promise<SDKResponse<T>> => {\n for (let attempt = 0; attempt <= retryCount; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const payload = await parseResponsePayload(response);\n\n if (!response.ok) {\n const fallbackHttpMessage = response.statusText\n ? `HTTP ${response.status}: ${response.statusText}`\n : `HTTP ${response.status}`;\n const message =\n (payload.data && typeof payload.data === 'object' && 'error' in payload.data && typeof payload.data.error === 'string'\n ? payload.data.error\n : null) ??\n (payload.data && typeof payload.data === 'object' && 'message' in payload.data && typeof payload.data.message === 'string'\n ? payload.data.message\n : null) ??\n payload.rawText ??\n fallbackHttpMessage;\n\n throw new NetworkError(message, response.status);\n }\n\n if (response.status === 204 && payload.data === null) {\n return {\n success: true,\n };\n }\n\n if (!payload.data || typeof payload.data !== 'object' || !('status' in payload.data)) {\n throw new NetworkError('Invalid API response', response.status);\n }\n\n const data = payload.data as ApiResponse<T>;\n\n return mapApiResponse(data);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (error instanceof DOMException && error.name === 'AbortError') {\n lastError = new NetworkError('Request timeout', 408);\n }\n\n if (attempt < retryCount) {\n await sleep(Math.pow(2, attempt) * 500);\n continue;\n }\n }\n }\n\n return {\n success: false,\n message: lastError?.message ?? 'Unknown error',\n };\n };\n\n if (method === 'GET' && cache && cache.ttl > 0) {\n const cacheKey = cache.key ?? `GET:${url}`;\n return getOrFetch(\n cacheKey,\n executeRequest,\n { ttl: cache.ttl, staleWhileRevalidate: cache.staleWhileRevalidate },\n (value) => value.success\n );\n }\n\n return executeRequest();\n}\n\nasync function parseResponsePayload(response: Response): Promise<ParsedResponsePayload> {\n const responseWithOptionalMethods = response as Response & {\n text?: () => Promise<string>;\n json?: () => Promise<unknown>;\n };\n\n // Runtime-safe fallback for test mocks that only implement `json()`.\n if (typeof responseWithOptionalMethods.text !== 'function') {\n if (typeof responseWithOptionalMethods.json === 'function') {\n try {\n return {\n data: await responseWithOptionalMethods.json(),\n rawText: null,\n };\n } catch {\n return { data: null, rawText: null };\n }\n }\n return { data: null, rawText: null };\n }\n\n try {\n const rawText = await responseWithOptionalMethods.text();\n if (!rawText) {\n return { data: null, rawText: null };\n }\n\n try {\n return {\n data: JSON.parse(rawText) as unknown,\n rawText: null,\n };\n } catch {\n const normalizedText = rawText.trim();\n return {\n data: null,\n rawText: normalizedText.length > 0 ? normalizedText : null,\n };\n }\n } catch {\n return { data: null, rawText: null };\n }\n}\n\nfunction mapApiResponse<T>(apiResponse: ApiResponse<T>): SDKResponse<T> {\n if (apiResponse.status >= 200 && apiResponse.status < 300) {\n return {\n success: true,\n data: apiResponse.data,\n };\n }\n\n return {\n success: false,\n message: apiResponse.error ?? `Request failed with status ${apiResponse.status}`,\n };\n}\n\nexport async function get<T>(\n endpoint: string,\n options?: Omit<RequestOptions, 'method' | 'body'>\n): Promise<SDKResponse<T>> {\n return request<T>(endpoint, { ...options, method: 'GET' });\n}\n\nexport async function post<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, 'method' | 'body'>\n): Promise<SDKResponse<T>> {\n return request<T>(endpoint, { ...options, method: 'POST', body });\n}\n","const PARAM_PATTERN = /:([A-Za-z0-9_]+)/g;\n\nexport function buildEndpoint(\n template: string,\n params: Record<string, string | number | null | undefined>\n): string {\n return template.replace(PARAM_PATTERN, (_, key: string) => {\n const rawValue = params[key];\n if (rawValue === null || rawValue === undefined) {\n throw new Error(`Missing endpoint param: ${key}`);\n }\n\n const value = String(rawValue).trim();\n if (!value) {\n throw new Error(`Endpoint param \"${key}\" must not be empty`);\n }\n\n return encodeURIComponent(value);\n });\n}\n","/**\n * Store Module\n *\n * API methods for store data.\n */\n\nimport { get } from '../core/client';\nimport { DEFAULT_API_BASE_URL, getConfig, isInitialized, setShopId } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Shop, Product, StorefrontData, ProductGroup, Category, StorefrontAddonBootstrap } from '../types';\n\ninterface StoreResponse {\n shop: Shop;\n products?: Product[];\n groups?: ProductGroup[];\n items?: StorefrontData['items'];\n categories?: Category[];\n addons?: StorefrontAddonBootstrap;\n}\n\ninterface StorefrontResponse {\n shop: Shop;\n}\n\nconst STORE_CACHE_TTL = 5 * 60 * 1000;\n\nexport async function getStore(): Promise<SDKResponse<Shop>> {\n const config = getConfig();\n const response = await get<StoreResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug', {\n storeSlug: config.storeSlug,\n }),\n {\n cache: {\n key: `store:${config.storeSlug}`,\n ttl: STORE_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n // Cache the shopId for slug lookups\n if (response.data.shop?.id) {\n setShopId(response.data.shop.id);\n }\n return {\n success: true,\n data: response.data.shop,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\nexport async function resolveStoreByDomain(\n domain?: string,\n apiBaseUrl?: string\n): Promise<SDKResponse<Shop>> {\n const resolvedDomain =\n domain ??\n (typeof window !== 'undefined' ? window.location.hostname : '');\n\n if (!resolvedDomain) {\n return {\n success: false,\n message: 'Domain is required to resolve store',\n };\n }\n\n const cleanDomain = resolvedDomain\n .replace(/^https?:\\/\\//, '')\n .split('/')[0]\n .trim();\n\n const baseUrl =\n apiBaseUrl ??\n (isInitialized() ? getConfig().apiBaseUrl : DEFAULT_API_BASE_URL);\n\n const response = await get<StorefrontResponse>(\n buildEndpoint('/v1/storefront/shops/domain/:domain', {\n domain: cleanDomain,\n }),\n {\n baseUrl,\n cache: {\n key: `store:domain:${cleanDomain}`,\n ttl: STORE_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data?.shop) {\n return {\n success: true,\n data: response.data.shop,\n };\n }\n\n return {\n success: false,\n message: response.message ?? 'Failed to resolve store',\n };\n}\n\nexport async function getStorefront(): Promise<SDKResponse<StorefrontData>> {\n const config = getConfig();\n const response = await get<StoreResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug', {\n storeSlug: config.storeSlug,\n }),\n {\n cache: {\n key: `storefront:${config.storeSlug}`,\n ttl: STORE_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n // Cache the shopId for slug lookups\n if (response.data.shop?.id) {\n setShopId(response.data.shop.id);\n }\n return {\n success: true,\n data: {\n shop: response.data.shop,\n products: response.data.products ?? [],\n groups: response.data.groups ?? [],\n items: response.data.items ?? [],\n categories: response.data.categories ?? [],\n addons: response.data.addons ?? { items: [] },\n },\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\nexport async function getStoreLogoUrl(): Promise<string | null> {\n const response = await getStore();\n\n if (response.success && response.data?.logo) {\n return response.data.logo;\n }\n\n return null;\n}\n\nexport async function getStoreBannerUrl(): Promise<string | null> {\n const response = await getStore();\n\n if (response.success && response.data?.banner) {\n return response.data.banner;\n }\n\n return null;\n}\n","/**\n * Products Module\n *\n * API methods for product data.\n */\n\nimport { get } from '../core/client';\nimport { getConfig, getShopId } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Product, ProductCategory } from '../types';\n\ninterface ProductsResponse {\n products: Product[];\n}\n\ninterface ProductResponse {\n product: Product;\n}\n\nconst PRODUCTS_CACHE_TTL = 2 * 60 * 1000;\n\nexport async function getProducts(): Promise<SDKResponse<Product[]>> {\n const config = getConfig();\n const response = await get<ProductsResponse>(\n buildEndpoint('/v1/storefront/products/public/:storeSlug', {\n storeSlug: config.storeSlug,\n }),\n {\n cache: {\n key: `products:${config.storeSlug}`,\n ttl: PRODUCTS_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.products,\n };\n }\n\n return {\n success: false,\n message: response.message,\n data: [],\n };\n}\n\nexport async function getProduct(\n idOrSlug: string\n): Promise<SDKResponse<Product>> {\n // Include slug_shop_id for slug-based lookups\n const shopId = getShopId();\n const queryParams = shopId ? `?slug_shop_id=${encodeURIComponent(shopId)}` : '';\n\n const response = await get<ProductResponse>(\n `${buildEndpoint('/v1/storefront/products/unique/:idOrSlug', { idOrSlug })}${queryParams}`,\n {\n cache: {\n key: `product:${idOrSlug}:${shopId ?? 'no-shop'}`,\n ttl: PRODUCTS_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data?.product) {\n return {\n success: true,\n data: response.data.product,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\nexport async function getCategories(): Promise<SDKResponse<string[]>> {\n const products = await getProducts();\n\n if (!products.success || !products.data) {\n return {\n success: false,\n message: products.message,\n };\n }\n\n const categories = new Set<string>();\n for (const product of products.data) {\n if (product.categories) {\n for (const category of product.categories) {\n if (typeof category === 'string') {\n categories.add(category);\n } else if (category && typeof category === 'object' && 'uniqid' in category) {\n categories.add((category as ProductCategory).uniqid);\n }\n }\n }\n }\n\n return {\n success: true,\n data: Array.from(categories),\n };\n}\n","/**\n * localStorage Wrapper\n *\n * Handles localStorage access with error handling for\n * environments where localStorage is not available.\n */\n\nconst STORAGE_PREFIX = 'shoppex_';\n\nfunction getKey(key: string): string {\n return `${STORAGE_PREFIX}${key}`;\n}\n\nexport function getItem<T>(key: string): T | null {\n try {\n const item = localStorage.getItem(getKey(key));\n if (!item) return null;\n return JSON.parse(item) as T;\n } catch {\n return null;\n }\n}\n\nexport function setItem<T>(key: string, value: T): void {\n try {\n localStorage.setItem(getKey(key), JSON.stringify(value));\n } catch {\n console.warn('[shoppex] Failed to save to localStorage');\n }\n}\n\nexport function removeItem(key: string): void {\n try {\n localStorage.removeItem(getKey(key));\n } catch {\n // Ignore errors\n }\n}\n","/**\n * Cart Module\n *\n * localStorage-based cart with support for Shoppex features:\n * - Addons (express shipping, gift wrap, etc.)\n * - Custom Fields (engraving, gift message, etc.)\n * - Price Variants (different pricing tiers)\n */\n\nimport { getItem, setItem, removeItem } from '../utils/storage';\nimport { getConfig } from '../core/config';\nimport { CartError } from '../core/errors';\nimport type {\n CartItem,\n CartAddOptions,\n CartPayload,\n CartMetadata,\n CartStats,\n} from '../types';\n\nconst STORAGE_KEYS = {\n cart: 'cart',\n cartBackup: 'cart_backup',\n meta: 'cart_meta',\n metaBackup: 'cart_backup_meta',\n} as const;\n\ntype StorageKeyType = keyof typeof STORAGE_KEYS;\n\nfunction getStorageKey(type: StorageKeyType): string {\n return `${STORAGE_KEYS[type]}_${getConfig().storeSlug}`;\n}\n\nfunction hashString(value: string): string {\n let hash = 2166136261;\n for (let i = 0; i < value.length; i += 1) {\n hash ^= value.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n return (hash >>> 0).toString(16);\n}\n\nfunction computeChecksum(cart: CartItem[]): string {\n return hashString(JSON.stringify(cart));\n}\n\nfunction normalizeQuantity(value: number): number {\n if (!Number.isFinite(value)) {\n throw new CartError('quantity must be a finite number');\n }\n return Math.floor(value);\n}\n\nfunction normalizeCartItems(value: unknown): CartItem[] {\n if (!Array.isArray(value)) return [];\n const normalized: CartItem[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== 'object') continue;\n const record = entry as Record<string, unknown>;\n const productId = typeof record.product_id === 'string' ? record.product_id.trim() : '';\n const variantId = typeof record.variant_id === 'string' ? record.variant_id.trim() : '';\n const quantity = Number(record.quantity);\n\n if (!productId || !variantId || !Number.isFinite(quantity) || quantity < 1) {\n continue;\n }\n\n const item: CartItem = {\n product_id: productId,\n variant_id: variantId,\n quantity: Math.floor(quantity),\n };\n\n if (typeof record.price_variant_id === 'string') {\n item.price_variant_id = record.price_variant_id;\n }\n if (record.price_data && typeof record.price_data === 'object') {\n const priceData = record.price_data as Record<string, unknown>;\n if (typeof priceData.unit_price === 'number' && Number.isFinite(priceData.unit_price)) {\n item.price_data = { unit_price: priceData.unit_price };\n }\n }\n if (Array.isArray(record.addons)) {\n item.addons = record.addons as CartItem['addons'];\n }\n if (record.custom_fields && typeof record.custom_fields === 'object' && !Array.isArray(record.custom_fields)) {\n item.custom_fields = record.custom_fields as Record<string, string>;\n }\n\n normalized.push(item);\n }\n return normalized;\n}\n\nfunction getCartMetadata(): CartMetadata | null {\n return getItem<CartMetadata>(getStorageKey('meta'));\n}\n\nfunction writeCart(cart: CartItem[]): void {\n setItem(getStorageKey('cart'), cart);\n const now = Date.now();\n const previous = getCartMetadata();\n const nextMeta: CartMetadata = {\n created_at: previous?.created_at ?? now,\n last_modified: now,\n version: (previous?.version ?? 0) + 1,\n checksum: computeChecksum(cart),\n };\n setItem(getStorageKey('meta'), nextMeta);\n}\n\nfunction setCartWithMetadata(cart: CartItem[], metadata?: CartMetadata | null): void {\n setItem(getStorageKey('cart'), cart);\n const now = Date.now();\n const base = metadata ?? getCartMetadata();\n const nextMeta: CartMetadata = {\n created_at: base?.created_at ?? now,\n last_modified: now,\n version: base?.version ?? 1,\n checksum: computeChecksum(cart),\n };\n setItem(getStorageKey('meta'), nextMeta);\n}\n\nexport function getCart(): CartItem[] {\n const raw = getItem<unknown>(getStorageKey('cart'));\n return normalizeCartItems(raw);\n}\n\nexport function getCartItemCount(): number {\n const cart = getCart();\n return cart.reduce((sum, item) => sum + item.quantity, 0);\n}\n\nexport function addToCart(\n productId: string,\n variantId: string,\n quantity: number = 1,\n options?: CartAddOptions\n): void {\n if (!productId || !variantId) {\n throw new CartError('product_id and variant_id are required');\n }\n\n const normalizedQuantity = normalizeQuantity(quantity);\n if (normalizedQuantity < 1) {\n throw new CartError('quantity must be at least 1');\n }\n\n const cart = getCart();\n\n const existingIndex = cart.findIndex(\n (item) => item.product_id === productId && item.variant_id === variantId\n );\n\n if (existingIndex >= 0) {\n cart[existingIndex].quantity += normalizedQuantity;\n\n if (options?.addons) {\n cart[existingIndex].addons = options.addons;\n }\n if (options?.custom_fields) {\n cart[existingIndex].custom_fields = options.custom_fields;\n }\n if (options?.price_variant_id) {\n cart[existingIndex].price_variant_id = options.price_variant_id;\n }\n if (options?.price_data) {\n cart[existingIndex].price_data = options.price_data;\n }\n } else {\n cart.push({\n product_id: productId,\n variant_id: variantId,\n quantity: normalizedQuantity,\n addons: options?.addons,\n custom_fields: options?.custom_fields,\n price_variant_id: options?.price_variant_id,\n price_data: options?.price_data,\n });\n }\n\n writeCart(cart);\n}\n\nexport function updateCartItem(\n productId: string,\n variantId: string,\n updates: Partial<Omit<CartItem, 'product_id' | 'variant_id'>>\n): void {\n const cart = getCart();\n\n const index = cart.findIndex(\n (item) => item.product_id === productId && item.variant_id === variantId\n );\n\n if (index < 0) {\n throw new CartError('Item not found in cart');\n }\n\n if (updates.quantity !== undefined) {\n const normalizedQuantity = normalizeQuantity(updates.quantity);\n if (normalizedQuantity < 1) {\n cart.splice(index, 1);\n writeCart(cart);\n return;\n }\n cart[index].quantity = normalizedQuantity;\n }\n\n if (updates.addons !== undefined) {\n cart[index].addons = updates.addons;\n }\n\n if (updates.custom_fields !== undefined) {\n cart[index].custom_fields = updates.custom_fields;\n }\n\n if (updates.price_variant_id !== undefined) {\n cart[index].price_variant_id = updates.price_variant_id;\n }\n if (updates.price_data !== undefined) {\n cart[index].price_data = updates.price_data;\n }\n\n writeCart(cart);\n}\n\nexport function removeFromCart(productId: string, variantId: string): void {\n const cart = getCart();\n\n const filtered = cart.filter(\n (item) => !(item.product_id === productId && item.variant_id === variantId)\n );\n\n writeCart(filtered);\n}\n\nexport function clearCart(): void {\n removeItem(getStorageKey('cart'));\n removeItem(getStorageKey('meta'));\n}\n\nexport function createCartBackup(): void {\n const cart = getCart();\n setItem(getStorageKey('cartBackup'), cart);\n const metadata = getCartMetadata();\n if (metadata) {\n setItem(getStorageKey('metaBackup'), metadata);\n } else {\n const now = Date.now();\n setItem(getStorageKey('metaBackup'), {\n created_at: now,\n last_modified: now,\n version: 1,\n checksum: computeChecksum(cart),\n });\n }\n}\n\nexport function restoreCartFromBackup(): boolean {\n const backupRaw = getItem<unknown>(getStorageKey('cartBackup'));\n const backup = normalizeCartItems(backupRaw);\n const backupMeta = getItem<CartMetadata>(getStorageKey('metaBackup'));\n\n if (backup && backup.length > 0) {\n setCartWithMetadata(backup, backupMeta);\n return true;\n }\n\n return false;\n}\n\nexport function mergeBaskets(items: CartItem[]): CartItem[] {\n const cart = getCart();\n\n for (const incoming of items) {\n const productId = typeof incoming.product_id === 'string' ? incoming.product_id.trim() : '';\n const variantId = typeof incoming.variant_id === 'string' ? incoming.variant_id.trim() : '';\n if (!productId || !variantId) {\n continue;\n }\n\n let normalizedQuantity: number;\n try {\n normalizedQuantity = normalizeQuantity(incoming.quantity);\n } catch {\n continue;\n }\n\n if (normalizedQuantity < 1) {\n continue;\n }\n\n const index = cart.findIndex(\n (item) =>\n item.product_id === productId &&\n item.variant_id === variantId\n );\n\n if (index >= 0) {\n cart[index].quantity = Math.max(cart[index].quantity, normalizedQuantity);\n } else {\n cart.push({\n ...incoming,\n product_id: productId,\n variant_id: variantId,\n quantity: normalizedQuantity,\n });\n }\n }\n\n writeCart(cart);\n return cart;\n}\n\nexport function moveBasketItem(\n fromProductId: string,\n fromVariantId: string,\n toProductId: string,\n toVariantId: string\n): void {\n const cart = getCart();\n const fromIndex = cart.findIndex(\n (item) => item.product_id === fromProductId && item.variant_id === fromVariantId\n );\n\n if (fromIndex < 0) {\n throw new CartError('Item not found in cart');\n }\n\n const [fromItem] = cart.splice(fromIndex, 1);\n const toIndex = cart.findIndex(\n (item) => item.product_id === toProductId && item.variant_id === toVariantId\n );\n\n if (toIndex >= 0) {\n cart[toIndex].quantity += fromItem.quantity;\n } else {\n cart.push({\n ...fromItem,\n product_id: toProductId,\n variant_id: toVariantId,\n });\n }\n\n writeCart(cart);\n}\n\nexport function validateCartIntegrity(): boolean {\n const cart = getCart();\n const metadata = getCartMetadata();\n const checksum = computeChecksum(cart);\n\n if (!metadata) {\n setCartWithMetadata(cart, null);\n return true;\n }\n\n return metadata.checksum === checksum;\n}\n\nexport function getCartStats(): CartStats {\n const cart = getCart();\n const integrityValid = validateCartIntegrity();\n const metadata = getCartMetadata();\n const backup = getItem<CartItem[]>(getStorageKey('cartBackup')) ?? [];\n const hasCompletePriceSnapshots =\n cart.length > 0 &&\n cart.every((item) => typeof item.price_data?.unit_price === 'number');\n const totalPrice = cart.reduce((sum, item) => {\n const unitPrice = item.price_data?.unit_price ?? 0;\n return sum + (unitPrice * item.quantity);\n }, 0);\n\n return {\n item_count: cart.length,\n total_quantity: cart.reduce((sum, item) => sum + item.quantity, 0),\n last_modified: metadata?.last_modified ?? 0,\n version: metadata?.version ?? 0,\n has_backup: backup.length > 0,\n integrity_valid: integrityValid,\n total_price: totalPrice,\n total_price_is_estimate: cart.length > 0 && !hasCompletePriceSnapshots,\n };\n}\n\nexport function getCartPayload(coupon?: string): CartPayload {\n const config = getConfig();\n return {\n store_slug: config.storeSlug,\n items: getCart(),\n coupon,\n };\n}\n\nexport function serializeCart(coupon?: string): string {\n const payload = getCartPayload(coupon);\n const json = JSON.stringify(payload);\n // UTF-8 safe Base64: encodeURIComponent converts to UTF-8, unescape converts percent-encoding to bytes\n if (typeof btoa !== 'undefined') {\n return btoa(unescape(encodeURIComponent(json)));\n }\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(json, 'utf8').toString('base64');\n }\n throw new CartError('Base64 encoding is not available in this environment');\n}\n","/**\n * Checkout Module\n *\n * Creates invoice via backend API and redirects to hosted checkout page.\n * All checkout flows go through: checkout.shoppex.io/invoice/{invoiceId}\n */\n\nimport { getConfig } from '../core/config';\nimport { post } from '../core/client';\nimport { getCart, createCartBackup, clearCart } from './cart';\nimport type { CartItem, CartAddon } from '../types/cart';\n\nexport interface CheckoutOptions {\n autoRedirect?: boolean;\n locale?: string;\n email?: string;\n coupon?: string;\n affiliateCode?: string;\n}\n\nexport interface CheckoutResult {\n success: boolean;\n redirectUrl?: string;\n invoiceId?: string;\n message?: string;\n}\n\ninterface CheckoutApiResponse {\n invoiceId?: string;\n checkoutUrl?: string;\n invoice_id?: string;\n checkout_url?: string;\n uniqid?: string;\n url?: string;\n url_branded?: string;\n invoice?: {\n invoiceId?: string;\n checkoutUrl?: string;\n invoice_id?: string;\n checkout_url?: string;\n uniqid?: string;\n url?: string;\n url_branded?: string;\n };\n}\n\ninterface NormalizedCheckoutData {\n invoiceId: string;\n checkoutUrl: string;\n}\n\nconst CHECKOUT_PREFILL_EMAIL_HASH_KEY = 'shoppex_prefill_email';\n\nfunction normalizeCoupon(coupon: string | null | undefined): string | null {\n const normalized = coupon?.trim();\n return normalized ? normalized : null;\n}\n\nfunction normalizeEmail(email: string | null | undefined): string | null {\n const normalized = email?.trim();\n return normalized ? normalized : null;\n}\n\nfunction normalizeCheckoutFailureMessage(rawMessage: string | null | undefined): string {\n const message = rawMessage?.trim() ?? '';\n if (!message) {\n return 'Checkout failed. Please try again.';\n }\n\n if (isStaleCartProductError(message)) {\n return 'Your cart is outdated. Please add the products again.';\n }\n\n const httpMatch = message.match(/^HTTP\\s+(\\d{3})(?::\\s*(.*))?$/i);\n if (httpMatch) {\n const status = Number(httpMatch[1]);\n const detail = httpMatch[2]?.trim();\n\n if (detail && detail.length > 0) {\n return `Checkout failed: ${detail}`;\n }\n\n if (status >= 500) {\n return 'Checkout is temporarily unavailable. Please try again.';\n }\n\n if (status === 400) {\n return 'Checkout failed. Please check your details and try again.';\n }\n\n if (status === 401 || status === 403) {\n return 'Checkout is currently unavailable for this request.';\n }\n\n return 'Checkout failed. Please try again.';\n }\n\n if (/^internal server error$/i.test(message)) {\n return 'Checkout is temporarily unavailable. Please try again.';\n }\n\n return message;\n}\n\nfunction isStaleCartProductError(rawMessage: string | null | undefined): boolean {\n const message = rawMessage?.trim().toLowerCase() ?? '';\n if (!message) {\n return false;\n }\n\n return message.includes('product not found')\n || message.includes('product not available')\n || message.includes('products are no longer available')\n || message.includes('outdated product');\n}\n\nfunction validateCheckoutUrl(\n checkoutUrl: string,\n checkoutBaseUrl: string | undefined,\n expectedInvoiceId?: string\n): string | null {\n const expectedBaseUrl = checkoutBaseUrl?.trim();\n if (!expectedBaseUrl) {\n return null;\n }\n\n try {\n const parsedCheckoutUrl = new URL(checkoutUrl);\n const parsedExpectedBaseUrl = new URL(expectedBaseUrl);\n\n if (parsedCheckoutUrl.origin !== parsedExpectedBaseUrl.origin) {\n return null;\n }\n\n const normalizedPath = parsedCheckoutUrl.pathname.replace(/\\/+$/, '');\n const normalizedBasePath = parsedExpectedBaseUrl.pathname.replace(/\\/+$/, '');\n const expectedInvoicePath = `${normalizedBasePath}/invoice/`.replace(/\\/{2,}/g, '/');\n if (!normalizedPath.startsWith(expectedInvoicePath)) {\n return null;\n }\n\n const invoiceIdSegment = normalizedPath.slice(expectedInvoicePath.length);\n if (!invoiceIdSegment || invoiceIdSegment.includes('/')) {\n return null;\n }\n\n if (expectedInvoiceId) {\n const normalizedExpectedInvoiceId = expectedInvoiceId.trim();\n const invoiceIdFromUrl = decodeURIComponent(invoiceIdSegment);\n if (!normalizedExpectedInvoiceId || invoiceIdFromUrl !== normalizedExpectedInvoiceId) {\n return null;\n }\n }\n\n return parsedCheckoutUrl.toString();\n } catch {\n return null;\n }\n}\n\nfunction buildCheckoutUrlFromInvoiceId(\n checkoutBaseUrl: string | undefined,\n invoiceId: string\n): string | null {\n const normalizedBaseUrl = checkoutBaseUrl?.trim();\n if (!normalizedBaseUrl) {\n return null;\n }\n\n try {\n const baseUrl = new URL(normalizedBaseUrl);\n const basePath = baseUrl.pathname.replace(/\\/+$/, '');\n baseUrl.pathname = `${basePath}/invoice/${encodeURIComponent(invoiceId)}`.replace(/\\/{2,}/g, '/');\n baseUrl.search = '';\n baseUrl.hash = '';\n return baseUrl.toString();\n } catch {\n return null;\n }\n}\n\nfunction appendPrefillEmailToCheckoutUrl(\n checkoutUrl: string,\n email: string | null | undefined,\n): string {\n const normalizedEmail = normalizeEmail(email);\n if (!normalizedEmail) {\n return checkoutUrl;\n }\n\n try {\n const parsedCheckoutUrl = new URL(checkoutUrl);\n const hashParams = new URLSearchParams(parsedCheckoutUrl.hash.startsWith('#')\n ? parsedCheckoutUrl.hash.slice(1)\n : parsedCheckoutUrl.hash);\n hashParams.set(CHECKOUT_PREFILL_EMAIL_HASH_KEY, normalizedEmail);\n parsedCheckoutUrl.hash = hashParams.toString();\n return parsedCheckoutUrl.toString();\n } catch {\n return checkoutUrl;\n }\n}\n\nfunction normalizeCheckoutResponse(\n response: CheckoutApiResponse | undefined,\n checkoutBaseUrl: string | undefined\n): NormalizedCheckoutData | null {\n const nestedInvoice = response?.invoice;\n const invoiceId = response?.invoiceId?.trim()\n || response?.invoice_id?.trim()\n || response?.uniqid?.trim()\n || nestedInvoice?.invoiceId?.trim()\n || nestedInvoice?.invoice_id?.trim()\n || nestedInvoice?.uniqid?.trim();\n let checkoutUrl = response?.checkoutUrl?.trim()\n || response?.checkout_url?.trim()\n || response?.url_branded?.trim()\n || response?.url?.trim()\n || nestedInvoice?.checkoutUrl?.trim()\n || nestedInvoice?.checkout_url?.trim()\n || nestedInvoice?.url_branded?.trim()\n || nestedInvoice?.url?.trim();\n\n if (!checkoutUrl && invoiceId && nestedInvoice) {\n checkoutUrl = buildCheckoutUrlFromInvoiceId(checkoutBaseUrl, invoiceId) ?? undefined;\n }\n\n if (!invoiceId || !checkoutUrl) {\n return null;\n }\n\n return { invoiceId, checkoutUrl };\n}\n\nfunction resolveCheckoutOptions(\n couponOrOptions?: string | CheckoutOptions,\n options?: CheckoutOptions\n): CheckoutOptions {\n if (typeof couponOrOptions === 'string') {\n return {\n ...options,\n coupon: couponOrOptions,\n };\n }\n\n return couponOrOptions ?? options ?? {};\n}\n\nfunction mapCartItemsForApi(items: CartItem[]) {\n const normalizeVariantIdForApi = (value: string | null | undefined): string | null => {\n const normalized = value?.trim();\n if (!normalized) return null;\n // Themes use \"default\" as a sentinel for \"no variant selected\".\n // Backend expects `null` in that case.\n if (normalized.toLowerCase() === 'default') return null;\n return normalized;\n };\n\n return items.map((item) => ({\n product_id: item.product_id,\n variant_id: normalizeVariantIdForApi(item.variant_id),\n quantity: item.quantity,\n addons: item.addons?.map((a: CartAddon) => ({ id: a.id, quantity: a.quantity ?? 1 })),\n custom_fields: item.custom_fields,\n price_variant_id: item.price_variant_id || null,\n }));\n}\n\nexport async function checkout(\n couponOrOptions?: string | CheckoutOptions,\n options?: CheckoutOptions\n): Promise<CheckoutResult> {\n const resolvedOptions = resolveCheckoutOptions(couponOrOptions, options);\n const { autoRedirect = true, email, coupon, affiliateCode } = resolvedOptions;\n const normalizedCoupon = normalizeCoupon(coupon);\n const normalizedEmail = normalizeEmail(email);\n const normalizedAffiliateCode = typeof affiliateCode === 'string' && affiliateCode.trim().length > 0\n ? affiliateCode.trim()\n : null;\n\n const cart = getCart();\n if (cart.length === 0) {\n return {\n success: false,\n message: 'Cart is empty',\n };\n }\n\n createCartBackup();\n\n const config = getConfig();\n\n let response = await post<CheckoutApiResponse>('/v1/storefront/invoices/from-cart', {\n shop_slug: config.storeSlug,\n cart: mapCartItemsForApi(cart),\n email: normalizedEmail,\n coupon: normalizedCoupon,\n affiliate_code: normalizedAffiliateCode,\n }, { retries: 0 });\n\n if (!response.success || !response.data) {\n if (isStaleCartProductError(response.message)) {\n clearCart();\n }\n return {\n success: false,\n message: normalizeCheckoutFailureMessage(response.message),\n };\n }\n\n const checkoutData = normalizeCheckoutResponse(response.data, config.checkoutBaseUrl);\n if (!checkoutData) {\n return {\n success: false,\n message: 'Failed to create invoice',\n };\n }\n\n const { invoiceId } = checkoutData;\n const safeCheckoutUrl = validateCheckoutUrl(\n checkoutData.checkoutUrl,\n config.checkoutBaseUrl,\n invoiceId\n );\n if (!safeCheckoutUrl) {\n return {\n success: false,\n message: 'Failed to create invoice',\n };\n }\n\n const checkoutUrlWithPrefill = appendPrefillEmailToCheckoutUrl(safeCheckoutUrl, normalizedEmail);\n\n if (autoRedirect) {\n if (typeof window !== 'undefined' && window?.location) {\n window.location.href = checkoutUrlWithPrefill;\n clearCart();\n }\n }\n\n return {\n success: true,\n redirectUrl: checkoutUrlWithPrefill,\n invoiceId,\n };\n}\n\n/**\n * Build checkout URL by creating invoice first.\n * Returns the checkout URL for the created invoice.\n */\nexport async function buildCheckoutUrl(\n couponOrOptions?: string | CheckoutOptions,\n options?: CheckoutOptions\n): Promise<string> {\n const resolvedOptions = resolveCheckoutOptions(couponOrOptions, options);\n const { email, coupon, affiliateCode } = resolvedOptions;\n const normalizedCoupon = normalizeCoupon(coupon);\n const normalizedEmail = normalizeEmail(email);\n const normalizedAffiliateCode = typeof affiliateCode === 'string' && affiliateCode.trim().length > 0\n ? affiliateCode.trim()\n : null;\n\n const cart = getCart();\n if (cart.length === 0) {\n throw new Error('Cart is empty');\n }\n\n const config = getConfig();\n\n let response = await post<CheckoutApiResponse>('/v1/storefront/invoices/from-cart', {\n shop_slug: config.storeSlug,\n cart: mapCartItemsForApi(cart),\n email: normalizedEmail,\n coupon: normalizedCoupon,\n affiliate_code: normalizedAffiliateCode,\n }, { retries: 0 });\n\n if (!response.success || !response.data) {\n if (isStaleCartProductError(response.message)) {\n clearCart();\n }\n throw new Error(normalizeCheckoutFailureMessage(response.message));\n }\n const checkoutData = normalizeCheckoutResponse(response.data, config.checkoutBaseUrl);\n if (!checkoutData) {\n throw new Error('Failed to create invoice');\n }\n\n const safeCheckoutUrl = validateCheckoutUrl(\n checkoutData.checkoutUrl,\n config.checkoutBaseUrl,\n checkoutData.invoiceId\n );\n if (!safeCheckoutUrl) {\n throw new Error('Failed to create invoice');\n }\n\n return appendPrefillEmailToCheckoutUrl(safeCheckoutUrl, normalizedEmail);\n}\n\n/**\n * @deprecated Use buildCheckoutUrl instead.\n * Sync version is no longer supported as invoice creation requires API call.\n */\nexport function buildCheckoutUrlSync(): never {\n throw new Error('buildCheckoutUrlSync is deprecated. Use buildCheckoutUrl (async) instead.');\n}\n","import { getConfig, isInitialized } from '../core/config';\nimport { post } from '../core/client';\n\nconst STORAGE_KEY = 'shoppex:affiliate_code:v1';\nconst DEFAULT_TTL_DAYS = 30;\n\ntype StoredAffiliate = {\n code: string;\n expiresAt: number;\n};\n\nfunction nowMs() {\n return Date.now();\n}\n\nfunction ttlMs(days: number) {\n return Math.max(1, days) * 24 * 60 * 60 * 1000;\n}\n\nfunction safeRead(): StoredAffiliate | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as StoredAffiliate;\n if (!parsed || typeof parsed.code !== 'string' || typeof parsed.expiresAt !== 'number') return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction safeWrite(value: StoredAffiliate) {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(value));\n } catch {\n // ignore\n }\n}\n\nexport function clearAffiliateCode(): void {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.removeItem(STORAGE_KEY);\n } catch {\n // ignore\n }\n}\n\nexport function getAffiliateCode(): string | null {\n const stored = safeRead();\n if (!stored) return null;\n if (stored.expiresAt <= nowMs()) {\n clearAffiliateCode();\n return null;\n }\n const normalized = stored.code.trim();\n return normalized.length > 0 ? normalized : null;\n}\n\n/**\n * Capture an affiliate code from the current URL and store it for 30 days (last-click).\n *\n * Example:\n * - URL: https://mystore.com/product/abc?ref=deadbeef\n * - captureAffiliateFromUrl() stores \"deadbeef\" and returns it.\n */\nexport async function captureAffiliateFromUrl(param = 'ref'): Promise<string | null> {\n if (typeof window === 'undefined') return null;\n\n let code: string | null = null;\n try {\n const url = new URL(window.location.href);\n const raw = url.searchParams.get(param);\n code = raw ? raw.trim() : null;\n } catch {\n code = null;\n }\n\n if (!code) return null;\n\n // Store immediately so we don't lose it if attribution call fails.\n safeWrite({ code, expiresAt: nowMs() + ttlMs(DEFAULT_TTL_DAYS) });\n\n // Optional: validate + normalize with backend. If invalid, clear it.\n if (isInitialized()) {\n try {\n const config = getConfig();\n const res = await post<{ accepted?: boolean; affiliate_code?: string | null }>(\n '/v1/storefront/affiliates/attribution',\n { shop_slug: config.storeSlug, code },\n { retries: 0 }\n );\n if (!res.success || !res.data?.accepted || !res.data?.affiliate_code) {\n clearAffiliateCode();\n return null;\n }\n safeWrite({ code: res.data.affiliate_code, expiresAt: nowMs() + ttlMs(DEFAULT_TTL_DAYS) });\n return res.data.affiliate_code;\n } catch {\n // keep stored raw code, from-cart will validate later\n return code;\n }\n }\n\n return code;\n}\n\n","/**\n * Coupons Module\n *\n * Coupon validation before checkout.\n */\n\nimport { post } from '../core/client';\nimport { getShopId } from '../core/config';\nimport { getStore } from './store';\nimport { getCart } from './cart';\nimport type { SDKResponse, CouponValidation } from '../types';\n\nasync function resolveShopId(): Promise<string | null> {\n const cachedShopId = getShopId();\n if (cachedShopId) {\n return cachedShopId;\n }\n\n const storeResult = await getStore();\n if (!storeResult.success || !storeResult.data?.id) {\n return null;\n }\n\n return storeResult.data.id;\n}\n\nexport async function validateCoupon(\n code: string,\n productId?: string\n): Promise<SDKResponse<CouponValidation>> {\n const trimmedCode = code.trim();\n if (!trimmedCode) {\n return {\n success: false,\n message: 'Coupon code is required',\n };\n }\n\n const payload: Record<string, unknown> = {\n code: trimmedCode,\n };\n\n if (productId) {\n payload.product_id = productId;\n } else {\n const cart = getCart();\n if (cart.length === 0) {\n return {\n success: false,\n message: 'Cart is empty',\n };\n }\n\n const shopId = await resolveShopId();\n if (!shopId) {\n return {\n success: false,\n message: 'Failed to resolve store',\n };\n }\n\n payload.cart = JSON.stringify({\n shop_id: shopId,\n products: cart.map((item) => ({\n uniqid: item.product_id,\n quantity: item.quantity,\n })),\n });\n }\n\n const response = await post<CouponValidation>(\n '/v1/storefront/coupons/check',\n payload\n );\n\n return response;\n}\n","/**\n * Reviews Module\n *\n * Shop-level feedback/reviews.\n * Note: Shoppex has shop-level feedback, not product-level reviews.\n */\n\nimport { get } from '../core/client';\nimport { getConfig } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Feedback } from '../types';\n\ninterface FeedbackResponse {\n feedback: Feedback[];\n}\n\nexport async function getShopReviews(): Promise<SDKResponse<Feedback[]>> {\n const config = getConfig();\n\n const response = await get<FeedbackResponse>(\n buildEndpoint('/v1/storefront/feedback/shop/:storeSlug', {\n storeSlug: config.storeSlug,\n })\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.feedback,\n };\n }\n\n return {\n success: false,\n message: response.message,\n data: [],\n };\n}\n","import { getProducts } from './products.js';\nimport { isInitialized } from '../core/config.js';\nimport type { SDKResponse, Product } from '../types/index.js';\n\nexport interface SearchOptions {\n hideOutOfStock?: boolean;\n}\n\nexport async function searchProducts(\n query: string,\n options?: SearchOptions\n): Promise<SDKResponse<Product[]>> {\n if (!isInitialized()) {\n return { success: false, message: 'SDK not initialized' };\n }\n\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) {\n return { success: true, data: [] };\n }\n\n const products = await getProducts();\n if (!products.success || !products.data) {\n return { success: false, message: products.message ?? 'Failed to fetch products' };\n }\n\n let results = products.data.filter(\n (p) =>\n p.title.toLowerCase().includes(trimmed) ||\n (p.description?.toLowerCase().includes(trimmed) ?? false)\n );\n\n if (options?.hideOutOfStock) {\n results = results.filter((p) => p.stock === undefined || p.stock === -1 || p.stock > 0);\n }\n\n return { success: true, data: results };\n}\n","/**\n * Invoices Module\n *\n * Invoice status checking after payment.\n */\n\nimport { get } from '../core/client';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Invoice } from '../types';\n\nfunction normalizeInvoiceId(invoiceId: string): string | null {\n const normalized = invoiceId.trim();\n if (!normalized) {\n return null;\n }\n return normalized;\n}\n\nexport async function getInvoice(\n invoiceId: string\n): Promise<SDKResponse<Invoice>> {\n const normalizedInvoiceId = normalizeInvoiceId(invoiceId);\n if (!normalizedInvoiceId) {\n return {\n success: false,\n message: 'Invoice ID is required',\n };\n }\n\n const response = await get<{ invoice: Invoice }>(\n buildEndpoint('/v1/storefront/invoices/unique/:invoiceId', {\n invoiceId: normalizedInvoiceId,\n })\n );\n if (!response.success) {\n return {\n success: false,\n message: response.message,\n };\n }\n\n if (!response.data?.invoice) {\n return {\n success: false,\n message: 'Invalid invoice response',\n };\n }\n\n return {\n success: true,\n data: response.data.invoice,\n };\n}\n\nexport async function getInvoiceStatus(\n invoiceId: string\n): Promise<SDKResponse<{ status: string }>> {\n const normalizedInvoiceId = normalizeInvoiceId(invoiceId);\n if (!normalizedInvoiceId) {\n return {\n success: false,\n message: 'Invoice ID is required',\n };\n }\n\n const response = await get<{ invoice: { status: string } }>(\n buildEndpoint('/v1/storefront/invoices/status/:invoiceId', {\n invoiceId: normalizedInvoiceId,\n })\n );\n if (!response.success) {\n return {\n success: false,\n message: response.message,\n };\n }\n\n if (!response.data?.invoice?.status) {\n return {\n success: false,\n message: 'Invalid invoice status response',\n };\n }\n\n return {\n success: true,\n data: { status: response.data.invoice.status },\n };\n}\n","/**\n * Pages Module\n *\n * API methods for public pages.\n */\n\nimport { get } from '../core/client';\nimport { getConfig } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Page } from '../types';\n\ninterface PagesResponse {\n pages: Page[];\n}\n\ninterface PageResponse {\n page: Page;\n}\n\nconst PAGES_CACHE_TTL = 5 * 60 * 1000;\n\n/**\n * Get all public pages for the store\n */\nexport async function getPages(): Promise<SDKResponse<Page[]>> {\n const config = getConfig();\n const response = await get<PagesResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug/pages', {\n storeSlug: config.storeSlug,\n }),\n {\n cache: {\n key: `pages:${config.storeSlug}`,\n ttl: PAGES_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.pages,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\n/**\n * Get a public page by slug\n */\nexport async function getPage(slug: string): Promise<SDKResponse<Page>> {\n const config = getConfig();\n const response = await get<PageResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug/pages/:slug', {\n storeSlug: config.storeSlug,\n slug,\n }),\n {\n cache: {\n key: `page:${config.storeSlug}:${slug}`,\n ttl: PAGES_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.page,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n","const NAVIGATION_MENU_SLOT_CONFIG = {\n header: {\n title: 'Header',\n aliases: ['Header Menu'],\n },\n footer: {\n title: 'Footer',\n aliases: ['Footer Links', 'Legal Links'],\n },\n} as const;\n\nexport type NavigationMenuSlot = keyof typeof NAVIGATION_MENU_SLOT_CONFIG;\n\nfunction normalizeNavigationToken(value: string): string {\n return value.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nexport function getNavigationMenuCanonicalTitle(slot: NavigationMenuSlot): string {\n return NAVIGATION_MENU_SLOT_CONFIG[slot].title;\n}\n\nexport function getNavigationMenuTitles(slot: NavigationMenuSlot): string[] {\n const config = NAVIGATION_MENU_SLOT_CONFIG[slot];\n return [config.title, ...config.aliases];\n}\n\nexport function isNavigationMenuSlot(value: string): value is NavigationMenuSlot {\n return value in NAVIGATION_MENU_SLOT_CONFIG;\n}\n\nexport function resolveNavigationMenuSlot(value: string | null | undefined): NavigationMenuSlot | null {\n if (!value) return null;\n\n const normalizedValue = normalizeNavigationToken(value);\n for (const slot of Object.keys(NAVIGATION_MENU_SLOT_CONFIG) as NavigationMenuSlot[]) {\n const candidates = [slot, ...getNavigationMenuTitles(slot)];\n if (candidates.some((candidate) => normalizeNavigationToken(candidate) === normalizedValue)) {\n return slot;\n }\n }\n\n return null;\n}\n\nexport function isSystemNavigationMenuTitle(value: string | null | undefined): boolean {\n return resolveNavigationMenuSlot(value) !== null;\n}\n\nexport const NAVIGATION_MENU_SLOTS = Object.keys(NAVIGATION_MENU_SLOT_CONFIG) as NavigationMenuSlot[];\n","/**\n * Navigation Module\n *\n * API methods for menus and navigation.\n */\n\nimport { get } from '../core/client';\nimport { getConfig } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport type { SDKResponse, Menu } from '../types';\nimport type { NavigationMenuSlot } from '@shoppex/contracts/navigation';\nimport { getNavigationMenuTitles } from '@shoppex/contracts/navigation';\n\ninterface MenusResponse {\n menus: Menu[];\n}\n\ninterface MenuResponse {\n menu: Menu;\n}\n\nconst NAVIGATION_CACHE_TTL = 5 * 60 * 1000;\n\n/**\n * Get all menus for the store\n */\nexport async function getMenus(): Promise<SDKResponse<Menu[]>> {\n const config = getConfig();\n const response = await get<MenusResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug/menus', {\n storeSlug: config.storeSlug,\n }),\n {\n cache: {\n key: `menus:${config.storeSlug}`,\n ttl: NAVIGATION_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.menus,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\n/**\n * Get a menu by its exact title.\n */\nexport async function getMenuByTitle(title: string): Promise<SDKResponse<Menu>> {\n const config = getConfig();\n const response = await get<MenuResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug/menus/:title', {\n storeSlug: config.storeSlug,\n title,\n }),\n {\n cache: {\n key: `menu:${config.storeSlug}:${title}`,\n ttl: NAVIGATION_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.menu,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\n/**\n * Get a menu by canonical slot. The backend resolves legacy menu titles too.\n */\nexport async function getMenuBySlot(slot: NavigationMenuSlot): Promise<SDKResponse<Menu>> {\n const config = getConfig();\n const response = await get<MenuResponse>(\n buildEndpoint('/v1/storefront/shops/name/:storeSlug/menus/:title', {\n storeSlug: config.storeSlug,\n title: slot,\n }),\n {\n cache: {\n key: `menu-slot:${config.storeSlug}:${slot}`,\n ttl: NAVIGATION_CACHE_TTL,\n staleWhileRevalidate: true,\n },\n }\n );\n\n if (response.success && response.data) {\n return {\n success: true,\n data: response.data.menu,\n };\n }\n\n return {\n success: false,\n message: response.message,\n };\n}\n\nexport function getMenuSlotTitles(slot: NavigationMenuSlot): string[] {\n return getNavigationMenuTitles(slot);\n}\n","import { isInitialized, getConfig } from '../core/config';\nimport { buildEndpoint } from '../core/endpoint';\nimport { getItem, setItem } from '../utils/storage';\n\nfunction createPresenceConnectionId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `spx_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction getPresenceConnectionId(storeSlug: string): string | null {\n if (typeof window === 'undefined') return null;\n\n const storageKey = `presence_connection_${storeSlug}`;\n const existing = getItem<string>(storageKey);\n if (existing && existing.trim()) {\n return existing;\n }\n\n const nextId = createPresenceConnectionId();\n setItem(storageKey, nextId);\n return nextId;\n}\n\nexport async function trackPageView(cartValue?: number, itemCount?: number): Promise<void> {\n if (!isInitialized()) return;\n if (typeof document === 'undefined') return;\n\n const config = getConfig();\n const connectionId = getPresenceConnectionId(config.storeSlug);\n\n try {\n const endpoint = buildEndpoint('/v1/storefront/shops/:storeSlug/ping', {\n storeSlug: config.storeSlug,\n });\n await fetch(`${config.apiBaseUrl}${endpoint}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n referer: document.referrer || undefined,\n cart_value: cartValue ?? undefined,\n item_count: itemCount ?? undefined,\n connection_id: connectionId ?? undefined,\n }),\n });\n } catch {\n // Intentionally silent - analytics should never block the user experience\n }\n}\n","/**\n * Formatting Utilities\n */\n\nimport { getConfig } from '../core/config';\n\nexport function createFormatter(\n currency?: string,\n locale?: string\n): Intl.NumberFormat {\n const config = getConfig();\n\n return new Intl.NumberFormat(locale ?? config.locale ?? 'en-US', {\n style: 'currency',\n currency: currency ?? config.currency ?? 'USD',\n });\n}\n\nexport function formatPrice(\n amount: number | string,\n currency?: string,\n locale?: string\n): string {\n const numericAmount = typeof amount === 'string' ? parseFloat(amount) : amount;\n if (Number.isNaN(numericAmount)) {\n return createFormatter(currency, locale).format(0);\n }\n return createFormatter(currency, locale).format(numericAmount);\n}\n","import type { ThemeConfig, ResolvedThemeSettings } from '../types/theme-config';\nimport { get } from '../core/client';\nimport { buildEndpoint } from '../core/endpoint';\n\nexport async function fetchPublishedThemeSettings(\n shopSlug: string\n): Promise<ResolvedThemeSettings | null> {\n const result = await get<{ settings: ResolvedThemeSettings }>(\n buildEndpoint('/v1/storefront/themes/builder/published/:shopSlug', { shopSlug })\n );\n return result.success && result.data ? result.data.settings : null;\n}\n\nexport function resolveDefaults(config: ThemeConfig): ResolvedThemeSettings {\n const resolved: ResolvedThemeSettings = {};\n for (const [category, fields] of Object.entries(config.settings)) {\n resolved[category] = {};\n for (const [key, field] of Object.entries(fields)) {\n resolved[category][key] = field.default;\n }\n }\n return resolved;\n}\n\nexport function mergeSettings(\n defaults: ResolvedThemeSettings,\n overrides: Partial<ResolvedThemeSettings>\n): ResolvedThemeSettings {\n const merged = { ...defaults };\n for (const [category, fields] of Object.entries(overrides)) {\n if (fields) {\n merged[category] = { ...merged[category], ...fields };\n }\n }\n return merged;\n}\n","/**\n * Shoppex Storefront SDK\n *\n * Usage:\n * ```html\n * <script src=\"https://cdn.shoppex.io/sdk/v1/shoppex.min.js\"></script>\n * <script>\n * shoppex.init('my-store');\n *\n * shoppex.getStore().then(store => console.log(store));\n * shoppex.addToCart('product-id', 'variant-id', 2);\n * shoppex.checkout();\n * </script>\n * ```\n */\n\nimport { initConfig, isInitialized, getConfig } from './core/config';\nimport type { ShoppexInitOptions } from './types';\n\n// Re-export types\nexport * from './types';\nexport * from './core/errors';\nexport type {\n ThemeConfig,\n SettingField,\n SectionDefinition,\n ResolvedThemeSettings,\n} from './types/theme-config';\nexport type { NavigationMenuSlot } from '@shoppex/contracts/navigation';\n\n// Store module\nimport {\n getStore,\n getStorefront,\n getStoreLogoUrl,\n getStoreBannerUrl,\n resolveStoreByDomain,\n} from './modules/store';\n\n// Products module\nimport { getProducts, getProduct, getCategories } from './modules/products';\n\n// Cart module\nimport {\n getCart,\n getCartItemCount,\n addToCart,\n updateCartItem,\n removeFromCart,\n clearCart,\n createCartBackup,\n restoreCartFromBackup,\n mergeBaskets,\n moveBasketItem,\n getCartStats,\n validateCartIntegrity,\n} from './modules/cart';\n\n// Checkout module\nimport { checkout, buildCheckoutUrl, buildCheckoutUrlSync } from './modules/checkout';\n\n// Affiliate module\nimport { captureAffiliateFromUrl, getAffiliateCode, clearAffiliateCode } from './modules/affiliates';\n\n// Coupons module\nimport { validateCoupon } from './modules/coupons';\n\n// Reviews module\nimport { getShopReviews } from './modules/reviews';\n\n// Search module\nimport { searchProducts } from './modules/search';\n\n// Invoices module\nimport { getInvoice, getInvoiceStatus } from './modules/invoices';\n\n// Pages module\nimport { getPages, getPage } from './modules/pages';\n\n// Navigation module\nimport { getMenus, getMenuBySlot, getMenuByTitle, getMenuSlotTitles } from './modules/navigation';\n\n// Analytics module\nimport { trackPageView } from './modules/analytics';\n\n// Format utilities\nimport { createFormatter, formatPrice } from './utils/format';\nimport { clearCache, invalidateCache, getCacheStats } from './core/cache';\nimport { fetchPublishedThemeSettings, resolveDefaults, mergeSettings } from './modules/theme';\n\nexport { fetchPublishedThemeSettings, resolveDefaults, mergeSettings } from './modules/theme';\nexport { trackPageView } from './modules/analytics';\nexport { getMenuBySlot, getMenuByTitle, getMenuSlotTitles } from './modules/navigation';\n\n/**\n * Initialize the SDK with a store slug\n */\nfunction init(storeSlug: string, options?: ShoppexInitOptions): void;\nfunction init(options: ShoppexInitOptions & { storeId: string }): void;\nfunction init(\n storeSlugOrOptions: string | (ShoppexInitOptions & { storeId: string }),\n options?: ShoppexInitOptions\n): void {\n if (typeof storeSlugOrOptions === 'string') {\n initConfig(storeSlugOrOptions, options);\n } else {\n initConfig(storeSlugOrOptions.storeId, storeSlugOrOptions);\n }\n}\n\n/**\n * Shoppex SDK instance\n */\nexport const shoppex = {\n // Initialization\n init,\n isInitialized,\n getConfig,\n\n // Store\n getStore,\n getStorefront,\n getStoreLogoUrl,\n getStoreBannerUrl,\n resolveStoreByDomain,\n\n // Products\n getProducts,\n getProduct,\n getCategories,\n\n // Cart\n getCart,\n getCartItemCount,\n addToCart,\n updateCartItem,\n removeFromCart,\n clearCart,\n createCartBackup,\n restoreCartFromBackup,\n mergeBaskets,\n moveBasketItem,\n getCartStats,\n validateCartIntegrity,\n\n // Checkout\n checkout,\n buildCheckoutUrl,\n buildCheckoutUrlSync,\n\n // Affiliates\n captureAffiliateFromUrl,\n getAffiliateCode,\n clearAffiliateCode,\n\n // Coupons\n validateCoupon,\n\n // Reviews\n getShopReviews,\n\n // Search\n searchProducts,\n\n // Invoices\n getInvoice,\n getInvoiceStatus,\n\n // Pages\n getPages,\n getPage,\n\n // Navigation\n getMenus,\n getMenuBySlot,\n getMenuByTitle,\n getMenuSlotTitles,\n\n // Analytics\n trackPageView,\n\n // Formatting\n createFormatter,\n formatPrice,\n\n // Cache\n clearCache,\n invalidateCache,\n getCacheStats,\n\n // Theme settings helpers\n fetchPublishedThemeSettings,\n resolveDefaults,\n mergeSettings,\n};\n\n// Default export for ES modules\nexport default shoppex;\n\n// UMD global exposure\nif (typeof window !== 'undefined') {\n (window as unknown as { shoppex: typeof shoppex }).shoppex = shoppex;\n}\n"],"mappings":"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","names":["cache","cachedShopId"]}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@shoppexio/storefront",
3
+ "version": "0.1.0",
4
+ "description": "Public npm package for the Shoppex Storefront SDK",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ShoppexIO/storefront-js.git"
9
+ },
10
+ "homepage": "https://docs.shoppex.io/sdk/introduction",
11
+ "bugs": {
12
+ "url": "https://github.com/ShoppexIO/storefront-js/issues"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "main": "./dist/index.js",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "CHANGELOG.md",
31
+ "LICENSE"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "dev": "tsup --watch",
36
+ "lint": "biome lint src",
37
+ "typecheck": "tsc --noEmit"
38
+ },
39
+ "keywords": [
40
+ "shoppex",
41
+ "storefront",
42
+ "sdk",
43
+ "checkout"
44
+ ],
45
+ "author": "Shoppex",
46
+ "license": "MIT",
47
+ "devDependencies": {
48
+ "@shoppex/contracts": "0.1.0",
49
+ "tsup": "^8.5.0",
50
+ "typescript": "^5.8.3"
51
+ }
52
+ }