@kasuvia/sdk 0.0.6 → 0.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/types/store/index.ts","../src/services/cart.service.ts","../src/services/order.service.ts","../src/services/auth.service.ts","../src/services/product.service.ts","../src/services/collection.service.ts","../src/services/wishlist.service.ts","../src/services/payment.service.ts","../src/services/consultation.service.ts","../src/services/logistics.service.ts","../src/services/bespoke.service.ts","../src/services/service-booking.service.ts","../src/services/notifications.service.ts","../src/services/app.service.ts","../src/services/config.service.ts","../src/services/cms.service.ts","../src/utils/cache.ts","../src/utils/logger.ts","../src/utils/sanitize-url.ts","../src/utils/customer.ts","../src/utils/checkout.ts","../src/utils/error-handler.ts","../src/utils/storage.ts","../src/utils/validators.ts"],"sourcesContent":["/**\n * SDK Constants\n * \n * Centralized constants to avoid hardcoded strings across the codebase.\n */\n\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'kasuvia_access_token',\n REFRESH_TOKEN: 'kasuvia_refresh_token',\n CHECKOUT_STATE: 'kasuvia_checkout_state',\n ORDERS_LINKED: 'kasuvia_orders_linked',\n STOREFRONT_STATE: 'storefront_state_v3',\n} as const;\n","import type { DeliveryAddress } from \"./shipping\";\n\nexport * from \"./shipping\";\nexport type { DeliveryAddress };\n\nexport type ProductType = \"physical\" | \"digital\" | \"service\" | \"bespoke\";\n\nexport enum ServiceTypeEnum {\n APPOINTMENT = 'appointment',\n PROJECT = 'project',\n RECURRING = 'recurring',\n}\n\nexport type ServiceType = ServiceTypeEnum | 'appointment' | 'project' | 'recurring'\n\nexport enum ServiceLocationTypeEnum {\n REMOTE = 'remote',\n PHYSICAL = 'physical',\n BOTH = 'both',\n}\n\nexport type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | 'physical' | 'both'\n\nexport enum ServiceRecurringIntervalEnum {\n WEEKLY = 'weekly',\n MONTHLY = 'monthly',\n YEARLY = 'yearly',\n}\n\nexport type ServiceRecurringInterval = ServiceRecurringIntervalEnum | 'weekly' | 'monthly' | 'yearly' | ''\n\nexport interface Address {\n street: string\n city: string\n state: string\n country: string\n zip?: string\n}\n\nexport interface Collection {\n id: string\n business_id?: string\n name: string\n slug: string\n description?: string\n image?: string\n collection_type?: string\n rules?: Record<string, unknown>\n status?: string\n sort_order?: number\n created_at: string\n updated_at: string\n}\n\nexport interface Inventory {\n id: string\n product_id: string\n variant_id?: string\n quantity: number\n reserved: number\n reorder_point: number\n reorder_quantity: number\n track_quantity: boolean\n allow_backorder: boolean\n available: number\n is_in_stock: boolean\n is_low_stock: boolean\n updated_at: string\n}\n\nexport interface ProductVariant {\n id: string\n product_id: string\n sku?: string\n attributes: Record<string, string>\n price?: number\n images: string[]\n weight_kg?: number\n is_active: boolean\n inventory?: Inventory\n created_at: string\n updated_at: string\n}\n\nexport interface CustomField {\n label: string\n unit?: string\n required: boolean\n type?: string\n key?: string\n placeholder?: string\n}\n\nexport interface Product {\n id: string\n business_id: string\n name: string\n slug: string\n description?: string\n brand?: string\n product_type: ProductType\n requires_shipping: boolean\n is_consumable: boolean\n is_bespoke: boolean\n is_physical?: boolean | null // For bespoke products: indicates if custom item requires physical delivery\n base_price: number\n currency: string\n sale_price?: number\n sale_start?: string\n sale_end?: string\n images: string[]\n tags: string[]\n custom_fields: CustomField[]\n is_published: boolean\n is_featured: boolean\n is_popular: boolean\n is_new: boolean\n is_temporary: boolean\n digital_file_key?: string\n download_limit?: number\n download_expires_at?: string\n // Service-specific fields\n service_type?: ServiceType | null\n service_duration_minutes?: number | null\n service_location_type?: ServiceLocationType | null\n service_requires_consultation?: boolean\n service_max_capacity_per_slot?: number | null\n service_buffer_minutes?: number\n service_is_recurring?: boolean\n service_recurring_interval?: ServiceRecurringInterval | null\n service_project_based?: boolean\n weight_kg: number\n length_cm?: number\n width_cm?: number\n height_cm?: number\n created_at: string\n updated_at: string\n variants: ProductVariant[]\n collections: Collection[]\n}\n\nexport interface ListParams {\n page?: number\n pageSize?: number\n search?: string\n ordering?: string\n collectionSlug?: string\n excludeProductId?: string\n}\n\nexport interface PaginatedResponse<T> {\n items: T[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\n// ============================================================================\n// CART TYPES\n// ============================================================================\n\nexport interface CartItem {\n id: string\n product_id: string\n product_slug: string\n product_name: string\n image?: string\n variant_id?: string\n variant_attributes?: string | Record<string, string>\n unit_price: number\n quantity: number\n custom_measurements?: string\n is_bespoke: boolean\n created_at: string\n updated_at: string\n}\n\nexport interface CartResponse {\n items: CartItem[]\n subtotal: number\n total: number\n item_count: number\n product_type?: string // \"physical\", \"digital\", \"bespoke\"\n}\n\n// ============================================================================\n// WISHLIST TYPES\n// ============================================================================\n\nexport interface WishlistItem {\n id: string\n product_id: string\n notes?: string\n created_at: string\n product_name?: string\n product_slug?: string\n product_price?: number\n product_image?: string\n}\n\nexport interface WishlistListResponse {\n items: WishlistItem[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport interface WishlistCheckResponse {\n in_wishlist: boolean\n}\n\nexport type OrderStatus =\n | 'pending'\n | 'confirmed'\n | 'processing'\n | 'packed'\n | 'picked_up'\n | 'in_transit'\n | 'shipped'\n | 'delivered'\n | 'voided'\n | 'refunded'\n | 'failed';\nexport type BespokeStageKey = \"received\" | \"development\" | \"finished\" | \"dispatched\";\n\nexport interface OrderItem {\n id: string;\n productName: string;\n image: string;\n quantity: number;\n price: number;\n}\n\nexport interface Order {\n id: string;\n display_id?: string;\n items: OrderItem[];\n total: number;\n status: OrderStatus;\n customerEmail: string;\n customerName: string;\n createdAt: number;\n updatedAt: number;\n deliveryMethod?: string;\n trackingNumber?: string;\n deliveryAddress?: string;\n shippingAddress?: DeliveryAddress;\n cancellationReason?: string;\n hasBespoke?: boolean;\n bespokeStage?: BespokeStageKey;\n bespokeBrief?: string;\n deliveryStatus?: string;\n carrierName?: string;\n terminalShipmentId?: string;\n guestToken?: string;\n guestEmail?: string;\n guestPhone?: string;\n guestName?: string;\n}\n\n// ============================================================================\n// CHECKOUT TYPES\n// ============================================================================\n\nexport interface CheckoutCustomer {\n first_name: string;\n last_name: string;\n email: string;\n phone: string;\n}\n\nexport interface ShippingLocation {\n street: string;\n city: string;\n state: string;\n lga: string;\n country: string;\n postal: string;\n}\n\n// ============================================================================\n// ORDER SERVICE PARAMS\n// ============================================================================\n\nexport interface FindOrderParams {\n email: string;\n order_id: string;\n}\n\nexport interface CreateOrderParams {\n customer_id?: string | null;\n status?: string;\n shipping_address?: DeliveryAddress;\n checkout_session_id?: string;\n items: Array<{\n product_id: string;\n product_name: string;\n quantity: number;\n unit_price: number;\n variant_id?: string;\n variant_details?: Record<string, unknown>;\n custom_measurements?: Record<string, unknown>;\n }>;\n delivery_method?: string;\n delivery_address?: string;\n total?: number;\n payment_method?: string;\n shipping_rate_id?: string;\n guest_token?: string;\n guest_email?: string;\n guest_phone?: string;\n guest_name?: string;\n product_type?: string;\n bespoke_brief?: string;\n bespoke_reference_images?: string[];\n bespoke_measurements?: Record<string, string>;\n bespoke_preferred_timeline?: string;\n bespoke_special_instructions?: string;\n}\n","/**\n * Cart Service\n * \n * Handles cart operations for both guest and authenticated users.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { CartItem, CartResponse } from '../types/store'\n\nfunction parseItems(items: CartItem[]): CartItem[] {\n return items.map((item) => ({\n ...item,\n variant_attributes:\n item.variant_attributes && typeof item.variant_attributes === \"string\"\n ? JSON.parse(item.variant_attributes)\n : item.variant_attributes,\n }));\n}\n\n/**\n * Fetch guest cart from backend (Redis-backed).\n */\nexport async function getGuestCart(config: SdkConfig, guestSessionId: string): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n try {\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n } catch {\n return []\n }\n}\n\n/**\n * Add item to guest cart (Redis-backed).\n */\nexport async function addToGuestCart(config: SdkConfig, guestSessionId: string, item: CartItem): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n const payload = {\n product_id: item.product_id,\n product_slug: item.product_slug,\n product_name: item.product_name,\n image: item.image,\n variant_id: item.variant_id,\n variant_attributes:\n typeof item.variant_attributes === \"string\"\n ? item.variant_attributes\n : JSON.stringify(item.variant_attributes),\n unit_price: item.unit_price,\n quantity: item.quantity,\n custom_measurements: item.custom_measurements,\n is_bespoke: item.is_bespoke,\n }\n\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n}\n\n/**\n * Update quantity of a guest cart item.\n */\nexport async function updateGuestCartItemQuantity(\n config: SdkConfig,\n guestSessionId: string,\n itemId: string,\n quantity: number\n): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'PATCH',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n body: JSON.stringify({ quantity }),\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n}\n\n/**\n * Remove an item from the guest cart.\n */\nexport async function removeFromGuestCart(\n config: SdkConfig,\n guestSessionId: string,\n itemId: string\n): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'DELETE',\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n\n return getGuestCart(config, guestSessionId)\n}\n\n/**\n * Clear the entire guest cart.\n */\nexport async function clearGuestCart(config: SdkConfig, guestSessionId: string): Promise<void> {\n if (!guestSessionId) return\n\n await fetch(`${config.backendUrls.store}/cart/clear`, {\n method: 'DELETE',\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n}\n\n/**\n * Fetch authenticated user's cart from backend.\n */\nexport async function getCart(config: SdkConfig, accessToken?: string | null): Promise<CartResponse> {\n if (!accessToken) {\n return { id: '', items: [], subtotal: 0, total: 0, product_type: 'physical' } as any;\n }\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to fetch cart')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Add item to authenticated user's cart.\n */\nexport async function addToCart(\n config: SdkConfig,\n accessToken: string,\n item: {\n product_id: string\n product_slug: string\n product_name: string\n image?: string\n variant_id?: string\n variant_attributes?: string\n unit_price: number\n quantity: number\n custom_measurements?: string\n is_bespoke: boolean\n }\n): Promise<CartResponse> {\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(item),\n })\n if (!response.ok) throw new Error('Failed to add to cart')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Update item quantity in authenticated user's cart.\n */\nexport async function updateCartItem(\n config: SdkConfig,\n accessToken: string,\n itemId: string,\n quantity: number\n): Promise<CartResponse> {\n const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'PATCH',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ quantity }),\n })\n if (!response.ok) throw new Error('Failed to update cart item')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Remove item from authenticated user's cart.\n */\nexport async function removeFromCart(\n config: SdkConfig,\n accessToken: string,\n itemId: string\n): Promise<CartResponse> {\n await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'DELETE',\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n return getCart(config, accessToken)\n}\n\n/**\n * Clear authenticated user's cart.\n */\nexport async function clearCart(config: SdkConfig, accessToken: string): Promise<void> {\n await fetch(`${config.backendUrls.store}/cart/clear`, {\n method: 'DELETE',\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n}\n\n/**\n * Merge guest cart (from Redis) into authenticated user's DB cart.\n */\nexport async function mergeGuestCart(\n config: SdkConfig,\n accessToken: string,\n guestSessionId: string\n): Promise<CartResponse> {\n const guestItems = guestSessionId ? await getGuestCart(config, guestSessionId) : []\n \n if (guestItems.length === 0) {\n return getCart(config, accessToken)\n }\n\n const payloadItems = guestItems.map((item) => ({\n product_id: item.product_id,\n product_slug: item.product_slug,\n product_name: item.product_name,\n image: item.image,\n variant_id: item.variant_id,\n variant_attributes:\n typeof item.variant_attributes === \"string\"\n ? item.variant_attributes\n : JSON.stringify(item.variant_attributes ?? {}),\n unit_price: item.unit_price,\n quantity: item.quantity,\n custom_measurements:\n typeof item.custom_measurements === \"string\"\n ? item.custom_measurements\n : JSON.stringify(item.custom_measurements ?? {}),\n is_bespoke: item.is_bespoke,\n }))\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n }\n if (guestSessionId) {\n headers[\"X-Guest-Session\"] = guestSessionId\n }\n\n const response = await fetch(`${config.backendUrls.store}/cart/merge`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ items: payloadItems }),\n })\n if (!response.ok) throw new Error('Failed to merge guest cart')\n const data = await response.json()\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Convenience wrapper: merge guest cart if it has items (called post-login).\n */\nexport async function mergeGuestCartIfPresent(\n config: SdkConfig,\n accessToken: string,\n guestSessionId: string\n): Promise<void> {\n try {\n const guestItems = await getGuestCart(config, guestSessionId)\n if (guestItems.length === 0) return\n await mergeGuestCart(config, accessToken, guestSessionId)\n } catch (error) {\n console.warn(\"[Cart] Failed to merge guest cart:\", error)\n }\n}\n\n/**\n * Returns 0 — count is now server-driven. Use the hook instead.\n * Kept for backward compatibility.\n */\nexport function getGuestCartCount(): number {\n return 0\n}\n\n/**\n * Returns 0 — subtotal is now server-driven.\n * Kept for backward compatibility.\n */\nexport function getGuestCartSubtotal(): number {\n return 0\n}\n\n/**\n * Derive product type from items (guest cart, no backend lookup needed).\n */\nexport function getGuestCartProductType(): \"physical\" | \"digital\" | \"bespoke\" {\n return \"physical\"\n}\n","/**\n * Order Service\n * \n * Handles order operations including creation, lookup, and tracking.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { Order, OrderStatus, FindOrderParams, CreateOrderParams, OrderItem } from '../types/store'\nimport type { DeliveryAddress } from '../types/store'\n\nexport type { FindOrderParams, CreateOrderParams, OrderStatus }\n\ninterface RawOrderItem {\n id: string\n product_name?: string\n productName?: string\n image?: string\n quantity?: number\n unit_price?: number\n price?: number\n}\n\ninterface RawShippingAddress {\n first_name?: string\n last_name?: string\n phone?: string\n street?: string\n city?: string\n state?: string\n country?: string\n postal?: string\n lga?: string\n}\n\ninterface RawOrder {\n id: string\n display_id?: string\n items?: RawOrderItem[]\n total_amount?: number\n total?: number\n status: OrderStatus\n customer_email?: string\n customer_name?: string\n guest_email?: string\n guest_phone?: string\n guest_name?: string\n guest_token?: string\n shipping_address?: RawShippingAddress | string | null\n delivery_method?: string\n tracking_number?: string\n delivery_status?: string\n carrier_name?: string\n terminal_shipment_id?: string\n product_type?: string\n bespoke_stage?: string\n bespoke_brief?: string\n created_at?: string\n updated_at?: string\n cancellation_reason?: string\n}\n\nfunction deriveCustomerName(raw: RawOrder): string {\n if (raw.customer_name) return raw.customer_name\n if (raw.guest_name) return raw.guest_name\n\n const addr = typeof raw.shipping_address === 'object' && raw.shipping_address !== null\n ? raw.shipping_address as RawShippingAddress\n : null\n if (addr) {\n const full = `${addr.first_name ?? ''} ${addr.last_name ?? ''}`.trim()\n if (full) return full\n }\n\n const email = raw.guest_email ?? raw.customer_email ?? ''\n if (email) return email.split('@')[0]\n\n return ''\n}\n\nfunction normaliseStorefrontOrder(raw: RawOrder): Order {\n const items: OrderItem[] = (raw.items ?? []).map((item) => ({\n id: item.id,\n productName: item.product_name ?? item.productName ?? '',\n image: item.image ?? '',\n quantity: item.quantity ?? 1,\n price: item.unit_price ?? item.price ?? 0,\n }))\n\n const addr = typeof raw.shipping_address === 'object' && raw.shipping_address !== null\n ? raw.shipping_address as RawShippingAddress\n : null\n\n return {\n id: raw.id,\n display_id: raw.display_id,\n items,\n total: raw.total_amount ?? raw.total ?? 0,\n status: raw.status,\n customerEmail: raw.guest_email ?? raw.customer_email ?? '',\n customerName: deriveCustomerName(raw),\n createdAt: raw.created_at ? new Date(raw.created_at).getTime() : Date.now(),\n updatedAt: raw.updated_at ? new Date(raw.updated_at).getTime() : Date.now(),\n deliveryMethod: raw.delivery_method,\n trackingNumber: raw.tracking_number,\n deliveryAddress: typeof raw.shipping_address === 'string'\n ? raw.shipping_address\n : addr\n ? `${addr.street}, ${addr.city}, ${addr.state}, ${addr.country}`\n : undefined,\n shippingAddress: addr\n ? {\n first_name: addr.first_name ?? '',\n last_name: addr.last_name ?? '',\n phone: addr.phone ?? '',\n street: addr.street ?? '',\n city: addr.city ?? '',\n state: addr.state ?? '',\n lga: addr.lga ?? '',\n country: addr.country ?? '',\n postal: addr.postal ?? '',\n }\n : undefined,\n cancellationReason: raw.cancellation_reason,\n hasBespoke: raw.product_type === 'bespoke',\n bespokeStage: raw.bespoke_stage as Order['bespokeStage'],\n bespokeBrief: raw.bespoke_brief,\n deliveryStatus: raw.delivery_status,\n carrierName: raw.carrier_name,\n terminalShipmentId: raw.terminal_shipment_id,\n guestToken: raw.guest_token,\n guestEmail: raw.guest_email,\n guestPhone: raw.guest_phone,\n guestName: raw.guest_name,\n }\n}\n\nexport async function createOrder(config: SdkConfig, accessToken: string, payload: CreateOrderParams): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/storefront`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to create order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function findOrder(config: SdkConfig, params: FindOrderParams & { guest_token?: string }): Promise<Order> {\n const queryParams = new URLSearchParams()\n if (params.email) queryParams.set('email', params.email)\n if (params.order_id) queryParams.set('order_id', params.order_id)\n if (params.guest_token) queryParams.set('guest_token', params.guest_token)\n \n const response = await fetch(`${config.backendUrls.store}/orders/find/?${queryParams.toString()}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to find order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function findOrderByToken(config: SdkConfig, token: string): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/find/?guest_token=${token}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to find order by token')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function getOrders(config: SdkConfig, accessToken: string, params?: { email?: string; page?: number; page_size?: number }): Promise<Order[]> {\n const queryParams = new URLSearchParams()\n if (params?.email) queryParams.set('email', params.email)\n if (params?.page) queryParams.set('page', params.page.toString())\n if (params?.page_size) queryParams.set('page_size', params.page_size.toString())\n \n const response = await fetch(`${config.backendUrls.store}/orders/?${queryParams.toString()}`, {\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get orders')\n const data = await response.json()\n const items: RawOrder[] = Array.isArray(data) ? data : (data.items ?? [])\n return items.map(normaliseStorefrontOrder)\n}\n\nexport async function cancelOrder(config: SdkConfig, accessToken: string, orderId: string, reason: string): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/${orderId}/cancel/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ reason }),\n })\n if (!response.ok) throw new Error('Failed to cancel order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function trackOrder(config: SdkConfig, orderId: string, token?: string): Promise<Order> {\n const queryParams = token ? `?token=${token}` : ''\n const response = await fetch(`${config.backendUrls.store}/orders/track/${orderId}${queryParams}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to track order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n","/**\n * Customer auth service — all API calls scoped to this storefront's business tenant.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport { logger } from '../utils/logger'\nimport { STORAGE_KEYS } from '../constants'\nimport type {\n CustomerAuthResponse,\n CustomerLoginPayload,\n CustomerRegisterPayload,\n LogoutPayload,\n RefreshTokenResponse,\n CustomerUser,\n AuthUserResponse,\n UpdateProfilePayload,\n} from '../types/auth'\n\n// ── Auth API Calls ────────────────────────────────────────────────────────────\n\n/**\n * POST /auth/login/customer/\n * The `tenant_id` is automatically filled from config.businessId.\n */\nexport async function loginCustomer(\n config: SdkConfig,\n payload: Omit<CustomerLoginPayload, 'tenant_id'>\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/login/customer/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n },\n body: JSON.stringify({\n ...payload,\n tenant_id: config.businessId,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Login failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/**\n * POST /auth/register/customer/\n * The `tenant_id` is automatically filled from config.businessId.\n */\nexport async function registerCustomer(\n config: SdkConfig,\n payload: Omit<CustomerRegisterPayload, 'tenant_id'>\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/register/customer/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n },\n body: JSON.stringify({\n ...payload,\n tenant_id: config.businessId,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Registration failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** POST /auth/token/refresh/\n */\nexport async function refreshToken(\n config: SdkConfig,\n refresh: string\n): Promise<RefreshTokenResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/token/refresh/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ refresh }),\n })\n\n if (!response.ok) {\n throw new Error('Token refresh failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** POST /auth/logout/ — revokes the server-side session. */\nexport async function logout(\n config: SdkConfig,\n refresh?: string\n): Promise<void> {\n const payload: LogoutPayload = refresh ? { refresh } : {}\n try {\n await fetch(`${config.backendUrls.auth}/auth/logout/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n })\n } catch {\n // Swallow server errors\n }\n}\n\n/**\n * Verify a social provider id_token (or access_token for Facebook) with the backend.\n */\nexport async function verifySocialToken(\n config: SdkConfig,\n provider: 'google' | 'facebook',\n token: string\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/social/verify/${provider}/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id_token: token,\n storefront_key: config.storefrontApiKey,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Social token verification failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** Decode a JWT payload without verifying signature (client-side use only). */\nfunction parseJwtPayload(token: string): Record<string, unknown> {\n try {\n return JSON.parse(atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')))\n } catch {\n return {}\n }\n}\n\nfunction resolveProvider(data: Pick<AuthUserResponse, 'is_google_auth_enabled' | 'is_facebook_auth_enabled'>): CustomerUser['provider'] {\n if (data.is_google_auth_enabled) return 'google'\n if (data.is_facebook_auth_enabled) return 'facebook'\n return 'email'\n}\n\nfunction resolveAvatar(profilePicture: unknown): string | null {\n if (!profilePicture) return null\n if (typeof profilePicture === 'string') return profilePicture\n if (typeof profilePicture === 'object' && profilePicture !== null && 'url' in profilePicture) {\n const url = (profilePicture as { url?: string }).url\n return typeof url === 'string' ? url : null\n }\n return null\n}\n\n/** Map kasuvia-auth UserSerializer response to storefront CustomerUser. */\nexport function mapAuthUserToCustomer(data: AuthUserResponse, provider?: CustomerUser['provider']): CustomerUser {\n const firstname = data.profile?.firstname?.trim() || undefined\n const lastname = data.profile?.lastname?.trim() || undefined\n const phone = data.profile?.phone?.trim() || undefined\n\n return {\n id: String(data.id),\n email: data.email,\n firstname,\n lastname,\n phone,\n full_name: buildFullName(firstname, lastname),\n avatar: resolveAvatar(data.profile?.profile_picture),\n provider: provider ?? resolveProvider(data),\n }\n}\n\nfunction buildCustomerFromClaims(claims: Record<string, unknown>): CustomerUser {\n const provider: CustomerUser['provider'] = claims.is_google_auth_enabled\n ? 'google'\n : claims.is_facebook_auth_enabled\n ? 'facebook'\n : 'email'\n\n const jwtFullName = String(claims.full_name ?? claims.name ?? '').trim() || undefined\n const { firstname: splitFirst, lastname: splitLast } = splitFullName(jwtFullName)\n\n return {\n id: String(claims.user_id ?? claims.sub ?? ''),\n email: String(claims.email ?? ''),\n firstname: splitFirst || undefined,\n lastname: splitLast || undefined,\n phone: String(claims.phone ?? '').trim() || undefined,\n full_name: jwtFullName,\n avatar: claims.avatar as string | null,\n provider,\n }\n}\n\n/** GET /auth/profile/ */\nexport async function getMe(config?: SdkConfig, accessToken?: string): Promise<CustomerUser> {\n if (!config || !accessToken) {\n const response = await fetch('/api/auth/me', { credentials: 'include' })\n if (!response.ok) throw new Error('Failed to fetch profile')\n const data = await response.json()\n return data.user\n }\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch profile')\n }\n\n const data = await response.json()\n return mapAuthUserToCustomer(data)\n}\n\n/** GET /auth/profile/ - alias for getMe for backward compatibility */\nexport async function getAuthUser(config?: SdkConfig, accessToken?: string): Promise<AuthUserResponse> {\n if (!config || !accessToken) {\n const response = await fetch('/api/auth/me', { credentials: 'include' })\n if (!response.ok) throw new Error('Failed to fetch auth user')\n const data = await response.json()\n return data.user\n }\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch auth user')\n }\n\n const data = await response.json()\n return data\n}\n\n/** PUT /auth/profile/ — update firstname, lastname, phone */\nexport async function updateProfile(\n configOrPayload: SdkConfig | UpdateProfilePayload,\n accessTokenOrPayload?: string | UpdateProfilePayload,\n payloadParam?: UpdateProfilePayload\n): Promise<CustomerUser> {\n const isArg1Config = typeof configOrPayload === 'object' && configOrPayload !== null && 'businessId' in configOrPayload\n if (!isArg1Config) {\n const payload = configOrPayload as UpdateProfilePayload\n const response = await fetch('/api/auth/profile', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include',\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to update profile')\n return response.json()\n }\n\n const config = configOrPayload as SdkConfig\n const accessToken = accessTokenOrPayload as string\n const payload = payloadParam as UpdateProfilePayload\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new Error('Failed to update profile')\n }\n\n const data = await response.json()\n return mapAuthUserToCustomer(data)\n}\n\n/**\n * Silently refresh the access token on app boot.\n * Builds CustomerUser from JWT claims — no additional profile API call needed.\n * Returns null if no refresh token exists or if the refresh fails.\n */\nexport async function silentRefresh(\n config: SdkConfig,\n refresh: string\n): Promise<{ user: CustomerUser; provider: CustomerUser['provider']; newAccessToken: string; newRefreshToken: string } | null> {\n try {\n const data = await refreshToken(config, refresh)\n if (!data.access || !data.refresh) {\n return null\n }\n const claims = parseJwtPayload(data.access)\n const user = buildCustomerFromClaims(claims)\n const provider = user.provider\n return { user, provider, newAccessToken: data.access, newRefreshToken: data.refresh }\n } catch {\n return null\n }\n}\n\n// ── Helper Functions ─────────────────────────────────────────────────────────\n\nfunction buildFullName(firstname?: string, lastname?: string): string {\n if (firstname && lastname) return `${firstname} ${lastname}`\n return firstname || lastname || ''\n}\n\nfunction splitFullName(fullName?: string): { firstname: string; lastname: string } {\n if (!fullName) return { firstname: '', lastname: '' }\n\n const parts = fullName.trim().split(/\\s+/)\n if (parts.length === 1) {\n return { firstname: parts[0], lastname: '' }\n }\n\n return {\n firstname: parts[0],\n lastname: parts.slice(1).join(' ')\n }\n}\n\n/**\n * Store tokens in localStorage (client-side utility)\n * This is a convenience function for storefronts to store auth tokens\n */\nexport function storeTokens(accessToken: string, refreshToken: string): void {\n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, accessToken)\n localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refreshToken)\n }\n}\n\n/**\n * Clear tokens from localStorage (client-side utility)\n */\nexport function clearTokens(): void {\n if (typeof window !== 'undefined') {\n localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN)\n localStorage.removeItem(STORAGE_KEYS.REFRESH_TOKEN)\n }\n}\n\n/**\n * Get stored tokens from localStorage (client-side utility)\n */\nexport function getStoredTokens(): { accessToken: string | null; refreshToken: string | null } {\n if (typeof window === 'undefined') {\n return { accessToken: null, refreshToken: null }\n }\n return {\n accessToken: localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN),\n refreshToken: localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN),\n }\n}\n","/**\n * Product Service\n * \n * Handles product operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { Product, PaginatedResponse, ListParams } from '../types/store'\nimport type { SdkConfig } from '../config'\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\nconst GET_STOREFRONT_PRODUCTS = `\n query GetStorefrontProducts($page: Int!, $pageSize: Int!, $collectionSlug: String, $search: String) {\n storefront_products(page: $page, pageSize: $pageSize, collectionSlug: $collectionSlug, search: $search) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_PRODUCT_BY_SLUG = `\n query GetStorefrontProductBySlug($slug: String!) {\n storefront_product_by_slug(slug: $slug) {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n }\n`\n\nconst GET_STOREFRONT_LATEST = `\n query GetStorefrontLatest($page: Int!, $pageSize: Int!) {\n storefront_latest(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_POPULAR = `\n query GetStorefrontPopular($page: Int!, $pageSize: Int!) {\n storefront_popular(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_FEATURED = `\n query GetStorefrontFeatured($page: Int!, $pageSize: Int!) {\n storefront_featured(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_NEW = `\n query GetStorefrontNew($page: Int!, $pageSize: Int!) {\n storefront_new(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_ON_SALE = `\n query GetStorefrontOnSale($page: Int!, $pageSize: Int!) {\n storefront_on_sale(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_LOW_STOCK = `\n query GetStorefrontLowStock($page: Int!, $pageSize: Int!) {\n storefront_low_stock(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_RECOMMENDED = `\n query GetStorefrontRecommended($page: Int!, $pageSize: Int!, $excludeProductId: String) {\n storefront_recommended(page: $page, pageSize: $pageSize, excludeProductId: $excludeProductId) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\n/**\n * Fetch all active products for the storefront.\n */\nexport async function getStorefrontProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n collectionSlug: params?.collectionSlug,\n search: params?.search,\n }\n const data = await client.request(GET_STOREFRONT_PRODUCTS, variables)\n return data.storefront_products\n}\n\n/**\n * Fetch a single product by slug for the storefront.\n */\nexport async function getStorefrontProductBySlug(\n config: SdkConfig,\n slug: string\n): Promise<Product> {\n const client = createGraphQLClient(config)\n const data = await client.request(GET_STOREFRONT_PRODUCT_BY_SLUG, { slug })\n return data.storefront_product_by_slug\n}\n\n/**\n * Fetch latest products for the storefront.\n */\nexport async function getLatestProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_LATEST, variables)\n return data.storefront_latest\n}\n\n/**\n * Fetch popular products for the storefront.\n */\nexport async function getPopularProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_POPULAR, variables)\n return data.storefront_popular\n}\n\n/**\n * Fetch featured products for the storefront.\n */\nexport async function getFeaturedProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_FEATURED, variables)\n return data.storefront_featured\n}\n\n/**\n * Fetch new products for the storefront.\n */\nexport async function getNewProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_NEW, variables)\n return data.storefront_new\n}\n\n/**\n * Fetch products currently on sale for the storefront.\n */\nexport async function getOnSaleProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_ON_SALE, variables)\n return data.storefront_on_sale\n}\n\n/**\n * Fetch products with low stock for the storefront.\n */\nexport async function getLowStockProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_LOW_STOCK, variables)\n return data.storefront_low_stock\n}\n\n/**\n * Fetch recommended products for the storefront.\n * Returns featured, popular, and new products.\n * Optionally excludes a specific product ID.\n */\nexport async function getRecommendedProducts(\n config: SdkConfig,\n params?: ListParams & { excludeProductId?: string }\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n excludeProductId: params?.excludeProductId,\n }\n const data = await client.request(GET_STOREFRONT_RECOMMENDED, variables)\n return data.storefront_recommended\n}\n\n","/**\n * Collection Service\n * \n * Handles collection operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { Collection, PaginatedResponse, ListParams } from '../types/store'\nimport type { SdkConfig } from '../config'\n\nconst GET_STOREFRONT_COLLECTIONS = `\n query GetStorefrontCollections($page: Int!, $pageSize: Int!) {\n storefront_collections(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n image \n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_COLLECTION_BY_SLUG = `\n query GetStorefrontCollectionBySlug($slug: String!) {\n storefront_collection_by_slug(slug: $slug) {\n id\n business_id\n name\n slug\n description\n image \n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n`\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\n/**\n * Fetch paginated active collections for the storefront.\n */\nexport async function getStorefrontCollections(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Collection>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n }\n const data = await client.request(GET_STOREFRONT_COLLECTIONS, variables)\n return data.storefront_collections\n}\n\n/**\n * Fetch a single collection by its slug.\n */\nexport async function getStorefrontCollectionBySlug(\n config: SdkConfig,\n slug: string\n): Promise<Collection> {\n const client = createGraphQLClient(config)\n const data = await client.request(GET_STOREFRONT_COLLECTION_BY_SLUG, { slug })\n return data.storefront_collection_by_slug\n}\n","/**\n * Wishlist Service\n * \n * Handles wishlist operations.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { SdkConfig } from '../config'\nimport type { WishlistItem, WishlistListResponse, WishlistCheckResponse } from '../types/store'\n\nconst GET_STOREFRONT_WISHLIST = `\n query GetStorefrontWishlist($page: Int!, $pageSize: Int!) {\n storefront_wishlist(page: $page, pageSize: $pageSize) {\n items {\n id\n product_id\n notes\n created_at\n product_name\n product_slug\n product_price\n currency\n product_image\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst CHECK_IN_STOREFRONT_WISHLIST = `\n query CheckInStorefrontWishlist($productId: String!) {\n check_in_storefront_wishlist(productId: $productId) {\n in_wishlist\n }\n }\n`\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig, accessToken?: string): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n if (accessToken) {\n headers['Authorization'] = `Bearer ${accessToken}`\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\n/**\n * Fetch the customer's wishlist for the current business.\n */\nexport async function getWishlist(config: SdkConfig, accessToken: string, params?: { page?: number; pageSize?: number }): Promise<WishlistListResponse> {\n const client = createGraphQLClient(config, accessToken)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n }\n const data = await client.request(GET_STOREFRONT_WISHLIST, variables)\n return data.storefront_wishlist\n}\n\n/**\n * Check if a product is in the customer's wishlist.\n */\nexport async function checkInWishlist(config: SdkConfig, accessToken: string, productId: string): Promise<WishlistCheckResponse> {\n const client = createGraphQLClient(config, accessToken)\n const data = await client.request(CHECK_IN_STOREFRONT_WISHLIST, { productId })\n return data.check_in_storefront_wishlist\n}\n\n/**\n * Add a product to the customer's wishlist.\n */\nexport async function addToWishlist(config: SdkConfig, accessToken: string, productId: string, notes?: string): Promise<WishlistItem> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n product_id: productId,\n notes: notes || undefined,\n }),\n })\n if (!response.ok) throw new Error('Failed to add to wishlist')\n return response.json()\n}\n\n/**\n * Remove an item from the customer's wishlist by item ID.\n */\nexport async function removeFromWishlist(config: SdkConfig, accessToken: string, itemId: string): Promise<void> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/${itemId}`, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to remove from wishlist')\n}\n\n/**\n * Remove a product from the customer's wishlist by product ID.\n */\nexport async function removeProductFromWishlist(config: SdkConfig, accessToken: string, productId: string): Promise<void> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/product/${productId}`, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to remove product from wishlist')\n}\n","/**\n * Payment Service\n * \n * Customer-facing payment API for payment initiation and verification.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n ConversionQuote,\n DVACreateRequest,\n DVADetails,\n PaymentInitiateRequest,\n PaymentInitiateResponse,\n TransactionVerifyResponse,\n} from '../types/payments/index'\n\n/**\n * Create a Monnify Dedicated Virtual Account so the customer can pay via\n * bank transfer. Note: Monnify DVA only supports NGN currency - the backend\n * will reject non-NGN requests for this payment method.\n */\nexport async function createDedicatedAccount(\n config: SdkConfig,\n accessToken: string,\n request: DVACreateRequest\n): Promise<DVADetails> {\n const isValidUUID = (str: string) => {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(str);\n }\n\n const response = await fetch(`${config.backendUrls.payment}/payments/dedicated-account`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n order_id: request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined,\n amount: request.amount,\n customer_email: request.customer_email,\n customer_name: request.customer_name,\n currency: request.currency,\n idempotency_key: request.idempotency_key,\n }),\n })\n if (!response.ok) throw new Error('Failed to create dedicated account')\n const data = await response.json()\n return data\n}\n\n/**\n * Initiate a card payment (customer → business owner).\n * Routes to Monnify (NGN) or Flutterwave (non-NGN) on the backend.\n * Returns a checkout_url to redirect the customer to the gateway.\n */\nexport async function initiatePayment(\n config: SdkConfig,\n accessToken: string,\n request: PaymentInitiateRequest\n): Promise<PaymentInitiateResponse> {\n const isValidUUID = (str: string) => {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(str);\n }\n\n const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined;\n\n const response = await fetch(`${config.backendUrls.payment}/payments/storefront/initiate`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n amount: request.amount,\n currency: request.currency,\n order_id: validOrderId,\n quote_id: request.quote_id,\n metadata_json: {\n customer_email: request.customer_email,\n customer_name: request.customer_name ?? '',\n order_id: validOrderId,\n ...(request.metadata ?? {}),\n },\n idempotency_key: request.idempotency_key,\n }),\n })\n if (!response.ok) throw new Error('Failed to initiate payment')\n const data = await response.json()\n\n return {\n id: data.id,\n gateway_ref: data.gateway_ref,\n gateway: data.gateway,\n status: data.status,\n checkout_url: data.metadata_json?.checkout_url ?? '',\n }\n}\n\n/**\n * Request a 15-minute rate-locked conversion quote for non-NGN transactions.\n */\nexport async function requestQuote(\n config: SdkConfig,\n amount: number\n): Promise<ConversionQuote> {\n const response = await fetch(`${config.backendUrls.payment}/payments/quote`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ amount }),\n })\n if (!response.ok) throw new Error('Failed to request quote')\n const data = await response.json()\n return data\n}\n\n/**\n * Verify a payment after the gateway redirects back to /checkout/verify.\n */\nexport async function verifyTransaction(\n configOrReference: SdkConfig | string,\n reference?: string\n): Promise<TransactionVerifyResponse> {\n if (typeof configOrReference === 'string') {\n const ref = configOrReference\n const response = await fetch(`/api/payments/verify/${ref}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n })\n if (!response.ok) throw new Error('Failed to verify transaction')\n return response.json()\n }\n\n const config = configOrReference\n const ref = reference || ''\n const response = await fetch(`${config.backendUrls.payment}/payments/verify/${ref}`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to verify transaction')\n const data = await response.json()\n return data\n}\n\n/**\n * Poll transaction status by internal transaction ID.\n */\nexport async function getTransactionStatus(\n config: SdkConfig,\n transactionId: string\n): Promise<TransactionVerifyResponse> {\n const response = await fetch(`${config.backendUrls.payment}/payments/transactions/${transactionId}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get transaction status')\n const data = await response.json()\n return data\n}\n\nexport const paymentService = {\n createDedicatedAccount,\n initiatePayment,\n requestQuote,\n verifyTransaction,\n getTransactionStatus,\n} as const\n","/**\n * Consultation Service\n * \n * Handles consultation operations for bespoke and service products.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n Consultation,\n ConsultationCreatePayload,\n ConsultationMessagePayload,\n ConsultationQuoteAcceptPayload,\n} from '../types/consultations'\n\nexport async function createConsultation(config: SdkConfig, accessToken: string, payload: ConsultationCreatePayload): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to create consultation')\n return response.json()\n}\n\nexport async function getConsultations(config: SdkConfig, accessToken: string): Promise<Consultation[]> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get consultations')\n return response.json()\n}\n\nexport async function getConsultation(config: SdkConfig, accessToken: string, id: string): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get consultation')\n return response.json()\n}\n\nexport async function sendMessage(config: SdkConfig, accessToken: string, id: string, payload: ConsultationMessagePayload): Promise<void> {\n await fetch(`${config.backendUrls.store}/social/consultations/${id}/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n}\n\nexport async function acceptQuote(config: SdkConfig, accessToken: string, id: string, payload: ConsultationQuoteAcceptPayload): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/accept-quote`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to accept quote')\n return response.json()\n}\n\nexport async function rejectQuote(config: SdkConfig, accessToken: string, id: string, reason?: string): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/reject-quote`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ reason }),\n })\n if (!response.ok) throw new Error('Failed to reject quote')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const consultationService = {\n createConsultation,\n getConsultations,\n getConsultation,\n sendMessage,\n acceptQuote,\n rejectQuote,\n}\n","/**\n * Logistics Service\n * \n * Handles shipping rates and address validation.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { ShippingRatesResponse } from '../types/store/shipping'\nimport type { Product, ProductVariant } from '../types/store'\n\nexport interface CartItemPayload {\n product: {\n name: string\n price: number\n weight: number\n }\n variant: ProductVariant | null\n quantity: number\n}\n\nexport interface RateAddress {\n city: string\n state: string\n country: string\n}\n\nexport interface ShippingRatesRequest {\n cart_items: CartItemPayload[]\n origin_address: RateAddress\n destination_address: RateAddress\n currency?: string\n}\n\n/**\n * Fetch shipping rates for a cart.\n */\nexport async function getShippingRates(\n config: SdkConfig,\n payload: ShippingRatesRequest\n): Promise<ShippingRatesResponse> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping/rates`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to get shipping rates')\n return response.json()\n}\n\n/**\n * Fetch the seller's registered shipping address.\n */\nexport async function getSellerShippingAddress(config: SdkConfig): Promise<{\n terminal_address_id: string | null\n address_details: {\n city: string\n state: string\n country: string\n line1: string\n line2: string\n zip: string\n } | null\n business_id: string\n message: string\n}> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get seller shipping address')\n return response.json()\n}\n\n/**\n * Validate a shipping address.\n */\nexport async function validateShippingAddress(\n config: SdkConfig,\n payload: {\n first_name: string\n last_name: string\n phone: string\n address_line1: string\n address_line2?: string\n city: string\n state: string\n country: string\n postal_code?: string\n }\n): Promise<{\n valid: boolean\n message?: string\n data?: Array<{ name: string; city_id: string; stateCode: string; countryCode: string }>\n}> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address/validate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to validate shipping address')\n return response.json()\n}\n\n// Service object for backward compatibility\nexport const logisticsService = {\n getShippingRates,\n getSellerShippingAddress,\n validateShippingAddress,\n}\n","/**\n * Bespoke Service\n * \n * Handles bespoke product availability checks.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { BespokeAvailability } from '../types/consultations'\n\nexport async function checkAvailability(config: SdkConfig, product_id: string): Promise<BespokeAvailability> {\n const response = await fetch(`${config.backendUrls.store}/bespoke/availability/${product_id}`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n\n if (!response.ok) throw new Error('Failed to check bespoke availability')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const bespokeService = {\n checkAvailability,\n}\n","/**\n * Service Booking Service\n * \n * Handles service appointments and deliverables.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n ServiceAppointment,\n ServiceAppointmentCreatePayload,\n AvailableSlot,\n ServiceDeliverable,\n DeliverableApprovalPayload,\n} from '../types/services'\n\nexport async function getAvailableSlots(\n config: SdkConfig,\n product_id: string,\n date_from: string,\n date_to: string\n): Promise<AvailableSlot[]> {\n const response = await fetch(\n `${config.backendUrls.store}/service/available-slots/${product_id}?date_from=${date_from}&date_to=${date_to}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n if (!response.ok) throw new Error('Failed to get available slots')\n return response.json()\n}\n\nexport async function bookAppointment(\n config: SdkConfig,\n accessToken: string,\n payload: ServiceAppointmentCreatePayload\n): Promise<ServiceAppointment> {\n const response = await fetch(`${config.backendUrls.store}/service/appointments/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to book appointment')\n return response.json()\n}\n\nexport async function getAppointments(config: SdkConfig, accessToken: string): Promise<ServiceAppointment[]> {\n const response = await fetch(`${config.backendUrls.store}/service/bookings/my`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get appointments')\n return response.json()\n}\n\nexport async function getAppointment(config: SdkConfig, accessToken: string, id: string): Promise<ServiceAppointment> {\n const response = await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get appointment')\n return response.json()\n}\n\nexport async function cancelAppointment(config: SdkConfig, accessToken: string, id: string): Promise<void> {\n await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {\n method: 'DELETE',\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n}\n\nexport async function getDeliverables(config: SdkConfig, accessToken: string, order_id: string): Promise<ServiceDeliverable[]> {\n const response = await fetch(`${config.backendUrls.store}/service/projects/${order_id}/deliverables/`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get deliverables')\n return response.json()\n}\n\nexport async function approveDeliverable(\n config: SdkConfig,\n accessToken: string,\n order_id: string,\n deliverable_id: string\n): Promise<ServiceDeliverable> {\n const response = await fetch(\n `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/approve`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ approved: true }),\n }\n )\n if (!response.ok) throw new Error('Failed to approve deliverable')\n return response.json()\n}\n\nexport async function requestRevision(\n config: SdkConfig,\n accessToken: string,\n order_id: string,\n deliverable_id: string,\n feedback: string\n): Promise<ServiceDeliverable> {\n const response = await fetch(\n `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/revision`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ approved: false, feedback }),\n }\n )\n if (!response.ok) throw new Error('Failed to request revision')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const serviceBookingService = {\n getAvailableSlots,\n bookAppointment,\n getAppointments,\n getAppointment,\n cancelAppointment,\n getDeliverables,\n approveDeliverable,\n requestRevision,\n}\n","/**\n * Notification Service\n * \n * Handles contact form submissions and email notifications.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\n\nexport interface ContactFormData {\n name: string\n email: string\n subject: string\n message: string\n source?: string\n company_name?: string\n current_year?: number\n turnstile_token?: string\n}\n\n/**\n * Send contact email to Kasuvia team.\n * POST /contact/send-contact-email\n */\nexport async function sendContactEmail(\n config: SdkConfig,\n payload: ContactFormData\n): Promise<{ detail: string }> {\n const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-email`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to send contact email')\n return response.json()\n}\n\n/**\n * Send confirmation email to user.\n * POST /contact/send-contact-confirmation\n */\nexport async function sendContactConfirmation(\n config: SdkConfig,\n payload: Omit<ContactFormData, 'turnstile_token'>\n): Promise<{ detail: string }> {\n const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-confirmation`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to send contact confirmation')\n return response.json()\n}\n\nexport const notificationsService = {\n sendContactEmail,\n sendContactConfirmation,\n} as const\n","/**\n * App Service\n * \n * Handles translation and other app-level utilities.\n */\n\nexport async function googleTranslate(text: string, target: string, source = \"en\"): Promise<string> {\n if (!text || target === source) return text;\n try {\n const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${source}&tl=${target}&dt=t&q=${encodeURIComponent(text)}`;\n const res = await fetch(url);\n const data = (await res.json()) as [Array<[string, string]>, ...unknown[]];\n return (data?.[0] || []).map((s) => s[0]).join(\"\");\n } catch {\n return text;\n }\n}\n","/**\n * Config Service\n *\n * Handles configuration endpoints (languages, currencies, locales, business config).\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { BackendLanguage, SupportedLanguagesResponse, SupportedCurrenciesResponse } from '../types/payments'\nimport type { BusinessConfig } from '../types/business'\n\n/**\n * Fetch supported languages from the payment system.\n * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-languages\n */\nexport async function getSupportedLanguages(config: SdkConfig): Promise<SupportedLanguagesResponse> {\n const response = await fetch(`${config.backendUrls.payment}/config/supported-languages`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get supported languages')\n return response.json()\n}\n\n/**\n * Fetch supported currencies from the payment system.\n * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-currencies\n */\nexport async function getSupportedCurrencies(config: SdkConfig): Promise<SupportedCurrenciesResponse> {\n const response = await fetch(`${config.backendUrls.payment}/config/supported-currencies`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get supported currencies')\n return response.json()\n}\n\n/**\n * Fetch the business's public configuration, including store_currency.\n * Uses storefront API key header (X-Storefront-Key).\n * Resolves to: {kasuviaAuthBackendUrl}/internal/businesses/{business_id}/\n * This endpoint is designed for storefronts to fetch business config using their storefront API key.\n */\nexport async function getBusinessConfig(config: SdkConfig): Promise<BusinessConfig> {\n const response = await fetch(`${config.backendUrls.auth}/internal/businesses/${config.businessId}/`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get business config')\n return response.json()\n}\n\nexport const configService = {\n getSupportedLanguages,\n getSupportedCurrencies,\n getBusinessConfig,\n} as const\n","/**\n * CMS Service\n * \n * Handles CMS model and entry operations using the kasuvia-cms SDK endpoints.\n * Protected by X-Storefront-Key and X-Business-ID headers.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n CmsEntry,\n CmsEntryListResponse,\n CreateCmsEntryParams,\n UpdateCmsEntryParams,\n ListCmsEntriesParams,\n} from '../types/cms'\n\n/**\n * List CMS entries for a specific model.\n * Requires public_api.read permission on the model.\n */\nexport async function listCmsEntries(\n config: SdkConfig,\n modelSlug: string,\n params?: ListCmsEntriesParams\n): Promise<CmsEntryListResponse> {\n const queryParams = new URLSearchParams()\n queryParams.set('page', (params?.page || 1).toString())\n queryParams.set('page_size', (params?.page_size || 50).toString())\n\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries?${queryParams.toString()}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to list CMS entries')\n return response.json()\n}\n\n/**\n * Get a single CMS entry by ID.\n * Requires public_api.read permission on the model.\n */\nexport async function getCmsEntry(\n config: SdkConfig,\n modelSlug: string,\n entryId: string\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to get CMS entry')\n return response.json()\n}\n\n/**\n * Create a new CMS entry.\n * Requires public_api.create permission on the model.\n */\nexport async function createCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n params: CreateCmsEntryParams\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(params),\n }\n )\n\n if (!response.ok) throw new Error('Failed to create CMS entry')\n return response.json()\n}\n\n/**\n * Update an existing CMS entry.\n * Requires public_api.update permission on the model.\n */\nexport async function updateCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n entryId: string,\n params: UpdateCmsEntryParams\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(params),\n }\n )\n\n if (!response.ok) throw new Error('Failed to update CMS entry')\n return response.json()\n}\n\n/**\n * Delete a CMS entry.\n * Requires public_api.delete permission on the model.\n */\nexport async function deleteCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n entryId: string\n): Promise<void> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n method: 'DELETE',\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to delete CMS entry')\n}\n","/**\n * Cache Tiers Utility\n * \n * Provides cache configuration for React Query based on environment.\n */\n\nconst CACHE_TIERS = {\n none: { staleTime: 0, gcTime: 0 },\n infinity: { staleTime: Infinity, gcTime: 0 },\n low: { staleTime: 1000 * 30, gcTime: 1000 * 60 }, // 30s / 1m\n medium: { staleTime: 1000 * 60 * 5, gcTime: 1000 * 60 * 10 }, // 5m / 10m\n high: { staleTime: 1000 * 60 * 30, gcTime: 1000 * 60 * 60 }, // 30m / 1h\n} as const;\n\nexport type CacheTier = keyof typeof CACHE_TIERS;\n\nlet isDevelopment = true;\n\n/**\n * Set the environment mode for cache configuration\n */\nexport function setEnvironmentMode(development: boolean): void {\n isDevelopment = development;\n}\n\n/**\n * Get cache configuration for a given tier\n * In development, returns 'none' tier to disable caching\n */\nexport const getCacheTier = (tier: CacheTier) => {\n if (isDevelopment) return CACHE_TIERS.none;\n return CACHE_TIERS[tier];\n};\n","/**\n * Logger Utility\n * \n * Environment-gated logger that suppresses output in production.\n */\n\nlet isDevelopment = true;\n\n/**\n * Set the environment mode for logging\n */\nexport function setLoggerEnvironmentMode(development: boolean): void {\n isDevelopment = development;\n}\n\nexport const logger = {\n log: (...args: unknown[]) => {\n if (isDevelopment) {\n console.log(...args)\n }\n },\n\n warn: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(...args)\n }\n },\n\n /**\n * Logs a warning to the console in development only.\n * Alias for warn() for Python logging compatibility.\n * In production, this is a no-op.\n */\n warning: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(...args)\n }\n },\n\n error: (...args: unknown[]) => {\n if (isDevelopment) {\n console.error(...args)\n }\n },\n\n info: (...args: unknown[]) => {\n if (isDevelopment) {\n console.info(...args)\n }\n },\n\n createScope: (scope: string) => ({\n log: (...args: unknown[]) => {\n if (isDevelopment) {\n console.log(`[${scope}]`, ...args)\n }\n },\n warn: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(`[${scope}]`, ...args)\n }\n },\n warning: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(`[${scope}]`, ...args)\n }\n },\n error: (...args: unknown[]) => {\n if (isDevelopment) {\n console.error(`[${scope}]`, ...args)\n }\n },\n info: (...args: unknown[]) => {\n if (isDevelopment) {\n console.info(`[${scope}]`, ...args)\n }\n },\n }),\n}\n","export class InvalidBaseURLError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"InvalidBaseURLError\";\r\n }\r\n}\r\n\r\nconst ALLOWED_SCHEMES = new Set([\"http:\", \"https:\", \"ws:\", \"wss:\"]);\r\n\r\n/**\r\n * Normalizes a URL by trimming whitespace and stripping trailing slashes.\r\n */\r\nexport function sanitizeBaseUrl(\r\n url: string | undefined | null,\r\n name = \"URL\"\r\n): string {\r\n if (url == null) {\r\n throw new InvalidBaseURLError(`${name} is not set`);\r\n }\r\n\r\n const cleaned0 = url.trim();\r\n if (!cleaned0) {\r\n throw new InvalidBaseURLError(`${name} is empty`);\r\n }\r\n\r\n // Strip all trailing slashes\r\n const cleaned = cleaned0.replace(/\\/+$/, \"\");\r\n\r\n let parsed: URL;\r\n try {\r\n parsed = new URL(cleaned);\r\n } catch {\r\n throw new InvalidBaseURLError(\r\n `${name} must start with http://, https://, ws://, or wss://, got: ${url}`\r\n );\r\n }\r\n\r\n if (!ALLOWED_SCHEMES.has(parsed.protocol)) {\r\n throw new InvalidBaseURLError(\r\n `${name} must start with http://, https://, ws://, or wss://, got: ${url}`\r\n );\r\n }\r\n\r\n if (!parsed.hostname) {\r\n throw new InvalidBaseURLError(`${name} is missing a host: ${url}`);\r\n }\r\n\r\n if (parsed.search || parsed.hash) {\r\n throw new InvalidBaseURLError(\r\n `${name} should not contain a query or fragment: ${url}`\r\n );\r\n }\r\n\r\n return cleaned;\r\n}","import type { CustomerUser } from \"../types\";\n\nexport function buildFullName(firstname?: string, lastname?: string): string | undefined {\n const name = [firstname, lastname].filter(Boolean).join(' ').trim()\n return name || undefined\n}\n\nexport function splitFullName(fullName?: string): { firstname: string; lastname: string } {\n if (!fullName?.trim()) return { firstname: '', lastname: '' }\n const parts = fullName.trim().split(/\\s+/)\n return {\n firstname: parts[0] ?? '',\n lastname: parts.slice(1).join(' '),\n }\n}\n\nexport function getCustomerDisplayName(user: CustomerUser): string {\n const fromParts = buildFullName(user.firstname, user.lastname)\n return fromParts || user.full_name || user.email.split('@')[0]\n}\n\n/**\n * Constructs live storefront URL for a business.\n * If custom domain is not yet connected/verified, defaults to `https://<business_id>.kasuvia.com`.\n */\nexport function getStorefrontUrl(businessId: string, customDomain?: string | null): string {\n if (customDomain && customDomain.trim()) {\n const cleanDomain = customDomain.trim().replace(/^https?:\\/\\//, '');\n return `https://${cleanDomain}`;\n }\n const cleanBid = (businessId || 'store').toLowerCase().trim();\n return `https://${cleanBid}.kasuvia.com`;\n}\n\n","import { buildFullName } from \"./customer\";\nimport type { CheckoutCustomer, DeliveryAddress, Order, ShippingLocation } from \"../types\";\n\nexport function buildDeliveryAddress(customer: CheckoutCustomer, location: ShippingLocation): DeliveryAddress {\n return {\n first_name: customer.first_name,\n last_name: customer.last_name,\n phone: customer.phone,\n ...location,\n };\n}\n\nexport function getCheckoutCustomerName(customer: CheckoutCustomer): string {\n return buildFullName(customer.first_name, customer.last_name) ?? customer.email.split(\"@\")[0];\n}\n\nexport function enrichCompletedOrder(\n order: Order,\n options: {\n customer: CheckoutCustomer;\n location?: ShippingLocation;\n bespokeBrief?: string;\n productType?: \"physical\" | \"digital\" | \"bespoke\" | null;\n },\n): Order {\n const customerName = getCheckoutCustomerName(options.customer);\n\n return {\n ...order,\n customerName: order.customerName || customerName,\n customerEmail: order.customerEmail || options.customer.email,\n shippingAddress:\n order.shippingAddress ??\n (options.productType === \"physical\" && options.location\n ? buildDeliveryAddress(options.customer, options.location)\n : undefined),\n bespokeBrief: order.bespokeBrief ?? options.bespokeBrief,\n };\n}\n","/**\n * Type-safe way to extract an error message from an API error.\n * Updated for fetch-based errors (no axios dependency).\n */\nexport function getErrorMessage(error: unknown, fallback: string = \"Something went wrong\"): string {\n if (error instanceof Error) {\n return error.message;\n }\n // Handle fetch Response objects that might be thrown\n if (error instanceof Response) {\n return `HTTP ${error.status}: ${error.statusText}`;\n }\n // Handle objects with detail or message properties (from API responses)\n if (typeof error === 'object' && error !== null) {\n const err = error as { detail?: string; message?: string; status?: number };\n return err.detail || err.message || fallback;\n }\n return fallback;\n}\n","/**\n * @file storage.ts\n * @description Centralized tenant-isolated storage utility for sessionStorage and localStorage.\n * Automatically prefixes all keys with the storefront Business ID to guarantee multi-tenant segregation.\n * Stateless - requires businessId parameter.\n */\n\nfunction getPrefixedKey(businessId: string, key: string): string {\n const cleanKey = key.startsWith('kasuvia_') ? key.substring(5) : key\n return businessId ? `kasuvia-sf-${businessId}-${cleanKey}` : `kasuvia-sf-anon-${cleanKey}`\n}\n\nexport const sessionStore = {\n get: (businessIdOrKey: string, key?: string): string | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n return sessionStorage.getItem(getPrefixedKey(bId, k))\n },\n set: (businessIdOrKey: string, keyOrVal: string, val?: string): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? businessIdOrKey : ''\n const k = val !== undefined ? keyOrVal : businessIdOrKey\n const v = val !== undefined ? val : keyOrVal\n sessionStorage.setItem(getPrefixedKey(bId, k), v)\n },\n remove: (businessIdOrKey: string, key?: string): void => {\n if (typeof window === 'undefined') return\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n sessionStorage.removeItem(getPrefixedKey(bId, k))\n },\n getJSON: <T = unknown>(businessIdOrKey: string, key?: string): T | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n const value = sessionStorage.getItem(getPrefixedKey(bId, k))\n if (!value) return null\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n },\n setJSON: (businessIdOrKey: string, keyOrVal: unknown, val?: unknown): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? (businessIdOrKey as string) : ''\n const k = val !== undefined ? (keyOrVal as string) : (businessIdOrKey as string)\n const v = val !== undefined ? val : keyOrVal\n sessionStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v))\n },\n}\n\nexport const localStore = {\n get: (businessIdOrKey: string, key?: string): string | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n return localStorage.getItem(getPrefixedKey(bId, k))\n },\n set: (businessIdOrKey: string, keyOrVal: string, val?: string): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? businessIdOrKey : ''\n const k = val !== undefined ? keyOrVal : businessIdOrKey\n const v = val !== undefined ? val : keyOrVal\n localStorage.setItem(getPrefixedKey(bId, k), v)\n },\n remove: (businessIdOrKey: string, key?: string): void => {\n if (typeof window === 'undefined') return\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n localStorage.removeItem(getPrefixedKey(bId, k))\n },\n getJSON: <T = unknown>(businessIdOrKey: string, key?: string): T | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n const value = localStorage.getItem(getPrefixedKey(bId, k))\n if (!value) return null\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n },\n setJSON: (businessIdOrKey: string, keyOrVal: unknown, val?: unknown): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? (businessIdOrKey as string) : ''\n const k = val !== undefined ? (keyOrVal as string) : (businessIdOrKey as string)\n const v = val !== undefined ? val : keyOrVal\n localStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v))\n },\n}\n","/**\n * Form validation utilities for kasuvia-sdk\n * Provides realtime validation for email, password, name, confirm password, and message fields\n */\n\nexport function validateEmail(email: string): string | null {\n if (!email || email.trim() === \"\") {\n return \"Email is required\";\n }\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email)) {\n return \"Please enter a valid email address\";\n }\n return null;\n}\n\nexport function validatePassword(password: string): string | null {\n if (!password || password.trim() === \"\") {\n return \"Password is required\";\n }\n if (password.length < 8) {\n return \"Password must be at least 8 characters\";\n }\n if (password.length > 72) {\n return \"Password cannot exceed 72 characters\";\n }\n if (!/[A-Z]/.test(password)) {\n return \"Password must contain at least one uppercase letter\";\n }\n if (!/[a-z]/.test(password)) {\n return \"Password must contain at least one lowercase letter\";\n }\n if (!/[0-9]/.test(password)) {\n return \"Password must contain at least one number\";\n }\n return null;\n}\n\nexport function validateName(name: string, fieldName: string = \"Name\"): string | null {\n if (!name || name.trim() === \"\") {\n return `${fieldName} is required`;\n }\n if (name.trim().length < 2) {\n return `${fieldName} must be at least 2 characters`;\n }\n if (name.trim().length > 50) {\n return `${fieldName} cannot exceed 50 characters`;\n }\n // Allow letters, spaces, hyphens, and apostrophes\n const nameRegex = /^[a-zA-Z\\s\\-'\\u00C0-\\u017F]+$/;\n if (!nameRegex.test(name.trim())) {\n return `${fieldName} can only contain letters, spaces, hyphens, and apostrophes`;\n }\n return null;\n}\n\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value || value.trim() === \"\") {\n return `${fieldName} is required`;\n }\n return null;\n}\n\n/**\n * Validates the confirm-password field.\n * Returns null (no error) when the field is empty — avoids nagging the user\n * before they've had a chance to type anything.\n */\nexport function validateConfirmPassword(password: string, confirmPassword: string): string | null {\n if (!confirmPassword) return null;\n if (confirmPassword !== password) {\n return \"Passwords do not match\";\n }\n return null;\n}\n\nexport function validateMessage(message: string): string | null {\n if (!message || message.trim() === \"\") {\n return \"Message is required\";\n }\n if (message.trim().length < 10) {\n return \"Message must be at least 10 characters\";\n }\n return null;\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmF9B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmF/B,IAAM,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;AAAA;AAAA;AAAA;AAmFhC,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsF3B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsF/B,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsFjC,IAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["ServiceTypeEnum","ServiceLocationTypeEnum","ServiceRecurringIntervalEnum","response","data","payload","refreshToken","GraphQLClient","createGraphQLClient","GraphQLClient","createGraphQLClient","ref","response","isDevelopment","buildFullName","splitFullName","buildFullName"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/types/store/index.ts","../src/services/cart.service.ts","../src/services/order.service.ts","../src/services/auth.service.ts","../src/services/product.service.ts","../src/services/collection.service.ts","../src/services/wishlist.service.ts","../src/services/payment.service.ts","../src/services/consultation.service.ts","../src/services/logistics.service.ts","../src/services/bespoke.service.ts","../src/services/service-booking.service.ts","../src/services/notifications.service.ts","../src/services/app.service.ts","../src/services/config.service.ts","../src/services/cms.service.ts","../src/utils/cache.ts","../src/utils/logger.ts","../src/utils/sanitize-url.ts","../src/utils/customer.ts","../src/utils/checkout.ts","../src/utils/error-handler.ts","../src/utils/storage.ts","../src/utils/validators.ts"],"sourcesContent":["/**\n * SDK Constants\n * \n * Centralized constants to avoid hardcoded strings across the codebase.\n */\n\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'kasuvia_access_token',\n REFRESH_TOKEN: 'kasuvia_refresh_token',\n CHECKOUT_STATE: 'kasuvia_checkout_state',\n ORDERS_LINKED: 'kasuvia_orders_linked',\n STOREFRONT_STATE: 'storefront_state_v3',\n} as const;\n\nexport const PAYMENT_URLS = {\n MONNIFY: 'https://sdk.monnify.com/plugin/monnify.js',\n FLUTTERWAVE: 'https://checkout.flutterwave.com/v3.js',\n} as const;","import type { DeliveryAddress } from \"./shipping\";\n\nexport * from \"./shipping\";\nexport type { DeliveryAddress };\n\nexport type ProductType = \"physical\" | \"digital\" | \"service\" | \"bespoke\";\n\nexport enum ServiceTypeEnum {\n APPOINTMENT = 'appointment',\n PROJECT = 'project',\n RECURRING = 'recurring',\n}\n\nexport type ServiceType = ServiceTypeEnum | 'appointment' | 'project' | 'recurring'\n\nexport enum ServiceLocationTypeEnum {\n REMOTE = 'remote',\n PHYSICAL = 'physical',\n BOTH = 'both',\n}\n\nexport type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | 'physical' | 'both'\n\nexport enum ServiceRecurringIntervalEnum {\n WEEKLY = 'weekly',\n MONTHLY = 'monthly',\n YEARLY = 'yearly',\n}\n\nexport type ServiceRecurringInterval = ServiceRecurringIntervalEnum | 'weekly' | 'monthly' | 'yearly' | ''\n\nexport interface Address {\n street: string\n city: string\n state: string\n country: string\n zip?: string\n}\n\nexport interface Collection {\n id: string\n business_id?: string\n name: string\n slug: string\n description?: string\n image?: string\n collection_type?: string\n rules?: Record<string, unknown>\n status?: string\n sort_order?: number\n created_at: string\n updated_at: string\n}\n\nexport interface Inventory {\n id: string\n product_id: string\n variant_id?: string\n quantity: number\n reserved: number\n reorder_point: number\n reorder_quantity: number\n track_quantity: boolean\n allow_backorder: boolean\n available: number\n is_in_stock: boolean\n is_low_stock: boolean\n updated_at: string\n}\n\nexport interface ProductVariant {\n id: string\n product_id: string\n sku?: string\n attributes: Record<string, string>\n price?: number\n images: string[]\n weight_kg?: number\n is_active: boolean\n inventory?: Inventory\n created_at: string\n updated_at: string\n}\n\nexport interface CustomField {\n label: string\n unit?: string\n required: boolean\n type?: string\n key?: string\n placeholder?: string\n}\n\nexport interface Product {\n id: string\n business_id: string\n name: string\n slug: string\n description?: string\n brand?: string\n product_type: ProductType\n requires_shipping: boolean\n is_consumable: boolean\n is_bespoke: boolean\n is_physical?: boolean | null // For bespoke products: indicates if custom item requires physical delivery\n base_price: number\n currency: string\n sale_price?: number\n sale_start?: string\n sale_end?: string\n images: string[]\n tags: string[]\n custom_fields: CustomField[]\n is_published: boolean\n is_featured: boolean\n is_popular: boolean\n is_new: boolean\n is_temporary: boolean\n digital_file_key?: string\n download_limit?: number\n download_expires_at?: string\n // Service-specific fields\n service_type?: ServiceType | null\n service_duration_minutes?: number | null\n service_location_type?: ServiceLocationType | null\n service_requires_consultation?: boolean\n service_max_capacity_per_slot?: number | null\n service_buffer_minutes?: number\n service_is_recurring?: boolean\n service_recurring_interval?: ServiceRecurringInterval | null\n service_project_based?: boolean\n weight_kg: number\n length_cm?: number\n width_cm?: number\n height_cm?: number\n created_at: string\n updated_at: string\n variants: ProductVariant[]\n collections: Collection[]\n}\n\nexport interface ListParams {\n page?: number\n pageSize?: number\n search?: string\n ordering?: string\n collectionSlug?: string\n excludeProductId?: string\n}\n\nexport interface PaginatedResponse<T> {\n items: T[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\n// ============================================================================\n// CART TYPES\n// ============================================================================\n\nexport interface CartItem {\n id: string\n product_id: string\n product_slug: string\n product_name: string\n image?: string\n variant_id?: string\n variant_attributes?: string | Record<string, string>\n unit_price: number\n quantity: number\n custom_measurements?: string\n is_bespoke: boolean\n created_at: string\n updated_at: string\n}\n\nexport interface CartResponse {\n items: CartItem[]\n subtotal: number\n total: number\n item_count: number\n product_type?: string // \"physical\", \"digital\", \"bespoke\"\n}\n\n// ============================================================================\n// WISHLIST TYPES\n// ============================================================================\n\nexport interface WishlistItem {\n id: string\n product_id: string\n notes?: string\n created_at: string\n product_name?: string\n product_slug?: string\n product_price?: number\n product_image?: string\n}\n\nexport interface WishlistListResponse {\n items: WishlistItem[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport interface WishlistCheckResponse {\n in_wishlist: boolean\n}\n\nexport type OrderStatus =\n | 'pending'\n | 'confirmed'\n | 'processing'\n | 'packed'\n | 'picked_up'\n | 'in_transit'\n | 'shipped'\n | 'delivered'\n | 'voided'\n | 'refunded'\n | 'failed';\nexport type BespokeStageKey = \"received\" | \"development\" | \"finished\" | \"dispatched\";\n\nexport interface OrderItem {\n id: string;\n productName: string;\n image: string;\n quantity: number;\n price: number;\n}\n\nexport interface Order {\n id: string;\n display_id?: string;\n items: OrderItem[];\n total: number;\n status: OrderStatus;\n customerEmail: string;\n customerName: string;\n createdAt: number;\n updatedAt: number;\n deliveryMethod?: string;\n trackingNumber?: string;\n deliveryAddress?: string;\n shippingAddress?: DeliveryAddress;\n cancellationReason?: string;\n hasBespoke?: boolean;\n bespokeStage?: BespokeStageKey;\n bespokeBrief?: string;\n deliveryStatus?: string;\n carrierName?: string;\n terminalShipmentId?: string;\n guestToken?: string;\n guestEmail?: string;\n guestPhone?: string;\n guestName?: string;\n}\n\n// ============================================================================\n// CHECKOUT TYPES\n// ============================================================================\n\nexport interface CheckoutCustomer {\n first_name: string;\n last_name: string;\n email: string;\n phone: string;\n}\n\nexport interface ShippingLocation {\n street: string;\n city: string;\n state: string;\n lga: string;\n country: string;\n postal: string;\n}\n\n// ============================================================================\n// ORDER SERVICE PARAMS\n// ============================================================================\n\nexport interface FindOrderParams {\n email: string;\n order_id: string;\n}\n\nexport interface CreateOrderParams {\n customer_id?: string | null;\n status?: string;\n shipping_address?: DeliveryAddress;\n checkout_session_id?: string;\n items: Array<{\n product_id: string;\n product_name: string;\n quantity: number;\n unit_price: number;\n variant_id?: string;\n variant_details?: Record<string, unknown>;\n custom_measurements?: Record<string, unknown>;\n }>;\n delivery_method?: string;\n delivery_address?: string;\n total?: number;\n payment_method?: string;\n shipping_rate_id?: string;\n guest_token?: string;\n guest_email?: string;\n guest_phone?: string;\n guest_name?: string;\n product_type?: string;\n bespoke_brief?: string;\n bespoke_reference_images?: string[];\n bespoke_measurements?: Record<string, string>;\n bespoke_preferred_timeline?: string;\n bespoke_special_instructions?: string;\n}\n","/**\n * Cart Service\n * \n * Handles cart operations for both guest and authenticated users.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { CartItem, CartResponse } from '../types/store'\n\nfunction parseItems(items: CartItem[]): CartItem[] {\n return items.map((item) => ({\n ...item,\n variant_attributes:\n item.variant_attributes && typeof item.variant_attributes === \"string\"\n ? JSON.parse(item.variant_attributes)\n : item.variant_attributes,\n }));\n}\n\n/**\n * Fetch guest cart from backend (Redis-backed).\n */\nexport async function getGuestCart(config: SdkConfig, guestSessionId: string): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n try {\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n } catch {\n return []\n }\n}\n\n/**\n * Add item to guest cart (Redis-backed).\n */\nexport async function addToGuestCart(config: SdkConfig, guestSessionId: string, item: CartItem): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n const payload = {\n product_id: item.product_id,\n product_slug: item.product_slug,\n product_name: item.product_name,\n image: item.image,\n variant_id: item.variant_id,\n variant_attributes:\n typeof item.variant_attributes === \"string\"\n ? item.variant_attributes\n : JSON.stringify(item.variant_attributes),\n unit_price: item.unit_price,\n quantity: item.quantity,\n custom_measurements: item.custom_measurements,\n is_bespoke: item.is_bespoke,\n }\n\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n}\n\n/**\n * Update quantity of a guest cart item.\n */\nexport async function updateGuestCartItemQuantity(\n config: SdkConfig,\n guestSessionId: string,\n itemId: string,\n quantity: number\n): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'PATCH',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n body: JSON.stringify({ quantity }),\n })\n if (!response.ok) return []\n const data = await response.json()\n return parseItems(data.items || [])\n}\n\n/**\n * Remove an item from the guest cart.\n */\nexport async function removeFromGuestCart(\n config: SdkConfig,\n guestSessionId: string,\n itemId: string\n): Promise<CartItem[]> {\n if (!guestSessionId) return []\n\n await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'DELETE',\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n\n return getGuestCart(config, guestSessionId)\n}\n\n/**\n * Clear the entire guest cart.\n */\nexport async function clearGuestCart(config: SdkConfig, guestSessionId: string): Promise<void> {\n if (!guestSessionId) return\n\n await fetch(`${config.backendUrls.store}/cart/clear`, {\n method: 'DELETE',\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n \"X-Guest-Session\": guestSessionId \n },\n })\n}\n\n/**\n * Fetch authenticated user's cart from backend.\n */\nexport async function getCart(config: SdkConfig, accessToken?: string | null): Promise<CartResponse> {\n if (!accessToken) {\n return { id: '', items: [], subtotal: 0, total: 0, product_type: 'physical' } as any;\n }\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to fetch cart')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Add item to authenticated user's cart.\n */\nexport async function addToCart(\n config: SdkConfig,\n accessToken: string,\n item: {\n product_id: string\n product_slug: string\n product_name: string\n image?: string\n variant_id?: string\n variant_attributes?: string\n unit_price: number\n quantity: number\n custom_measurements?: string\n is_bespoke: boolean\n }\n): Promise<CartResponse> {\n const response = await fetch(`${config.backendUrls.store}/cart/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(item),\n })\n if (!response.ok) throw new Error('Failed to add to cart')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Update item quantity in authenticated user's cart.\n */\nexport async function updateCartItem(\n config: SdkConfig,\n accessToken: string,\n itemId: string,\n quantity: number\n): Promise<CartResponse> {\n const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'PATCH',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ quantity }),\n })\n if (!response.ok) throw new Error('Failed to update cart item')\n const data = await response.json()\n const parsedItems = parseItems(data.items || [])\n return { ...data, items: parsedItems }\n}\n\n/**\n * Remove item from authenticated user's cart.\n */\nexport async function removeFromCart(\n config: SdkConfig,\n accessToken: string,\n itemId: string\n): Promise<CartResponse> {\n await fetch(`${config.backendUrls.store}/cart/${itemId}`, {\n method: 'DELETE',\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n return getCart(config, accessToken)\n}\n\n/**\n * Clear authenticated user's cart.\n */\nexport async function clearCart(config: SdkConfig, accessToken: string): Promise<void> {\n await fetch(`${config.backendUrls.store}/cart/clear`, {\n method: 'DELETE',\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n}\n\n/**\n * Merge guest cart (from Redis) into authenticated user's DB cart.\n */\nexport async function mergeGuestCart(\n config: SdkConfig,\n accessToken: string,\n guestSessionId: string\n): Promise<CartResponse> {\n const guestItems = guestSessionId ? await getGuestCart(config, guestSessionId) : []\n \n if (guestItems.length === 0) {\n return getCart(config, accessToken)\n }\n\n const payloadItems = guestItems.map((item) => ({\n product_id: item.product_id,\n product_slug: item.product_slug,\n product_name: item.product_name,\n image: item.image,\n variant_id: item.variant_id,\n variant_attributes:\n typeof item.variant_attributes === \"string\"\n ? item.variant_attributes\n : JSON.stringify(item.variant_attributes ?? {}),\n unit_price: item.unit_price,\n quantity: item.quantity,\n custom_measurements:\n typeof item.custom_measurements === \"string\"\n ? item.custom_measurements\n : JSON.stringify(item.custom_measurements ?? {}),\n is_bespoke: item.is_bespoke,\n }))\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n }\n if (guestSessionId) {\n headers[\"X-Guest-Session\"] = guestSessionId\n }\n\n const response = await fetch(`${config.backendUrls.store}/cart/merge`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ items: payloadItems }),\n })\n if (!response.ok) throw new Error('Failed to merge guest cart')\n const data = await response.json()\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Convenience wrapper: merge guest cart if it has items (called post-login).\n */\nexport async function mergeGuestCartIfPresent(\n config: SdkConfig,\n accessToken: string,\n guestSessionId: string\n): Promise<void> {\n try {\n const guestItems = await getGuestCart(config, guestSessionId)\n if (guestItems.length === 0) return\n await mergeGuestCart(config, accessToken, guestSessionId)\n } catch (error) {\n console.warn(\"[Cart] Failed to merge guest cart:\", error)\n }\n}\n\n/**\n * Returns 0 — count is now server-driven. Use the hook instead.\n * Kept for backward compatibility.\n */\nexport function getGuestCartCount(): number {\n return 0\n}\n\n/**\n * Returns 0 — subtotal is now server-driven.\n * Kept for backward compatibility.\n */\nexport function getGuestCartSubtotal(): number {\n return 0\n}\n\n/**\n * Derive product type from items (guest cart, no backend lookup needed).\n */\nexport function getGuestCartProductType(): \"physical\" | \"digital\" | \"bespoke\" {\n return \"physical\"\n}\n","/**\n * Order Service\n * \n * Handles order operations including creation, lookup, and tracking.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { Order, OrderStatus, FindOrderParams, CreateOrderParams, OrderItem } from '../types/store'\nimport type { DeliveryAddress } from '../types/store'\n\nexport type { FindOrderParams, CreateOrderParams, OrderStatus }\n\ninterface RawOrderItem {\n id: string\n product_name?: string\n productName?: string\n image?: string\n quantity?: number\n unit_price?: number\n price?: number\n}\n\ninterface RawShippingAddress {\n first_name?: string\n last_name?: string\n phone?: string\n street?: string\n city?: string\n state?: string\n country?: string\n postal?: string\n lga?: string\n}\n\ninterface RawOrder {\n id: string\n display_id?: string\n items?: RawOrderItem[]\n total_amount?: number\n total?: number\n status: OrderStatus\n customer_email?: string\n customer_name?: string\n guest_email?: string\n guest_phone?: string\n guest_name?: string\n guest_token?: string\n shipping_address?: RawShippingAddress | string | null\n delivery_method?: string\n tracking_number?: string\n delivery_status?: string\n carrier_name?: string\n terminal_shipment_id?: string\n product_type?: string\n bespoke_stage?: string\n bespoke_brief?: string\n created_at?: string\n updated_at?: string\n cancellation_reason?: string\n}\n\nfunction deriveCustomerName(raw: RawOrder): string {\n if (raw.customer_name) return raw.customer_name\n if (raw.guest_name) return raw.guest_name\n\n const addr = typeof raw.shipping_address === 'object' && raw.shipping_address !== null\n ? raw.shipping_address as RawShippingAddress\n : null\n if (addr) {\n const full = `${addr.first_name ?? ''} ${addr.last_name ?? ''}`.trim()\n if (full) return full\n }\n\n const email = raw.guest_email ?? raw.customer_email ?? ''\n if (email) return email.split('@')[0]\n\n return ''\n}\n\nfunction normaliseStorefrontOrder(raw: RawOrder): Order {\n const items: OrderItem[] = (raw.items ?? []).map((item) => ({\n id: item.id,\n productName: item.product_name ?? item.productName ?? '',\n image: item.image ?? '',\n quantity: item.quantity ?? 1,\n price: item.unit_price ?? item.price ?? 0,\n }))\n\n const addr = typeof raw.shipping_address === 'object' && raw.shipping_address !== null\n ? raw.shipping_address as RawShippingAddress\n : null\n\n return {\n id: raw.id,\n display_id: raw.display_id,\n items,\n total: raw.total_amount ?? raw.total ?? 0,\n status: raw.status,\n customerEmail: raw.guest_email ?? raw.customer_email ?? '',\n customerName: deriveCustomerName(raw),\n createdAt: raw.created_at ? new Date(raw.created_at).getTime() : Date.now(),\n updatedAt: raw.updated_at ? new Date(raw.updated_at).getTime() : Date.now(),\n deliveryMethod: raw.delivery_method,\n trackingNumber: raw.tracking_number,\n deliveryAddress: typeof raw.shipping_address === 'string'\n ? raw.shipping_address\n : addr\n ? `${addr.street}, ${addr.city}, ${addr.state}, ${addr.country}`\n : undefined,\n shippingAddress: addr\n ? {\n first_name: addr.first_name ?? '',\n last_name: addr.last_name ?? '',\n phone: addr.phone ?? '',\n street: addr.street ?? '',\n city: addr.city ?? '',\n state: addr.state ?? '',\n lga: addr.lga ?? '',\n country: addr.country ?? '',\n postal: addr.postal ?? '',\n }\n : undefined,\n cancellationReason: raw.cancellation_reason,\n hasBespoke: raw.product_type === 'bespoke',\n bespokeStage: raw.bespoke_stage as Order['bespokeStage'],\n bespokeBrief: raw.bespoke_brief,\n deliveryStatus: raw.delivery_status,\n carrierName: raw.carrier_name,\n terminalShipmentId: raw.terminal_shipment_id,\n guestToken: raw.guest_token,\n guestEmail: raw.guest_email,\n guestPhone: raw.guest_phone,\n guestName: raw.guest_name,\n }\n}\n\nexport async function createOrder(config: SdkConfig, accessToken: string, payload: CreateOrderParams): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/storefront`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to create order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function findOrder(config: SdkConfig, params: FindOrderParams & { guest_token?: string }): Promise<Order> {\n const queryParams = new URLSearchParams()\n if (params.email) queryParams.set('email', params.email)\n if (params.order_id) queryParams.set('order_id', params.order_id)\n if (params.guest_token) queryParams.set('guest_token', params.guest_token)\n \n const response = await fetch(`${config.backendUrls.store}/orders/find/?${queryParams.toString()}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to find order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function findOrderByToken(config: SdkConfig, token: string): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/find/?guest_token=${token}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to find order by token')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function getOrders(config: SdkConfig, accessToken: string, params?: { email?: string; page?: number; page_size?: number }): Promise<Order[]> {\n const queryParams = new URLSearchParams()\n if (params?.email) queryParams.set('email', params.email)\n if (params?.page) queryParams.set('page', params.page.toString())\n if (params?.page_size) queryParams.set('page_size', params.page_size.toString())\n \n const response = await fetch(`${config.backendUrls.store}/orders/?${queryParams.toString()}`, {\n headers: { \n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get orders')\n const data = await response.json()\n const items: RawOrder[] = Array.isArray(data) ? data : (data.items ?? [])\n return items.map(normaliseStorefrontOrder)\n}\n\nexport async function cancelOrder(config: SdkConfig, accessToken: string, orderId: string, reason: string): Promise<Order> {\n const response = await fetch(`${config.backendUrls.store}/orders/${orderId}/cancel/`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ reason }),\n })\n if (!response.ok) throw new Error('Failed to cancel order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n\nexport async function trackOrder(config: SdkConfig, orderId: string, token?: string): Promise<Order> {\n const queryParams = token ? `?token=${token}` : ''\n const response = await fetch(`${config.backendUrls.store}/orders/track/${orderId}${queryParams}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to track order')\n const data = await response.json()\n return normaliseStorefrontOrder(data)\n}\n","/**\n * Customer auth service — all API calls scoped to this storefront's business tenant.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport { STORAGE_KEYS } from '../constants'\nimport type {\n CustomerAuthResponse,\n CustomerLoginPayload,\n CustomerRegisterPayload,\n LogoutPayload,\n RefreshTokenResponse,\n CustomerUser,\n AuthUserResponse,\n UpdateProfilePayload,\n} from '../types/auth'\n\n// ── Auth API Calls ────────────────────────────────────────────────────────────\n\n/**\n * POST /auth/login/customer/\n * The `tenant_id` is automatically filled from config.businessId.\n */\nexport async function loginCustomer(\n config: SdkConfig,\n payload: Omit<CustomerLoginPayload, 'tenant_id'>\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/login/customer/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n },\n body: JSON.stringify({\n ...payload,\n tenant_id: config.businessId,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Login failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/**\n * POST /auth/register/customer/\n * The `tenant_id` is automatically filled from config.businessId.\n */\nexport async function registerCustomer(\n config: SdkConfig,\n payload: Omit<CustomerRegisterPayload, 'tenant_id'>\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/register/customer/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n },\n body: JSON.stringify({\n ...payload,\n tenant_id: config.businessId,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Registration failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** POST /auth/token/refresh/\n */\nexport async function refreshToken(\n config: SdkConfig,\n refresh: string\n): Promise<RefreshTokenResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/token/refresh/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ refresh }),\n })\n\n if (!response.ok) {\n throw new Error('Token refresh failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** POST /auth/logout/ — revokes the server-side session. */\nexport async function logout(\n config: SdkConfig,\n refresh?: string\n): Promise<void> {\n const payload: LogoutPayload = refresh ? { refresh } : {}\n try {\n await fetch(`${config.backendUrls.auth}/auth/logout/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n })\n } catch {\n // Swallow server errors\n }\n}\n\n/**\n * Verify a social provider id_token (or access_token for Facebook) with the backend.\n */\nexport async function verifySocialToken(\n config: SdkConfig,\n provider: 'google' | 'facebook',\n token: string\n): Promise<CustomerAuthResponse> {\n const response = await fetch(`${config.backendUrls.auth}/auth/social/verify/${provider}/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id_token: token,\n storefront_key: config.storefrontApiKey,\n }),\n })\n\n if (!response.ok) {\n throw new Error('Social token verification failed')\n }\n\n const data = await response.json()\n return data\n}\n\n/** Decode a JWT payload without verifying signature (client-side use only). */\nfunction parseJwtPayload(token: string): Record<string, unknown> {\n try {\n return JSON.parse(atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')))\n } catch {\n return {}\n }\n}\n\nfunction resolveProvider(data: Pick<AuthUserResponse, 'is_google_auth_enabled' | 'is_facebook_auth_enabled'>): CustomerUser['provider'] {\n if (data.is_google_auth_enabled) return 'google'\n if (data.is_facebook_auth_enabled) return 'facebook'\n return 'email'\n}\n\nfunction resolveAvatar(profilePicture: unknown): string | null {\n if (!profilePicture) return null\n if (typeof profilePicture === 'string') return profilePicture\n if (typeof profilePicture === 'object' && profilePicture !== null && 'url' in profilePicture) {\n const url = (profilePicture as { url?: string }).url\n return typeof url === 'string' ? url : null\n }\n return null\n}\n\n/** Map kasuvia-auth UserSerializer response to storefront CustomerUser. */\nexport function mapAuthUserToCustomer(data: AuthUserResponse, provider?: CustomerUser['provider']): CustomerUser {\n const firstname = data.profile?.firstname?.trim() || undefined\n const lastname = data.profile?.lastname?.trim() || undefined\n const phone = data.profile?.phone?.trim() || undefined\n\n return {\n id: String(data.id),\n email: data.email,\n firstname,\n lastname,\n phone,\n full_name: buildFullName(firstname, lastname),\n avatar: resolveAvatar(data.profile?.profile_picture),\n provider: provider ?? resolveProvider(data),\n }\n}\n\nfunction buildCustomerFromClaims(claims: Record<string, unknown>): CustomerUser {\n const provider: CustomerUser['provider'] = claims.is_google_auth_enabled\n ? 'google'\n : claims.is_facebook_auth_enabled\n ? 'facebook'\n : 'email'\n\n const jwtFullName = String(claims.full_name ?? claims.name ?? '').trim() || undefined\n const { firstname: splitFirst, lastname: splitLast } = splitFullName(jwtFullName)\n\n return {\n id: String(claims.user_id ?? claims.sub ?? ''),\n email: String(claims.email ?? ''),\n firstname: splitFirst || undefined,\n lastname: splitLast || undefined,\n phone: String(claims.phone ?? '').trim() || undefined,\n full_name: jwtFullName,\n avatar: claims.avatar as string | null,\n provider,\n }\n}\n\n/** GET /auth/profile/ */\nexport async function getMe(config?: SdkConfig, accessToken?: string): Promise<CustomerUser> {\n if (!config || !accessToken) {\n const response = await fetch('/api/auth/me', { credentials: 'include' })\n if (!response.ok) throw new Error('Failed to fetch profile')\n const data = await response.json()\n return data.user\n }\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch profile')\n }\n\n const data = await response.json()\n return mapAuthUserToCustomer(data)\n}\n\n/** GET /auth/profile/ - alias for getMe for backward compatibility */\nexport async function getAuthUser(config?: SdkConfig, accessToken?: string): Promise<AuthUserResponse> {\n if (!config || !accessToken) {\n const response = await fetch('/api/auth/me', { credentials: 'include' })\n if (!response.ok) throw new Error('Failed to fetch auth user')\n const data = await response.json()\n return data.user\n }\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch auth user')\n }\n\n const data = await response.json()\n return data\n}\n\n/** PUT /auth/profile/ — update firstname, lastname, phone */\nexport async function updateProfile(\n configOrPayload: SdkConfig | UpdateProfilePayload,\n accessTokenOrPayload?: string | UpdateProfilePayload,\n payloadParam?: UpdateProfilePayload\n): Promise<CustomerUser> {\n const isArg1Config = typeof configOrPayload === 'object' && configOrPayload !== null && 'businessId' in configOrPayload\n if (!isArg1Config) {\n const payload = configOrPayload as UpdateProfilePayload\n const response = await fetch('/api/auth/profile', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include',\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to update profile')\n return response.json()\n }\n\n const config = configOrPayload as SdkConfig\n const accessToken = accessTokenOrPayload as string\n const payload = payloadParam as UpdateProfilePayload\n\n const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new Error('Failed to update profile')\n }\n\n const data = await response.json()\n return mapAuthUserToCustomer(data)\n}\n\n/**\n * Silently refresh the access token on app boot.\n * Builds CustomerUser from JWT claims — no additional profile API call needed.\n * Returns null if no refresh token exists or if the refresh fails.\n */\nexport async function silentRefresh(\n config: SdkConfig,\n refresh: string\n): Promise<{ user: CustomerUser; provider: CustomerUser['provider']; newAccessToken: string; newRefreshToken: string } | null> {\n try {\n const data = await refreshToken(config, refresh)\n if (!data.access || !data.refresh) {\n return null\n }\n const claims = parseJwtPayload(data.access)\n const user = buildCustomerFromClaims(claims)\n const provider = user.provider\n return { user, provider, newAccessToken: data.access, newRefreshToken: data.refresh }\n } catch {\n return null\n }\n}\n\n// ── Helper Functions ─────────────────────────────────────────────────────────\n\nfunction buildFullName(firstname?: string, lastname?: string): string {\n if (firstname && lastname) return `${firstname} ${lastname}`\n return firstname || lastname || ''\n}\n\nfunction splitFullName(fullName?: string): { firstname: string; lastname: string } {\n if (!fullName) return { firstname: '', lastname: '' }\n\n const parts = fullName.trim().split(/\\s+/)\n if (parts.length === 1) {\n return { firstname: parts[0], lastname: '' }\n }\n\n return {\n firstname: parts[0],\n lastname: parts.slice(1).join(' ')\n }\n}\n\n/**\n * Store tokens in localStorage (client-side utility)\n * This is a convenience function for storefronts to store auth tokens\n */\nexport function storeTokens(accessToken: string, refreshToken: string): void {\n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, accessToken)\n localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refreshToken)\n }\n}\n\n/**\n * Clear tokens from localStorage (client-side utility)\n */\nexport function clearTokens(): void {\n if (typeof window !== 'undefined') {\n localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN)\n localStorage.removeItem(STORAGE_KEYS.REFRESH_TOKEN)\n }\n}\n\n/**\n * Get stored tokens from localStorage (client-side utility)\n */\nexport function getStoredTokens(): { accessToken: string | null; refreshToken: string | null } {\n if (typeof window === 'undefined') {\n return { accessToken: null, refreshToken: null }\n }\n return {\n accessToken: localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN),\n refreshToken: localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN),\n }\n}\n","/**\n * Product Service\n * \n * Handles product operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { Product, PaginatedResponse, ListParams } from '../types/store'\nimport type { SdkConfig } from '../config'\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\nconst GET_STOREFRONT_PRODUCTS = `\n query GetStorefrontProducts($page: Int!, $pageSize: Int!, $collectionSlug: String, $search: String) {\n storefront_products(page: $page, pageSize: $pageSize, collectionSlug: $collectionSlug, search: $search) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_PRODUCT_BY_SLUG = `\n query GetStorefrontProductBySlug($slug: String!) {\n storefront_product_by_slug(slug: $slug) {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n }\n`\n\nconst GET_STOREFRONT_LATEST = `\n query GetStorefrontLatest($page: Int!, $pageSize: Int!) {\n storefront_latest(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_POPULAR = `\n query GetStorefrontPopular($page: Int!, $pageSize: Int!) {\n storefront_popular(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_FEATURED = `\n query GetStorefrontFeatured($page: Int!, $pageSize: Int!) {\n storefront_featured(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_NEW = `\n query GetStorefrontNew($page: Int!, $pageSize: Int!) {\n storefront_new(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_ON_SALE = `\n query GetStorefrontOnSale($page: Int!, $pageSize: Int!) {\n storefront_on_sale(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_LOW_STOCK = `\n query GetStorefrontLowStock($page: Int!, $pageSize: Int!) {\n storefront_low_stock(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n sale_price\n sale_start\n sale_end\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_RECOMMENDED = `\n query GetStorefrontRecommended($page: Int!, $pageSize: Int!, $excludeProductId: String) {\n storefront_recommended(page: $page, pageSize: $pageSize, excludeProductId: $excludeProductId) {\n items {\n id\n business_id\n name\n slug\n description\n brand\n product_type\n requires_shipping\n is_consumable\n is_bespoke\n base_price\n currency\n images\n tags\n custom_fields { label unit required }\n is_published\n is_featured\n is_popular\n is_new\n is_temporary\n digital_file_key\n download_limit\n download_expires_at\n weight_kg\n length_cm\n width_cm\n height_cm\n created_at\n updated_at\n variants {\n id\n product_id\n sku\n attributes\n price\n images\n weight_kg\n is_active\n inventory {\n id\n product_id\n variant_id\n quantity\n reserved\n reorder_point\n reorder_quantity\n track_quantity\n allow_backorder\n available\n is_in_stock\n is_low_stock\n updated_at\n }\n created_at\n updated_at\n }\n collections {\n id\n business_id\n name\n slug\n description\n image\n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\n/**\n * Fetch all active products for the storefront.\n */\nexport async function getStorefrontProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n collectionSlug: params?.collectionSlug,\n search: params?.search,\n }\n const data = await client.request(GET_STOREFRONT_PRODUCTS, variables)\n return data.storefront_products\n}\n\n/**\n * Fetch a single product by slug for the storefront.\n */\nexport async function getStorefrontProductBySlug(\n config: SdkConfig,\n slug: string\n): Promise<Product> {\n const client = createGraphQLClient(config)\n const data = await client.request(GET_STOREFRONT_PRODUCT_BY_SLUG, { slug })\n return data.storefront_product_by_slug\n}\n\n/**\n * Fetch latest products for the storefront.\n */\nexport async function getLatestProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_LATEST, variables)\n return data.storefront_latest\n}\n\n/**\n * Fetch popular products for the storefront.\n */\nexport async function getPopularProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_POPULAR, variables)\n return data.storefront_popular\n}\n\n/**\n * Fetch featured products for the storefront.\n */\nexport async function getFeaturedProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_FEATURED, variables)\n return data.storefront_featured\n}\n\n/**\n * Fetch new products for the storefront.\n */\nexport async function getNewProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_NEW, variables)\n return data.storefront_new\n}\n\n/**\n * Fetch products currently on sale for the storefront.\n */\nexport async function getOnSaleProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_ON_SALE, variables)\n return data.storefront_on_sale\n}\n\n/**\n * Fetch products with low stock for the storefront.\n */\nexport async function getLowStockProducts(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n }\n const data = await client.request(GET_STOREFRONT_LOW_STOCK, variables)\n return data.storefront_low_stock\n}\n\n/**\n * Fetch recommended products for the storefront.\n * Returns featured, popular, and new products.\n * Optionally excludes a specific product ID.\n */\nexport async function getRecommendedProducts(\n config: SdkConfig,\n params?: ListParams & { excludeProductId?: string }\n): Promise<PaginatedResponse<Product>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n excludeProductId: params?.excludeProductId,\n }\n const data = await client.request(GET_STOREFRONT_RECOMMENDED, variables)\n return data.storefront_recommended\n}\n\n","/**\n * Collection Service\n * \n * Handles collection operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { Collection, PaginatedResponse, ListParams } from '../types/store'\nimport type { SdkConfig } from '../config'\n\nconst GET_STOREFRONT_COLLECTIONS = `\n query GetStorefrontCollections($page: Int!, $pageSize: Int!) {\n storefront_collections(page: $page, pageSize: $pageSize) {\n items {\n id\n business_id\n name\n slug\n description\n image \n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst GET_STOREFRONT_COLLECTION_BY_SLUG = `\n query GetStorefrontCollectionBySlug($slug: String!) {\n storefront_collection_by_slug(slug: $slug) {\n id\n business_id\n name\n slug\n description\n image \n collection_type\n rules\n status\n sort_order\n created_at\n updated_at\n }\n }\n`\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\n/**\n * Fetch paginated active collections for the storefront.\n */\nexport async function getStorefrontCollections(\n config: SdkConfig,\n params?: ListParams\n): Promise<PaginatedResponse<Collection>> {\n const client = createGraphQLClient(config)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n }\n const data = await client.request(GET_STOREFRONT_COLLECTIONS, variables)\n return data.storefront_collections\n}\n\n/**\n * Fetch a single collection by its slug.\n */\nexport async function getStorefrontCollectionBySlug(\n config: SdkConfig,\n slug: string\n): Promise<Collection> {\n const client = createGraphQLClient(config)\n const data = await client.request(GET_STOREFRONT_COLLECTION_BY_SLUG, { slug })\n return data.storefront_collection_by_slug\n}\n","/**\n * Wishlist Service\n * \n * Handles wishlist operations.\n * Stateless - all configuration passed as parameters.\n */\nimport { GraphQLClient } from 'graphql-request'\nimport type { SdkConfig } from '../config'\nimport type { WishlistItem, WishlistListResponse, WishlistCheckResponse } from '../types/store'\n\nconst GET_STOREFRONT_WISHLIST = `\n query GetStorefrontWishlist($page: Int!, $pageSize: Int!) {\n storefront_wishlist(page: $page, pageSize: $pageSize) {\n items {\n id\n product_id\n notes\n created_at\n product_name\n product_slug\n product_price\n currency\n product_image\n }\n total\n page\n page_size\n total_pages\n }\n }\n`\n\nconst CHECK_IN_STOREFRONT_WISHLIST = `\n query CheckInStorefrontWishlist($productId: String!) {\n check_in_storefront_wishlist(productId: $productId) {\n in_wishlist\n }\n }\n`\n\n/**\n * Create GraphQL client with provided config\n */\nfunction createGraphQLClient(config: SdkConfig, accessToken?: string): GraphQLClient {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n if (accessToken) {\n headers['Authorization'] = `Bearer ${accessToken}`\n }\n return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })\n}\n\n/**\n * Fetch the customer's wishlist for the current business.\n */\nexport async function getWishlist(config: SdkConfig, accessToken: string, params?: { page?: number; pageSize?: number }): Promise<WishlistListResponse> {\n const client = createGraphQLClient(config, accessToken)\n const variables = {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n }\n const data = await client.request(GET_STOREFRONT_WISHLIST, variables)\n return data.storefront_wishlist\n}\n\n/**\n * Check if a product is in the customer's wishlist.\n */\nexport async function checkInWishlist(config: SdkConfig, accessToken: string, productId: string): Promise<WishlistCheckResponse> {\n const client = createGraphQLClient(config, accessToken)\n const data = await client.request(CHECK_IN_STOREFRONT_WISHLIST, { productId })\n return data.check_in_storefront_wishlist\n}\n\n/**\n * Add a product to the customer's wishlist.\n */\nexport async function addToWishlist(config: SdkConfig, accessToken: string, productId: string, notes?: string): Promise<WishlistItem> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n product_id: productId,\n notes: notes || undefined,\n }),\n })\n if (!response.ok) throw new Error('Failed to add to wishlist')\n return response.json()\n}\n\n/**\n * Remove an item from the customer's wishlist by item ID.\n */\nexport async function removeFromWishlist(config: SdkConfig, accessToken: string, itemId: string): Promise<void> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/${itemId}`, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to remove from wishlist')\n}\n\n/**\n * Remove a product from the customer's wishlist by product ID.\n */\nexport async function removeProductFromWishlist(config: SdkConfig, accessToken: string, productId: string): Promise<void> {\n const response = await fetch(`${config.backendUrls.store}/wishlist/product/${productId}`, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to remove product from wishlist')\n}\n","/**\n * Payment Service\n * \n * Customer-facing payment API for payment initiation and verification.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n ConversionQuote,\n DVACreateRequest,\n DVADetails,\n PaymentInitiateRequest,\n PaymentInitiateResponse,\n TransactionVerifyResponse,\n} from '../types/payments/index'\n\n/**\n * Create a Monnify Dedicated Virtual Account so the customer can pay via\n * bank transfer. Note: Monnify DVA only supports NGN currency - the backend\n * will reject non-NGN requests for this payment method.\n */\nexport async function createDedicatedAccount(\n config: SdkConfig,\n accessToken: string,\n request: DVACreateRequest\n): Promise<DVADetails> {\n const isValidUUID = (str: string) => {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(str);\n }\n\n const response = await fetch(`${config.backendUrls.payment}/payments/dedicated-account`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n order_id: request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined,\n amount: request.amount,\n customer_email: request.customer_email,\n customer_name: request.customer_name,\n currency: request.currency,\n idempotency_key: request.idempotency_key,\n }),\n })\n if (!response.ok) throw new Error('Failed to create dedicated account')\n const data = await response.json()\n return data\n}\n\n/**\n * Initiate a card payment (customer → business owner).\n * Routes to Monnify (NGN) or Flutterwave (non-NGN) on the backend.\n * Returns a checkout_url to redirect the customer to the gateway.\n */\nexport async function initiatePayment(\n config: SdkConfig,\n accessToken: string,\n request: PaymentInitiateRequest\n): Promise<PaymentInitiateResponse> {\n const isValidUUID = (str: string) => {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(str);\n }\n\n const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined;\n\n const response = await fetch(`${config.backendUrls.payment}/payments/storefront/initiate`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({\n amount: request.amount,\n currency: request.currency,\n order_id: validOrderId,\n quote_id: request.quote_id,\n metadata_json: {\n customer_email: request.customer_email,\n customer_name: request.customer_name ?? '',\n order_id: validOrderId,\n ...(request.metadata ?? {}),\n },\n idempotency_key: request.idempotency_key,\n }),\n })\n if (!response.ok) throw new Error('Failed to initiate payment')\n const data = await response.json()\n\n return {\n id: data.id,\n gateway_ref: data.gateway_ref,\n gateway: data.gateway,\n status: data.status,\n checkout_url: data.metadata_json?.checkout_url ?? '',\n }\n}\n\n/**\n * Request a 15-minute rate-locked conversion quote for non-NGN transactions.\n */\nexport async function requestQuote(\n config: SdkConfig,\n amount: number\n): Promise<ConversionQuote> {\n const response = await fetch(`${config.backendUrls.payment}/payments/quote`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ amount }),\n })\n if (!response.ok) throw new Error('Failed to request quote')\n const data = await response.json()\n return data\n}\n\n/**\n * Verify a payment after the gateway redirects back to /checkout/verify.\n */\nexport async function verifyTransaction(\n configOrReference: SdkConfig | string,\n reference?: string\n): Promise<TransactionVerifyResponse> {\n if (typeof configOrReference === 'string') {\n const ref = configOrReference\n const response = await fetch(`/api/payments/verify/${ref}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n })\n if (!response.ok) throw new Error('Failed to verify transaction')\n return response.json()\n }\n\n const config = configOrReference\n const ref = reference || ''\n const response = await fetch(`${config.backendUrls.payment}/payments/verify/${ref}`, {\n method: 'POST',\n headers: { \n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to verify transaction')\n const data = await response.json()\n return data\n}\n\n/**\n * Poll transaction status by internal transaction ID.\n */\nexport async function getTransactionStatus(\n config: SdkConfig,\n transactionId: string\n): Promise<TransactionVerifyResponse> {\n const response = await fetch(`${config.backendUrls.payment}/payments/transactions/${transactionId}`, {\n headers: { \n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get transaction status')\n const data = await response.json()\n return data\n}\n\nexport const paymentService = {\n createDedicatedAccount,\n initiatePayment,\n requestQuote,\n verifyTransaction,\n getTransactionStatus,\n} as const\n","/**\n * Consultation Service\n * \n * Handles consultation operations for bespoke and service products.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n Consultation,\n ConsultationCreatePayload,\n ConsultationMessagePayload,\n ConsultationQuoteAcceptPayload,\n} from '../types/consultations'\n\nexport async function createConsultation(config: SdkConfig, accessToken: string, payload: ConsultationCreatePayload): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to create consultation')\n return response.json()\n}\n\nexport async function getConsultations(config: SdkConfig, accessToken: string): Promise<Consultation[]> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get consultations')\n return response.json()\n}\n\nexport async function getConsultation(config: SdkConfig, accessToken: string, id: string): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get consultation')\n return response.json()\n}\n\nexport async function sendMessage(config: SdkConfig, accessToken: string, id: string, payload: ConsultationMessagePayload): Promise<void> {\n await fetch(`${config.backendUrls.store}/social/consultations/${id}/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n}\n\nexport async function acceptQuote(config: SdkConfig, accessToken: string, id: string, payload: ConsultationQuoteAcceptPayload): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/accept-quote`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to accept quote')\n return response.json()\n}\n\nexport async function rejectQuote(config: SdkConfig, accessToken: string, id: string, reason?: string): Promise<Consultation> {\n const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/reject-quote`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ reason }),\n })\n if (!response.ok) throw new Error('Failed to reject quote')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const consultationService = {\n createConsultation,\n getConsultations,\n getConsultation,\n sendMessage,\n acceptQuote,\n rejectQuote,\n}\n","/**\n * Logistics Service\n * \n * Handles shipping rates and address validation.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { ShippingRatesResponse } from '../types/store/shipping'\nimport type { Product, ProductVariant } from '../types/store'\n\nexport interface CartItemPayload {\n product: {\n name: string\n price: number\n weight: number\n }\n variant: ProductVariant | null\n quantity: number\n}\n\nexport interface RateAddress {\n city: string\n state: string\n country: string\n}\n\nexport interface ShippingRatesRequest {\n cart_items: CartItemPayload[]\n origin_address: RateAddress\n destination_address: RateAddress\n currency?: string\n}\n\n/**\n * Fetch shipping rates for a cart.\n */\nexport async function getShippingRates(\n config: SdkConfig,\n payload: ShippingRatesRequest\n): Promise<ShippingRatesResponse> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping/rates`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to get shipping rates')\n return response.json()\n}\n\n/**\n * Fetch the seller's registered shipping address.\n */\nexport async function getSellerShippingAddress(config: SdkConfig): Promise<{\n terminal_address_id: string | null\n address_details: {\n city: string\n state: string\n country: string\n line1: string\n line2: string\n zip: string\n } | null\n business_id: string\n message: string\n}> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get seller shipping address')\n return response.json()\n}\n\n/**\n * Validate a shipping address.\n */\nexport async function validateShippingAddress(\n config: SdkConfig,\n payload: {\n first_name: string\n last_name: string\n phone: string\n address_line1: string\n address_line2?: string\n city: string\n state: string\n country: string\n postal_code?: string\n }\n): Promise<{\n valid: boolean\n message?: string\n errorType?: 'state' | 'city' | 'general'\n data?: unknown\n cities?: Array<{ name: string; city_id: string; stateCode: string; countryCode: string }>\n states?: Array<{ name: string; code: string; countryCode: string }>\n}> {\n const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address/validate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to validate shipping address')\n return response.json()\n}\n\n// Service object for backward compatibility\nexport const logisticsService = {\n getShippingRates,\n getSellerShippingAddress,\n validateShippingAddress,\n}\n","/**\n * Bespoke Service\n * \n * Handles bespoke product availability checks.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { BespokeAvailability } from '../types/consultations'\n\nexport async function checkAvailability(config: SdkConfig, product_id: string): Promise<BespokeAvailability> {\n const response = await fetch(`${config.backendUrls.store}/bespoke/availability/${product_id}`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n\n if (!response.ok) throw new Error('Failed to check bespoke availability')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const bespokeService = {\n checkAvailability,\n}\n","/**\n * Service Booking Service\n * \n * Handles service appointments and deliverables.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n ServiceAppointment,\n ServiceAppointmentCreatePayload,\n AvailableSlot,\n ServiceDeliverable,\n DeliverableApprovalPayload,\n} from '../types/services'\n\nexport async function getAvailableSlots(\n config: SdkConfig,\n product_id: string,\n date_from: string,\n date_to: string\n): Promise<AvailableSlot[]> {\n const response = await fetch(\n `${config.backendUrls.store}/service/available-slots/${product_id}?date_from=${date_from}&date_to=${date_to}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n if (!response.ok) throw new Error('Failed to get available slots')\n return response.json()\n}\n\nexport async function bookAppointment(\n config: SdkConfig,\n accessToken: string,\n payload: ServiceAppointmentCreatePayload\n): Promise<ServiceAppointment> {\n const response = await fetch(`${config.backendUrls.store}/service/appointments/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to book appointment')\n return response.json()\n}\n\nexport async function getAppointments(config: SdkConfig, accessToken: string): Promise<ServiceAppointment[]> {\n const response = await fetch(`${config.backendUrls.store}/service/bookings/my`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get appointments')\n return response.json()\n}\n\nexport async function getAppointment(config: SdkConfig, accessToken: string, id: string): Promise<ServiceAppointment> {\n const response = await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get appointment')\n return response.json()\n}\n\nexport async function cancelAppointment(config: SdkConfig, accessToken: string, id: string): Promise<void> {\n await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {\n method: 'DELETE',\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n}\n\nexport async function getDeliverables(config: SdkConfig, accessToken: string, order_id: string): Promise<ServiceDeliverable[]> {\n const response = await fetch(`${config.backendUrls.store}/service/projects/${order_id}/deliverables/`, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get deliverables')\n return response.json()\n}\n\nexport async function approveDeliverable(\n config: SdkConfig,\n accessToken: string,\n order_id: string,\n deliverable_id: string\n): Promise<ServiceDeliverable> {\n const response = await fetch(\n `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/approve`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ approved: true }),\n }\n )\n if (!response.ok) throw new Error('Failed to approve deliverable')\n return response.json()\n}\n\nexport async function requestRevision(\n config: SdkConfig,\n accessToken: string,\n order_id: string,\n deliverable_id: string,\n feedback: string\n): Promise<ServiceDeliverable> {\n const response = await fetch(\n `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/revision`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify({ approved: false, feedback }),\n }\n )\n if (!response.ok) throw new Error('Failed to request revision')\n return response.json()\n}\n\n// Service object export for backward compatibility\nexport const serviceBookingService = {\n getAvailableSlots,\n bookAppointment,\n getAppointments,\n getAppointment,\n cancelAppointment,\n getDeliverables,\n approveDeliverable,\n requestRevision,\n}\n","/**\n * Notification Service\n * \n * Handles contact form submissions and email notifications.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\n\nexport interface ContactFormData {\n name: string\n email: string\n subject: string\n message: string\n source?: string\n company_name?: string\n current_year?: number\n turnstile_token?: string\n}\n\n/**\n * Send contact email to Kasuvia team.\n * POST /contact/send-contact-email\n */\nexport async function sendContactEmail(\n config: SdkConfig,\n payload: ContactFormData\n): Promise<{ detail: string }> {\n const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-email`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to send contact email')\n return response.json()\n}\n\n/**\n * Send confirmation email to user.\n * POST /contact/send-contact-confirmation\n */\nexport async function sendContactConfirmation(\n config: SdkConfig,\n payload: Omit<ContactFormData, 'turnstile_token'>\n): Promise<{ detail: string }> {\n const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-confirmation`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(payload),\n })\n if (!response.ok) throw new Error('Failed to send contact confirmation')\n return response.json()\n}\n\nexport const notificationsService = {\n sendContactEmail,\n sendContactConfirmation,\n} as const\n","/**\n * App Service\n * \n * Handles translation and other app-level utilities.\n */\n\nexport async function googleTranslate(text: string, target: string, source = \"en\"): Promise<string> {\n if (!text || target === source) return text;\n try {\n const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${source}&tl=${target}&dt=t&q=${encodeURIComponent(text)}`;\n const res = await fetch(url);\n const data = (await res.json()) as [Array<[string, string]>, ...unknown[]];\n return (data?.[0] || []).map((s) => s[0]).join(\"\");\n } catch {\n return text;\n }\n}\n","/**\n * Config Service\n *\n * Handles configuration endpoints (languages, currencies, locales, business config).\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { BackendLanguage, SupportedLanguagesResponse, SupportedCurrenciesResponse } from '../types/payments'\nimport type { BusinessConfig } from '../types/business'\n\n/**\n * Fetch supported languages from the payment system.\n * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-languages\n */\nexport async function getSupportedLanguages(config: SdkConfig): Promise<SupportedLanguagesResponse> {\n const response = await fetch(`${config.backendUrls.payment}/config/supported-languages`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get supported languages')\n return response.json()\n}\n\n/**\n * Fetch supported currencies from the payment system.\n * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-currencies\n */\nexport async function getSupportedCurrencies(config: SdkConfig): Promise<SupportedCurrenciesResponse> {\n const response = await fetch(`${config.backendUrls.payment}/config/supported-currencies`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get supported currencies')\n return response.json()\n}\n\n/**\n * Fetch the business's public configuration, including store_currency.\n * Uses storefront API key header (X-Storefront-Key).\n * Resolves to: {kasuviaAuthBackendUrl}/internal/businesses/{business_id}/\n * This endpoint is designed for storefronts to fetch business config using their storefront API key.\n */\nexport async function getBusinessConfig(config: SdkConfig): Promise<BusinessConfig> {\n const response = await fetch(`${config.backendUrls.auth}/internal/businesses/${config.businessId}/`, {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n })\n if (!response.ok) throw new Error('Failed to get business config')\n return response.json()\n}\n\nexport const configService = {\n getSupportedLanguages,\n getSupportedCurrencies,\n getBusinessConfig,\n} as const\n","/**\n * CMS Service\n * \n * Handles CMS model and entry operations using the kasuvia-cms SDK endpoints.\n * Protected by X-Storefront-Key and X-Business-ID headers.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n CmsEntry,\n CmsEntryListResponse,\n CreateCmsEntryParams,\n UpdateCmsEntryParams,\n ListCmsEntriesParams,\n} from '../types/cms'\n\n/**\n * List CMS entries for a specific model.\n * Requires public_api.read permission on the model.\n */\nexport async function listCmsEntries(\n config: SdkConfig,\n modelSlug: string,\n params?: ListCmsEntriesParams\n): Promise<CmsEntryListResponse> {\n const queryParams = new URLSearchParams()\n queryParams.set('page', (params?.page || 1).toString())\n queryParams.set('page_size', (params?.page_size || 50).toString())\n\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries?${queryParams.toString()}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to list CMS entries')\n return response.json()\n}\n\n/**\n * Get a single CMS entry by ID.\n * Requires public_api.read permission on the model.\n */\nexport async function getCmsEntry(\n config: SdkConfig,\n modelSlug: string,\n entryId: string\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n headers: {\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to get CMS entry')\n return response.json()\n}\n\n/**\n * Create a new CMS entry.\n * Requires public_api.create permission on the model.\n */\nexport async function createCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n params: CreateCmsEntryParams\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(params),\n }\n )\n\n if (!response.ok) throw new Error('Failed to create CMS entry')\n return response.json()\n}\n\n/**\n * Update an existing CMS entry.\n * Requires public_api.update permission on the model.\n */\nexport async function updateCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n entryId: string,\n params: UpdateCmsEntryParams\n): Promise<CmsEntry> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n body: JSON.stringify(params),\n }\n )\n\n if (!response.ok) throw new Error('Failed to update CMS entry')\n return response.json()\n}\n\n/**\n * Delete a CMS entry.\n * Requires public_api.delete permission on the model.\n */\nexport async function deleteCmsEntry(\n config: SdkConfig,\n accessToken: string,\n modelSlug: string,\n entryId: string\n): Promise<void> {\n const response = await fetch(\n `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,\n {\n method: 'DELETE',\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"X-Storefront-Key\": config.storefrontApiKey,\n \"X-Business-ID\": config.businessId,\n },\n }\n )\n\n if (!response.ok) throw new Error('Failed to delete CMS entry')\n}\n","/**\n * Cache Tiers Utility\n * \n * Provides cache configuration for React Query based on environment.\n */\n\nconst CACHE_TIERS = {\n none: { staleTime: 0, gcTime: 0 },\n infinity: { staleTime: Infinity, gcTime: 0 },\n low: { staleTime: 1000 * 30, gcTime: 1000 * 60 }, // 30s / 1m\n medium: { staleTime: 1000 * 60 * 5, gcTime: 1000 * 60 * 10 }, // 5m / 10m\n high: { staleTime: 1000 * 60 * 30, gcTime: 1000 * 60 * 60 }, // 30m / 1h\n} as const;\n\nexport type CacheTier = keyof typeof CACHE_TIERS;\n\nlet isDevelopment = true;\n\n/**\n * Set the environment mode for cache configuration\n */\nexport function setEnvironmentMode(development: boolean): void {\n isDevelopment = development;\n}\n\n/**\n * Get cache configuration for a given tier\n * In development, returns 'none' tier to disable caching\n */\nexport const getCacheTier = (tier: CacheTier) => {\n if (isDevelopment) return CACHE_TIERS.none;\n return CACHE_TIERS[tier];\n};\n","/**\n * Logger Utility\n * \n * Environment-gated logger that suppresses output in production.\n */\n\nlet isDevelopment = true;\n\n/**\n * Set the environment mode for logging\n */\nexport function setLoggerEnvironmentMode(development: boolean): void {\n isDevelopment = development;\n}\n\nexport const logger = {\n log: (...args: unknown[]) => {\n if (isDevelopment) {\n console.log(...args)\n }\n },\n\n warn: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(...args)\n }\n },\n\n /**\n * Logs a warning to the console in development only.\n * Alias for warn() for Python logging compatibility.\n * In production, this is a no-op.\n */\n warning: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(...args)\n }\n },\n\n error: (...args: unknown[]) => {\n if (isDevelopment) {\n console.error(...args)\n }\n },\n\n info: (...args: unknown[]) => {\n if (isDevelopment) {\n console.info(...args)\n }\n },\n\n createScope: (scope: string) => ({\n log: (...args: unknown[]) => {\n if (isDevelopment) {\n console.log(`[${scope}]`, ...args)\n }\n },\n warn: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(`[${scope}]`, ...args)\n }\n },\n warning: (...args: unknown[]) => {\n if (isDevelopment) {\n console.warn(`[${scope}]`, ...args)\n }\n },\n error: (...args: unknown[]) => {\n if (isDevelopment) {\n console.error(`[${scope}]`, ...args)\n }\n },\n info: (...args: unknown[]) => {\n if (isDevelopment) {\n console.info(`[${scope}]`, ...args)\n }\n },\n }),\n}\n","export class InvalidBaseURLError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"InvalidBaseURLError\";\r\n }\r\n}\r\n\r\nconst ALLOWED_SCHEMES = new Set([\"http:\", \"https:\", \"ws:\", \"wss:\"]);\r\n\r\n/**\r\n * Normalizes a URL by trimming whitespace and stripping trailing slashes.\r\n */\r\nexport function sanitizeBaseUrl(\r\n url: string | undefined | null,\r\n name = \"URL\"\r\n): string {\r\n if (url == null) {\r\n throw new InvalidBaseURLError(`${name} is not set`);\r\n }\r\n\r\n const cleaned0 = url.trim();\r\n if (!cleaned0) {\r\n throw new InvalidBaseURLError(`${name} is empty`);\r\n }\r\n\r\n // Strip all trailing slashes\r\n const cleaned = cleaned0.replace(/\\/+$/, \"\");\r\n\r\n let parsed: URL;\r\n try {\r\n parsed = new URL(cleaned);\r\n } catch {\r\n throw new InvalidBaseURLError(\r\n `${name} must start with http://, https://, ws://, or wss://, got: ${url}`\r\n );\r\n }\r\n\r\n if (!ALLOWED_SCHEMES.has(parsed.protocol)) {\r\n throw new InvalidBaseURLError(\r\n `${name} must start with http://, https://, ws://, or wss://, got: ${url}`\r\n );\r\n }\r\n\r\n if (!parsed.hostname) {\r\n throw new InvalidBaseURLError(`${name} is missing a host: ${url}`);\r\n }\r\n\r\n if (parsed.search || parsed.hash) {\r\n throw new InvalidBaseURLError(\r\n `${name} should not contain a query or fragment: ${url}`\r\n );\r\n }\r\n\r\n return cleaned;\r\n}","import type { CustomerUser } from \"../types\";\n\nexport function buildFullName(firstname?: string, lastname?: string): string | undefined {\n const name = [firstname, lastname].filter(Boolean).join(' ').trim()\n return name || undefined\n}\n\nexport function splitFullName(fullName?: string): { firstname: string; lastname: string } {\n if (!fullName?.trim()) return { firstname: '', lastname: '' }\n const parts = fullName.trim().split(/\\s+/)\n return {\n firstname: parts[0] ?? '',\n lastname: parts.slice(1).join(' '),\n }\n}\n\nexport function getCustomerDisplayName(user: CustomerUser): string {\n const fromParts = buildFullName(user.firstname, user.lastname)\n return fromParts || user.full_name || user.email.split('@')[0]\n}\n\n/**\n * Constructs live storefront URL for a business.\n * If custom domain is not yet connected/verified, defaults to `https://<business_id>.kasuvia.com`.\n */\nexport function getStorefrontUrl(businessId: string, customDomain?: string | null): string {\n if (customDomain && customDomain.trim()) {\n const cleanDomain = customDomain.trim().replace(/^https?:\\/\\//, '');\n return `https://${cleanDomain}`;\n }\n const cleanBid = (businessId || 'store').toLowerCase().trim();\n return `https://${cleanBid}.kasuvia.com`;\n}\n\n","import { buildFullName } from \"./customer\";\nimport type { CheckoutCustomer, DeliveryAddress, Order, ShippingLocation } from \"../types\";\n\nexport function buildDeliveryAddress(customer: CheckoutCustomer, location: ShippingLocation): DeliveryAddress {\n return {\n first_name: customer.first_name,\n last_name: customer.last_name,\n phone: customer.phone,\n ...location,\n };\n}\n\nexport function getCheckoutCustomerName(customer: CheckoutCustomer): string {\n return buildFullName(customer.first_name, customer.last_name) ?? customer.email.split(\"@\")[0];\n}\n\nexport function enrichCompletedOrder(\n order: Order,\n options: {\n customer: CheckoutCustomer;\n location?: ShippingLocation;\n bespokeBrief?: string;\n productType?: \"physical\" | \"digital\" | \"bespoke\" | null;\n },\n): Order {\n const customerName = getCheckoutCustomerName(options.customer);\n\n return {\n ...order,\n customerName: order.customerName || customerName,\n customerEmail: order.customerEmail || options.customer.email,\n shippingAddress:\n order.shippingAddress ??\n (options.productType === \"physical\" && options.location\n ? buildDeliveryAddress(options.customer, options.location)\n : undefined),\n bespokeBrief: order.bespokeBrief ?? options.bespokeBrief,\n };\n}\n","/**\n * Type-safe way to extract an error message from an API error.\n * Updated for fetch-based errors (no axios dependency).\n */\nexport function getErrorMessage(error: unknown, fallback: string = \"Something went wrong\"): string {\n if (error instanceof Error) {\n return error.message;\n }\n // Handle fetch Response objects that might be thrown\n if (error instanceof Response) {\n return `HTTP ${error.status}: ${error.statusText}`;\n }\n // Handle objects with detail or message properties (from API responses)\n if (typeof error === 'object' && error !== null) {\n const err = error as { detail?: string; message?: string; status?: number };\n return err.detail || err.message || fallback;\n }\n return fallback;\n}\n","/**\n * @file storage.ts\n * @description Centralized tenant-isolated storage utility for sessionStorage and localStorage.\n * Automatically prefixes all keys with the storefront Business ID to guarantee multi-tenant segregation.\n * Stateless - requires businessId parameter.\n */\n\nfunction getPrefixedKey(businessId: string, key: string): string {\n const cleanKey = key.startsWith('kasuvia_') ? key.substring(5) : key\n return businessId ? `kasuvia-sf-${businessId}-${cleanKey}` : `kasuvia-sf-anon-${cleanKey}`\n}\n\nexport const sessionStore = {\n get: (businessIdOrKey: string, key?: string): string | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n return sessionStorage.getItem(getPrefixedKey(bId, k))\n },\n set: (businessIdOrKey: string, keyOrVal: string, val?: string): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? businessIdOrKey : ''\n const k = val !== undefined ? keyOrVal : businessIdOrKey\n const v = val !== undefined ? val : keyOrVal\n sessionStorage.setItem(getPrefixedKey(bId, k), v)\n },\n remove: (businessIdOrKey: string, key?: string): void => {\n if (typeof window === 'undefined') return\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n sessionStorage.removeItem(getPrefixedKey(bId, k))\n },\n getJSON: <T = unknown>(businessIdOrKey: string, key?: string): T | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n const value = sessionStorage.getItem(getPrefixedKey(bId, k))\n if (!value) return null\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n },\n setJSON: (businessIdOrKey: string, keyOrVal: unknown, val?: unknown): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? (businessIdOrKey as string) : ''\n const k = val !== undefined ? (keyOrVal as string) : (businessIdOrKey as string)\n const v = val !== undefined ? val : keyOrVal\n sessionStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v))\n },\n}\n\nexport const localStore = {\n get: (businessIdOrKey: string, key?: string): string | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n return localStorage.getItem(getPrefixedKey(bId, k))\n },\n set: (businessIdOrKey: string, keyOrVal: string, val?: string): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? businessIdOrKey : ''\n const k = val !== undefined ? keyOrVal : businessIdOrKey\n const v = val !== undefined ? val : keyOrVal\n localStorage.setItem(getPrefixedKey(bId, k), v)\n },\n remove: (businessIdOrKey: string, key?: string): void => {\n if (typeof window === 'undefined') return\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n localStorage.removeItem(getPrefixedKey(bId, k))\n },\n getJSON: <T = unknown>(businessIdOrKey: string, key?: string): T | null => {\n if (typeof window === 'undefined') return null\n const bId = key ? businessIdOrKey : ''\n const k = key || businessIdOrKey\n const value = localStorage.getItem(getPrefixedKey(bId, k))\n if (!value) return null\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n },\n setJSON: (businessIdOrKey: string, keyOrVal: unknown, val?: unknown): void => {\n if (typeof window === 'undefined') return\n const bId = val !== undefined ? (businessIdOrKey as string) : ''\n const k = val !== undefined ? (keyOrVal as string) : (businessIdOrKey as string)\n const v = val !== undefined ? val : keyOrVal\n localStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v))\n },\n}\n","/**\n * Form validation utilities for kasuvia-sdk\n * Provides realtime validation for email, password, name, confirm password, and message fields\n */\n\nexport function validateEmail(email: string): string | null {\n if (!email || email.trim() === \"\") {\n return \"Email is required\";\n }\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email)) {\n return \"Please enter a valid email address\";\n }\n return null;\n}\n\nexport function validatePassword(password: string): string | null {\n if (!password || password.trim() === \"\") {\n return \"Password is required\";\n }\n if (password.length < 8) {\n return \"Password must be at least 8 characters\";\n }\n if (password.length > 72) {\n return \"Password cannot exceed 72 characters\";\n }\n if (!/[A-Z]/.test(password)) {\n return \"Password must contain at least one uppercase letter\";\n }\n if (!/[a-z]/.test(password)) {\n return \"Password must contain at least one lowercase letter\";\n }\n if (!/[0-9]/.test(password)) {\n return \"Password must contain at least one number\";\n }\n return null;\n}\n\nexport function validateName(name: string, fieldName: string = \"Name\"): string | null {\n if (!name || name.trim() === \"\") {\n return `${fieldName} is required`;\n }\n if (name.trim().length < 2) {\n return `${fieldName} must be at least 2 characters`;\n }\n if (name.trim().length > 50) {\n return `${fieldName} cannot exceed 50 characters`;\n }\n // Allow letters, spaces, hyphens, and apostrophes\n const nameRegex = /^[a-zA-Z\\s\\-'\\u00C0-\\u017F]+$/;\n if (!nameRegex.test(name.trim())) {\n return `${fieldName} can only contain letters, spaces, hyphens, and apostrophes`;\n }\n return null;\n}\n\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value || value.trim() === \"\") {\n return `${fieldName} is required`;\n }\n return null;\n}\n\n/**\n * Validates the confirm-password field.\n * Returns null (no error) when the field is empty — avoids nagging the user\n * before they've had a chance to type anything.\n */\nexport function validateConfirmPassword(password: string, confirmPassword: string): string | null {\n if (!confirmPassword) return null;\n if (confirmPassword !== password) {\n return \"Passwords do not match\";\n }\n return null;\n}\n\nexport function validateMessage(message: string): string | null {\n if (!message || message.trim() === \"\") {\n return \"Message is required\";\n }\n if (message.trim().length < 10) {\n return \"Message must be at least 10 characters\";\n }\n return null;\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmF9B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmF/B,IAAM,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;AAAA;AAAA;AAAA;AAmFhC,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsF3B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsF/B,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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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","names":["ServiceTypeEnum","ServiceLocationTypeEnum","ServiceRecurringIntervalEnum","response","data","payload","refreshToken","GraphQLClient","createGraphQLClient","GraphQLClient","createGraphQLClient","ref","response","isDevelopment","buildFullName","splitFullName","buildFullName"]}