@kasuvia/sdk 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -15
- package/dist/AddressAutocomplete-CjcqPElD.d.mts +46 -0
- package/dist/AddressAutocomplete-CvJHuRkf.d.ts +46 -0
- package/dist/components/index.d.mts +497 -0
- package/dist/components/index.d.ts +497 -0
- package/dist/components/index.js +4217 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +4194 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/server.d.mts +26 -0
- package/dist/config/server.d.ts +26 -0
- package/dist/config/server.js +38 -0
- package/dist/config/server.js.map +1 -0
- package/dist/config/server.mjs +13 -0
- package/dist/config/server.mjs.map +1 -0
- package/dist/hooks/index.d.mts +393 -160
- package/dist/hooks/index.d.ts +393 -160
- package/dist/hooks/index.js +2792 -2137
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +2734 -2121
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index-CNW_LINy.d.mts +578 -0
- package/dist/index-CNW_LINy.d.ts +578 -0
- package/dist/{index-C1chUA3P.d.mts → index-F7N6UItS.d.mts} +1 -1
- package/dist/{index-C1chUA3P.d.ts → index-F7N6UItS.d.ts} +1 -1
- package/dist/index-NkI10J_E.d.mts +40 -0
- package/dist/index-NkI10J_E.d.ts +40 -0
- package/dist/index.d.mts +20437 -103
- package/dist/index.d.ts +20437 -103
- package/dist/index.js +2111 -1802
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2006 -1786
- package/dist/index.mjs.map +1 -1
- package/dist/media.service-Cx7dQjzX.d.mts +1393 -0
- package/dist/media.service-mrBFJ2UQ.d.ts +1393 -0
- package/dist/services/index.d.mts +908 -2
- package/dist/services/index.d.ts +908 -2
- package/dist/services/index.js +1492 -1686
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +1431 -1670
- package/dist/services/index.mjs.map +1 -1
- package/package.json +46 -6
- package/src/components/bespoke/BespokeAvailabilityBadge.tsx +32 -0
- package/src/components/bespoke/BespokeProgressTracker.tsx +58 -0
- package/src/components/bespoke/index.ts +3 -0
- package/src/components/booking/SlotPicker.tsx +97 -0
- package/src/components/booking/index.ts +1 -0
- package/src/components/cart/CartItem.tsx +81 -0
- package/src/components/cart/CartSidebar.tsx +115 -0
- package/src/components/cart/CartTypeMismatchBanner.tsx +55 -0
- package/src/components/cart/index.ts +3 -0
- package/src/components/index.ts +8 -0
- package/src/components/orders/DeliverableReviewer.tsx +139 -0
- package/src/components/orders/index.ts +1 -0
- package/src/components/product/ProductCard.tsx +350 -0
- package/src/components/product/ProductGrid.tsx +84 -0
- package/src/components/product/index.ts +2 -0
- package/src/components/shared/AddressAutocomplete.tsx +212 -0
- package/src/components/shared/AnalyticsScripts.tsx +56 -0
- package/src/components/shared/CookieConsentBanner.tsx +98 -0
- package/src/components/shared/ImageEditorModal.tsx +1066 -0
- package/src/components/shared/ImageViewerModal.tsx +598 -0
- package/src/components/shared/LucideReactIcon.tsx +52 -0
- package/src/components/shared/MapPinDrop.tsx +101 -0
- package/src/components/shared/MultiSelectPicker.tsx +193 -0
- package/src/components/shared/OfflineBanner.tsx +46 -0
- package/src/components/shared/SearchableInput.tsx +153 -0
- package/src/components/shared/SearchablePopover.tsx +166 -0
- package/src/components/shared/SmartImage.tsx +311 -0
- package/src/components/shared/TruncatedValue.tsx +27 -0
- package/src/components/shared/UnsavedChangesGuard.tsx +138 -0
- package/src/components/shared/index.ts +15 -0
- package/src/components/skeletons/CardSkeleton.tsx +26 -0
- package/src/components/skeletons/CartItemSkeleton.tsx +26 -0
- package/src/components/skeletons/OrderItemSkeleton.tsx +26 -0
- package/src/components/skeletons/ProductCardSkeleton.tsx +26 -0
- package/src/components/skeletons/TableSkeleton.tsx +42 -0
- package/src/components/skeletons/index.ts +5 -0
- package/src/config/index.ts +22 -4
- package/src/config/server.ts +45 -0
- package/src/context/sdk-context.tsx +5 -2
- package/src/generated/auth-openapi.ts +2935 -0
- package/src/generated/cart-openapi.ts +652 -0
- package/src/generated/cms-openapi.ts +1668 -0
- package/src/generated/crm-openapi.ts +986 -0
- package/src/generated/graphql.ts +126 -0
- package/src/generated/index.ts +11 -0
- package/src/generated/media-openapi.ts +613 -0
- package/src/generated/notification-openapi.ts +862 -0
- package/src/generated/payment-openapi.ts +2713 -0
- package/src/generated/store-openapi.ts +9510 -0
- package/src/graphql/operations/collections.graphql +32 -0
- package/src/graphql/operations/products.graphql +197 -0
- package/src/graphql/operations/wishlist.graphql +25 -0
- package/src/hooks/index.ts +9 -2
- package/src/hooks/use-auth.ts +163 -69
- package/src/hooks/use-bespoke-availability.ts +39 -22
- package/src/hooks/use-business-config.ts +51 -0
- package/src/hooks/use-cart.ts +310 -238
- package/src/hooks/use-cms.ts +107 -127
- package/src/hooks/use-collections.ts +35 -55
- package/src/hooks/use-consultations.ts +9 -136
- package/src/hooks/use-countries.ts +19 -28
- package/src/hooks/use-currencies.ts +8 -20
- package/src/hooks/use-customer-address.ts +64 -0
- package/src/hooks/use-feedback.ts +34 -0
- package/src/hooks/use-languages.ts +26 -39
- package/src/hooks/use-media-upload.ts +23 -0
- package/src/hooks/use-notification-stream.ts +88 -0
- package/src/hooks/use-notifications.ts +163 -0
- package/src/hooks/use-order-stream.ts +29 -29
- package/src/hooks/use-orders.ts +91 -73
- package/src/hooks/use-payment.ts +116 -84
- package/src/hooks/use-products.ts +65 -269
- package/src/hooks/use-push-notifications.ts +122 -0
- package/src/hooks/use-reviews.ts +175 -0
- package/src/hooks/use-service-booking.ts +109 -132
- package/src/hooks/use-states.ts +16 -30
- package/src/hooks/use-wishlist.ts +44 -69
- package/src/index.ts +15 -11
- package/src/services/auth.service.ts +422 -132
- package/src/services/bespoke.service.ts +69 -10
- package/src/services/cart.service.ts +155 -186
- package/src/services/cms.service.ts +41 -50
- package/src/services/collection.service.ts +25 -63
- package/src/services/config.service.ts +10 -21
- package/src/services/consultation.service.ts +36 -93
- package/src/services/feedback.service.ts +76 -0
- package/src/services/index.ts +7 -1
- package/src/services/legal.service.ts +62 -0
- package/src/services/logistics.service.ts +235 -53
- package/src/services/media.service.ts +115 -0
- package/src/services/notifications.service.ts +204 -20
- package/src/services/order.service.ts +498 -127
- package/src/services/payment.service.ts +149 -100
- package/src/services/product.service.ts +157 -814
- package/src/services/review.service.ts +211 -0
- package/src/services/service-booking.service.ts +198 -99
- package/src/services/wishlist.service.ts +27 -74
- package/src/types/auth/index.ts +161 -18
- package/src/types/business/index.ts +9 -1
- package/src/types/cms/index.ts +91 -6
- package/src/types/cms/legal.ts +18 -0
- package/src/types/consultations/index.ts +60 -68
- package/src/types/index.ts +5 -3
- package/src/types/media/index.ts +35 -3
- package/src/types/payments/index.ts +80 -16
- package/src/types/reviews/index.ts +116 -0
- package/src/types/services/index.ts +113 -38
- package/src/types/store/checkout.ts +53 -0
- package/src/types/store/index.ts +273 -52
- package/src/types/store/invoice.ts +31 -0
- package/src/types/store/shipping.ts +84 -3
- package/src/types/ui/index.ts +1 -1
- package/src/utils/checkout.ts +19 -3
- package/src/utils/cookieConsent.ts +34 -0
- package/src/utils/format.ts +408 -0
- package/src/utils/geolocation.ts +134 -0
- package/src/utils/graphql-url.ts +47 -0
- package/src/utils/guest-session.ts +59 -0
- package/src/utils/http-client.ts +147 -0
- package/src/utils/index.ts +11 -4
- package/src/utils/status-colors.ts +79 -0
- package/src/utils/token-refresh.ts +115 -0
- package/src/utils/validators.ts +13 -0
- package/src/utils/youtube.ts +18 -0
- package/dist/index-C5YO9gTl.d.mts +0 -507
- package/dist/index-C5YO9gTl.d.ts +0 -507
- package/dist/index-CefG7_xq.d.mts +0 -793
- package/dist/index-DeHCf3zI.d.ts +0 -793
- package/src/graphql/collections.graphql.ts +0 -48
- package/src/graphql/index.ts +0 -7
- package/src/graphql/products.graphql.ts +0 -860
- package/src/graphql/wishlist.graphql.ts +0 -34
- package/src/hooks/use-consultation-stream.ts +0 -142
- package/src/types/bespoke/index.ts +0 -39
package/dist/index.mjs.map
CHANGED
|
@@ -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\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/types/store/index.ts","../src/types/payments/index.ts","../src/types/reviews/index.ts","../src/utils/token-refresh.ts","../src/utils/http-client.ts","../src/services/cart.service.ts","../src/services/order.service.ts","../src/services/consultation.service.ts","../src/services/feedback.service.ts","../src/utils/customer.ts","../src/services/auth.service.ts","../src/utils/graphql-url.ts","../src/generated/graphql.ts","../src/services/product.service.ts","../src/services/collection.service.ts","../src/services/wishlist.service.ts","../src/services/payment.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/services/legal.service.ts","../src/services/review.service.ts","../src/services/media.service.ts","../src/utils/cache.ts","../src/utils/logger.ts","../src/utils/storage.ts","../src/utils/sanitize-url.ts","../src/utils/checkout.ts","../src/utils/error-handler.ts","../src/utils/format.ts","../src/utils/geolocation.ts","../src/utils/status-colors.ts","../src/utils/youtube.ts","../src/utils/cookieConsent.ts","../src/utils/validators.ts","../src/utils/guest-session.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 * from \"./invoice\";\nexport * from \"./checkout\";\nexport type { DeliveryAddress };\n\nexport enum ProductTypeEnum {\n PHYSICAL = \"physical\",\n DIGITAL = \"digital\",\n SERVICE = \"service\",\n BESPOKE = \"bespoke\",\n}\n\nexport type ProductType = ProductTypeEnum | \"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\n// REAL BUG FIXED (2026-09-21): these values didn't match anything the real\n// backend ever stores — kasuvia-store-management's Product.service_location_type\n// (app/models/catalog.py) is validated against exactly \"remote\" |\n// \"at_business\" | \"customer_location\". The old \"physical\"/\"both\" values\n// would never match a real product's actual value.\nexport enum ServiceLocationTypeEnum {\n REMOTE = 'remote',\n AT_BUSINESS = 'at_business',\n CUSTOMER_LOCATION = 'customer_location',\n}\n\nexport type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | 'at_business' | 'customer_location'\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 collection_type?: string\n /** Raw JSON string of smart-collection matching rules (kasuvia-store-management's own evaluation detail, never parsed client-side) — the real backend GraphQL field is a String scalar, not a structured object. */\n rules?: string\n image_url?: string\n image_id?: string\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 length_cm?: number\n width_cm?: number\n height_cm?: number\n is_active: boolean\n inventory?: Inventory\n}\n\nexport interface CustomField {\n label: string\n unit?: string\n required: boolean\n /** \"text\" (free text/number input) or \"choice\" (customer picks from\n * `options`) — matches kasuvia-store-management's CustomFieldSchema. */\n field_type: \"text\" | \"choice\"\n /** Only meaningful when field_type is \"choice\" - the pick list a\n * merchant configured. Always [] for a \"text\" field. */\n options: string[]\n}\n\n/** One file of a DIGITAL/MIXED product (kasuvia-store-management's ProductDigitalFile) — replaces the old dropped single `digital_file_key` scalar. */\nexport interface ProductDigitalFile {\n id: string\n file_key: string\n display_name: string\n sort_order: number\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\n is_non_returnable?: boolean\n deposit_percentage?: number\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 /** Real fields (kasuvia-crm's review pipeline syncs into these). */\n average_rating?: number | null\n rating_count: number\n /** \"kasuvia\" for organic products, a real channel key (\"whatsapp\", etc.) for channel-imported products. */\n source_channel: string\n source_channel_ref_id?: string | null\n digital_files: ProductDigitalFile[]\n download_limit?: number\n download_expires_at?: string\n service_type?: ServiceType\n service_duration_minutes?: number\n service_location_type?: ServiceLocationType\n /** Only meaningful when service_location_type === \"customer_location\". */\n service_coverage_radius_km?: number | null\n service_requires_consultation?: boolean\n service_max_capacity_per_slot?: number\n service_buffer_minutes?: number\n service_is_recurring?: boolean\n service_recurring_interval?: ServiceRecurringInterval\n service_project_based?: boolean\n weight_kg?: number\n length_cm?: number\n width_cm?: number\n height_cm?: number\n variants?: ProductVariant[]\n collections?: Collection[]\n inventory?: Inventory\n created_at: string\n updated_at: string\n}\n\nexport interface ProductListResponse {\n items: Product[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport interface CollectionListResponse {\n items: Collection[]\n total: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport interface ListParams {\n page?: number\n pageSize?: number\n collectionSlug?: string\n search?: string\n excludeProductId?: string\n /** One of physical/digital/service/bespoke — omit to browse the whole catalog. */\n productType?: ProductType\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_url?: 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 product_type?: ProductType\n created_at: string\n updated_at: string\n}\n\nexport interface CartResponse {\n /**\n * The Redis cart key returned by kasuvia-cart-management on every cart operation.\n * Used to correlate a cart with a shipping-rate quote and checkout session.\n */\n id?: string\n items: CartItem[]\n subtotal: number\n total: number\n item_count: number\n product_type?: ProductType\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 /**\n * REAL BUG FIXED (2026-09-21): was typed as an object\n * (`Record<string, unknown> | null`) but the real GraphQL resolver\n * (kasuvia-store-management's queries.py storefront wishlist query)\n * returns a plain image URL string — a live consumer's `typeof === 'object'`\n * check against this field was always false, silently hiding every\n * wishlist item's image.\n */\n product_image?: string | null\n /** Real field (queries.py's `item.product.currency`) — the SDK's own GET_STOREFRONT_WISHLIST query already fetches it. */\n currency?: 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' // Carrier pickup (for carrier shipping)\n | 'ready_for_pickup' // Customer self-pickup: order ready for customer collection\n | 'picked_up_by_customer' // Customer self-pickup: customer has collected the order\n | 'in_transit'\n | 'shipped'\n | 'delivered'\n | 'voided'\n | 'refunded'\n | 'failed';\n\nexport interface OrderItem {\n id: string;\n order_id?: string;\n product_id?: string;\n variant_id?: string;\n product_name: string;\n quantity: number;\n unit_price: number;\n variant_details?: Record<string, unknown>;\n custom_measurements?: Record<string, unknown>;\n image_url?: string;\n}\n\nexport interface Order {\n id: string;\n display_id: string;\n business_id: string;\n customer_id?: string;\n status: OrderStatus;\n payment_status: string;\n product_type?: ProductType;\n subtotal_amount?: number;\n discount_amount?: number;\n discount_code?: string;\n tax_amount?: number;\n shipping_amount?: number;\n total_amount: number;\n currency: string;\n customer_name?: string;\n customer_email?: string;\n carrier_name?: string;\n carrier_slug?: string;\n terminal_rate_id?: string;\n tracking_number?: string;\n delivery_status?: string;\n guest_token?: string;\n guest_email?: string;\n guest_phone?: string;\n guest_name?: string;\n\n // Weight discrepancy & surcharge fields (Task 2)\n shipping_surcharge_amount?: number;\n shipping_surcharge_reason?: string;\n shipping_surcharge_description?: string;\n shipping_surcharge_applied_at?: string;\n declared_weight_kg?: number;\n actual_weight_kg?: number;\n\n // Self-pickup verification fields (Task 3)\n pickup_verification_code?: string;\n pickup_verification_code_generated_at?: string;\n pickup_verification_code_used_at?: string;\n pickup_verification_failed_attempts?: number;\n pickup_verification_locked_until?: string;\n pickup_qr_payload?: string;\n\n // Bespoke fields (Batch 4)\n bespoke_brief?: string;\n bespoke_reference_images?: string[];\n bespoke_measurements?: Record<string, unknown>;\n bespoke_preferred_timeline?: string;\n bespoke_special_instructions?: string;\n bespoke_deposit_ratio?: number;\n bespoke_deposit_amount?: number;\n bespoke_balance_amount?: number;\n /** BespokeFulfillmentStatus: \"processing\" | \"awaiting_approval\" | \"under_review\" | \"confirmed\". */\n bespoke_status?: string;\n bespoke_deliverable_submitted_at?: string;\n bespoke_deliverable_url?: string;\n bespoke_deliverable_notes?: string;\n bespoke_buyer_approved_at?: string;\n bespoke_revision_count?: number;\n bespoke_revision_notes?: string;\n\n items: OrderItem[];\n buyer_country?: string;\n withdrawal_consent_given_at?: string;\n created_at: string;\n updated_at: string;\n\n // Optional SDK legacy compatibility aliases for existing component consumers\n total?: number;\n shippingAmount?: number;\n discountAmount?: number;\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?: string;\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 // Task: Plus Codes + Interactive Map Pin-Drop - Geolocation fields\n latitude?: number | null;\n longitude?: number | null;\n plus_code?: string | null;\n coordinate_source?: 'pin_drop' | 'plus_code' | 'manual' | null;\n}\n\n// ============================================================================\n// ORDER SERVICE PARAMS\n// ============================================================================\n\nexport interface FindOrderParams {\n email: string;\n order_id: string;\n}\n\n/**\n * Mirrors kasuvia-store-management's real PhysicalFulfillmentCreate schema\n * exactly (app/schemas/order.py) — the ONLY place these fields are actually\n * read from on OrderCreate. See CreateOrderParams's own doc comment for the\n * real bug this replaced (they used to be declared flat on CreateOrderParams\n * itself, which OrderBase's `extra: \"allow\"` config accepted with no\n * validation error, then silently discarded — order_in.physical stayed None\n * regardless of what was sent).\n */\nexport interface CreateOrderPhysicalParams {\n shipping_address?: DeliveryAddress;\n shipping_latitude?: number | null;\n shipping_longitude?: number | null;\n shipping_plus_code?: string | null;\n shipping_coordinate_source?: 'pin_drop' | 'plus_code' | 'manual' | null;\n /**\n * A quote_id from getShippingRates' per-rate \"quote_id\" field (carrier\n * shipments only). Required for any nonzero shipping fee — the backend\n * reads shipping_amount/terminal_rate_id/carrier_name from this stored\n * quote. self_pickup orders need one too (a real zero-fee quote, see\n * logisticsService.getShippingRates' self_pickup branch) — the backend\n * derives resolved_location_id from it, required for both shipping_method.\n */\n shipping_quote_id?: string;\n /** A ShippingQuoteGroup id when the cart needed splitting across multiple locations — mutually exclusive with shipping_quote_id. */\n shipping_plan_id?: string;\n /**\n * Client-repeated for documentation only — the backend derives the REAL\n * shipping method from the quote itself (resolved_terminal_rate_id is\n * None for a self_pickup quote), never trusts this field. Safe to omit.\n */\n shipping_method?: 'carrier' | 'self_pickup';\n}\n\n/** Mirrors kasuvia-store-management's real DigitalFulfillmentCreate schema exactly. */\nexport interface CreateOrderDigitalParams {\n /** ISO-3166-1 alpha-2 country code (e.g. \"NG\"). Required for digital orders — the backend's VAT lookup refuses to guess a tax jurisdiction. */\n buyer_country?: string;\n withdrawal_consent_given_at?: string;\n}\n\n/**\n * REAL BUG FIXED (2026-09-24), live-reported (\"digital checkout still does\n * not work\" / the [FlatRateVAT] error persisting even after buyer_country\n * was correctly collected in the UI): shipping_address, shipping_quote_id,\n * shipping_latitude/longitude/plus_code/coordinate_source, buyer_country,\n * withdrawal_consent_given_at, and shipping_rate_id used to be declared\n * FLAT on this interface. kasuvia-store-management's real OrderCreate\n * schema never had flat equivalents of any of these — confirmed against\n * app/schemas/order.py directly - they only ever existed nested under\n * `physical`/`digital` (see CreateOrderPhysicalParams/\n * CreateOrderDigitalParams above). OrderBase's `extra: \"allow\"` config\n * meant sending them flat produced no validation error at all - Pydantic\n * silently accepted and discarded them, so order_in.physical/order_in.digital\n * stayed None regardless of what the checkout form collected. Every real\n * physical order's shipping_address/quote and every real digital order's\n * buyer_country has been silently lost this way. shipping_rate_id and\n * pickup_location_id (also previously flat) never existed on the backend\n * schema in ANY shape - both removed outright as confirmed-dead.\n */\nexport interface CreateOrderParams {\n customer_id?: string | null;\n status?: string;\n checkout_session_id?: string;\n physical?: CreateOrderPhysicalParams;\n digital?: CreateOrderDigitalParams;\n /**\n * Line items for the order.\n *\n * @important DASHBOARD-ONLY — For the merchant dashboard path (POST /sales/orders),\n * these items are used directly. For storefront checkout (POST /orders/storefront),\n * the backend IGNORES this field entirely and reads items from the customer's\n * server-side Redis cart instead. Do NOT rely on this field for storefront orders.\n */\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 subtotal_amount?: number;\n /** @deprecated Ignored by the backend when discount_code is set (recomputed server-side from the real Discount row); rejected outright if sent without a code. */\n discount_amount?: number;\n discount_code?: string;\n promo_code?: string;\n /** @deprecated Ignored by the backend — tax is always recomputed server-side from the DB VAT rate for the buyer's country. */\n tax_amount?: number;\n /** @deprecated Ignored by the backend for carrier shipments once physical.shipping_quote_id is set; rejected outright if sent nonzero without one. */\n shipping_amount?: number;\n payment_method?: string;\n guest_token?: string;\n guest_email?: string;\n guest_phone?: string;\n guest_name?: string;\n product_type?: ProductType;\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 * @file types/payments/index.ts\n * @description All customer-facing payment types for the Kasuvia Payment System.\n *\n * Auth model:\n * - X-Storefront-Key → identifies the business storefront\n * - X-Business-ID → tenant context\n * No business-owner JWT used here — these are CUSTOMER-facing types.\n *\n * Payment flow:\n * Customer → Business Owner : Monnify (NGN) | Flutterwave (non-NGN)\n * Business Owner → Kasuvia : Subscription (separate, JWT-auth)\n * Kasuvia → Business Owner : Payout (separate, JWT-auth)\n */\n\n// ── Configuration Types ─────────────────────────────────────────────────────────\n\nexport interface Currency {\n code: string; // ISO 4217 currency code (e.g., USD, NGN, EUR)\n name: string; // Full currency name (e.g., US Dollar, Nigerian Naira)\n symbol: string; // Currency symbol (e.g., $, ₦, €)\n decimals: number; // Number of decimal places (e.g., 2 for USD, 0 for JPY)\n is_active: boolean; // Whether this currency is active\n}\n\nexport interface SupportedCurrenciesResponse {\n currencies: Currency[];\n}\n\nexport interface BackendLanguage {\n code: string; // Language code (e.g., en, ar, fr)\n label: string; // Language label (e.g., English, Arabic, French)\n flag: string; // Flag emoji or icon\n}\n\nexport interface SupportedLang {\n code: string; // Google Translate code\n appCode: string; // Internal app code\n label: string;\n native: string;\n flag: string;\n}\n\nexport interface SupportedLanguagesResponse {\n languages: BackendLanguage[];\n}\n\nexport enum PaymentGatewayEnum {\n MONNIFY = \"monnify\",\n FLUTTERWAVE = \"flutterwave\",\n PAYSTACK = \"paystack\",\n}\n\nexport type PaymentGateway = PaymentGatewayEnum | \"monnify\" | \"flutterwave\" | \"paystack\";\n\nexport enum PaymentMethodTypeEnum {\n CARD = \"card\",\n TRANSFER = \"transfer\",\n BANK_TRANSFER = \"bank_transfer\",\n ACCOUNT = \"account\",\n USSD = \"ussd\",\n}\n\nexport type PaymentMethodType = PaymentMethodTypeEnum | \"card\" | \"transfer\" | \"bank_transfer\" | \"account\" | \"ussd\";\n\nexport interface PaymentMethodOption {\n method: PaymentMethodType | string;\n display_name: string;\n description: string;\n}\n\nexport interface GatewayMethods {\n gateway: PaymentGateway | string;\n display_name: string;\n methods: PaymentMethodOption[];\n}\n\n// ── Wallet Types ───────────────────────────────────────────────────────────────\n\nexport interface WalletBalanceResponse {\n balance: number;\n currency: string;\n}\n\nexport interface WalletLedgerEntry {\n id: string;\n entry_type: string;\n amount: number;\n currency: string;\n refund_id?: string | null;\n transaction_id?: string | null;\n balance_after: number;\n created_at: string;\n}\n\nexport interface WalletLedgerResponse {\n items: WalletLedgerEntry[];\n total: number;\n page: number;\n page_size: number;\n}\n\nexport interface ClaimWalletCreditRequest {\n claim_token: string;\n}\n\nexport interface OutstandingClaimResponse {\n wallet_id: string;\n claim_email: string;\n balance: number;\n currency: string;\n created_at: string;\n}\n\n// ── Request Types ─────────────────────────────────────────────────────────────\n\nexport interface DVACreateRequest {\n order_id?: string;\n /** Ignored by the backend — the real order total is always charged instead. Only meaningful (and required) if order_id is omitted. */\n amount?: number;\n customer_email: string;\n customer_name?: string;\n /** Defaults to NGN — DVA is Monnify-only */\n currency?: string;\n /** Gateway identifier — the backend requires this explicitly, no default */\n gateway: string;\n /** Window origin of the storefront */\n storefront_origin?: string;\n /** Idempotency key to prevent duplicate DVA creation */\n idempotency_key?: string;\n}\n\nexport interface PaymentInitiateRequest {\n /** Ignored by the backend when order_id is set — the real order total is always charged instead. Required only if order_id is omitted. */\n amount?: number;\n currency?: string;\n customer_email: string;\n customer_name?: string;\n order_id?: string;\n quote_id?: string;\n /** ISO 2-letter country code (defaults to 'NG') */\n country_code?: string;\n /** Gateway chosen by customer (e.g., 'monnify', 'flutterwave', 'paystack') — the backend requires this explicitly, no default */\n gateway: string;\n /** Window origin of the storefront — used as gateway redirect base URL */\n storefront_origin?: string;\n metadata?: Record<string, string | number | boolean>;\n /** Idempotency key to prevent duplicate payment initiation */\n idempotency_key?: string;\n}\n\n// ── Response Types ─────────────────────────────────────────────────────────────\n\nexport interface DVADetails {\n account_number: string;\n bank_name: string;\n account_name: string;\n reference: string;\n amount: number;\n transaction_id: string;\n expires_at: string;\n}\n\nexport interface PaymentInitiateResponse {\n id: string;\n gateway_ref: string;\n gateway: string;\n status: string;\n /** Normalised top-level checkout URL for gateway redirect */\n checkout_url: string;\n}\n\nexport interface TransactionVerifyResponse {\n id: string;\n status: string;\n amount: number;\n currency: string;\n gateway_ref: string;\n gateway?: string;\n order_id?: string;\n escrow_status?: string;\n escrow_release_date?: string;\n metadata_json?: Record<string, unknown>;\n}\n","/**\n * Review and Comment types for CRM service\n */\n\nexport enum ModerationStatus {\n PENDING = 'pending',\n APPROVED = 'approved',\n REJECTED = 'rejected'\n}\n\nexport interface Review {\n id: string\n business_id: string\n product_id: string\n order_id?: string\n customer_id: string\n /** Real field (kasuvia-crm-go's ReviewResponse.customer_name_masked) — the raw customer_id is never exposed to other storefront visitors. */\n customer_name_masked: string\n rating: number\n body: string\n media: string[]\n media_ids: string[]\n verified_purchase: boolean\n moderation_status: ModerationStatus\n merchant_reply?: string\n merchant_reply_at?: string\n created_at: string\n edited_at?: string\n edit_count: number\n}\n\nexport interface Comment {\n id: string\n business_id: string\n product_id: string\n customer_id?: string\n /** Real field (kasuvia-crm-go's CommentResponse.customer_name_masked). */\n customer_name_masked: string\n body: string\n parent_comment_id?: string\n moderation_status: ModerationStatus\n is_merchant_reply: boolean\n created_at: string\n updated_at: string\n}\n\nexport interface ReviewCreate {\n product_id: string\n /** Required: reviews are purchase-verified — must reference a completed order for this product. */\n order_id: string\n rating: number\n body: string\n /**\n * `media` (asset URLs) and `media_ids` (the matching MediaAsset ids) must\n * be two parallel, order-paired arrays of the SAME length — the real\n * backend (kasuvia-crm-go's validateMediaPairing) 400s otherwise. Omit\n * both together, or populate both together in the same order.\n */\n media?: string[]\n media_ids?: string[]\n}\n\nexport interface ReviewUpdate {\n rating?: number\n body?: string\n /** See ReviewCreate's identical doc comment — media/media_ids must be order-paired, same length. */\n media?: string[]\n media_ids?: string[]\n}\n\nexport interface CommentCreate {\n product_id: string\n body: string\n parent_comment_id?: string\n}\n\nexport interface CommentUpdate {\n body?: string\n}\n\nexport interface MerchantReplyCreate {\n body: string\n}\n\nexport interface ReviewModerationAction {\n status: ModerationStatus\n reason?: string\n}\n\nexport interface CommentModerationAction {\n status: ModerationStatus\n reason?: string\n}\n\n// REAL BUG FIXED (2026-09-21): these used `reviews`/`comments`/`total` —\n// kasuvia-crm-go's real GET /products/{id}/reviews and .../comments\n// (reviews.go) return the platform's standard pagination shape instead\n// (`results`/`count`/`page`/`page_size`/`total_pages`), same convention as\n// every other paginated Kasuvia endpoint.\nexport interface ProductReviewsResponse {\n results: Review[]\n count: number\n page: number\n page_size: number\n total_pages: number\n average_rating: number | null\n rating_distribution: Record<number, number>\n}\n\nexport interface ProductCommentsResponse {\n results: Comment[]\n count: number\n page: number\n page_size: number\n total_pages: number\n}","/**\n * Silent-refresh registry for apiRequest's automatic 401 retry.\n *\n * REAL GAP FIXED (2026-09-28), live-reported (\"authentication in\n * kasuvia-storefront is terrible, sometimes it gets cut off while using\n * the app\"): AuthProvider only ever called /api/auth/refresh once, in a\n * useEffect on mount (restoreSession()) — every one of apiRequest's ~100+\n * real call sites had zero awareness of token expiry at all. The moment a\n * customer's access token expired mid-session (JWT_ACCESS_TOKEN_LIFETIME_\n * MINUTES defaults to 30 on kasuvia-auth — see common/utils/tokens.py),\n * every subsequent authenticated call 401'd and stayed broken for the rest\n * of that browser tab, with no recovery short of a full page reload\n * (which re-runs restoreSession() exactly once more, then the cycle\n * repeats). This is a fundamentally different failure mode than \"signed\n * out on refresh\" (investigated exhaustively earlier this session and\n * found structurally sound) - it only shows up while actively using the\n * app between page loads, matching the user's own description exactly.\n *\n * Compared directly against kasuvia/ (the merchant dashboard)'s own proven\n * architecture (lib/api/interceptors.ts's withAuthInterceptors): every\n * axios instance there has a response interceptor that, on any 401 from a\n * non-refresh endpoint, transparently calls the refresh endpoint once\n * (coalescing concurrent 401s into a single in-flight refresh via a\n * pending-request queue - never a stampede of parallel refresh calls),\n * updates the in-memory access token, and retries the original request\n * with the new token - completely invisible to the calling code and the\n * user. kasuvia/ can do this because its access token lives in a plain,\n * synchronously-readable/writable module-level variable\n * (lib/api/auth/axios.ts's tokenStore), not React state - exactly what\n * makes an imperative, outside-the-render-cycle interceptor possible.\n *\n * This module ports that same pattern into kasuvia-sdk's fetch-based\n * apiRequest, which every one of the storefront's ~100+ authenticated SDK\n * calls already funnels through - fixing it once here reaches every call\n * site with zero changes to any of them. A consumer (AuthProvider) calls\n * registerRefreshHandler() once with a function that knows how to obtain a\n * fresh token (POST /api/auth/refresh, in the storefront's case) and keeps\n * its own React state in sync; apiRequest below calls it automatically\n * whenever a request carrying an Authorization header gets a real 401,\n * with the same in-flight-coalescing guarantee kasuvia/'s interceptor has.\n * If no handler is registered (e.g. a server-side call, or a consumer that\n * never opts in), behavior is completely unchanged - a 401 throws\n * immediately, exactly as before this module existed.\n *\n * REAL BUG FOUND AND FIXED while live-verifying this exact mechanism\n * (2026-09-28): kasuvia-sdk's tsup config builds each package entry point\n * (`.` / `./services` / `./hooks` / `./components`) as a fully independent\n * bundle with no shared chunk - confirmed by grepping the built output,\n * every one of the 3 real dist files contains its OWN separate copy of this\n * file's code. A plain module-level `let refreshHandler` therefore gave\n * each entry point its own invisible-to-each-other copy of this state:\n * registering via `@kasuvia/sdk` (the root entry, what AuthProvider\n * imports from) silently did nothing for any authenticated call made\n * through `@kasuvia/sdk/hooks` (a different physical bundle, and the one\n * real hooks like useWalletBalance/useCart actually route through) - the\n * exact majority-of-real-traffic case this whole fix exists for. Storing\n * the registry on `globalThis` under a fixed key instead makes it a true\n * process/tab-wide singleton no matter how many separate bundle copies of\n * this module end up loaded side by side in the same browser tab - the\n * standard fix for this exact \"multiple bundled copies of one logical\n * module\" bug class, without needing to change the package's build/\n * splitting setup (out of scope for an auth fix, wider blast radius).\n */\n\nexport type RefreshHandler = () => Promise<string | null>\n\ninterface RefreshRegistry {\n handler: RefreshHandler | null\n inFlight: Promise<string | null> | null\n}\n\nconst GLOBAL_KEY = '__kasuviaSdkTokenRefreshRegistry__'\n\nfunction getRegistry(): RefreshRegistry {\n const g = globalThis as unknown as Record<string, RefreshRegistry | undefined>\n if (!g[GLOBAL_KEY]) {\n g[GLOBAL_KEY] = { handler: null, inFlight: null }\n }\n return g[GLOBAL_KEY]!\n}\n\n/**\n * Registers the function apiRequest calls to obtain a fresh access token\n * after a 401. Call this once, e.g. in AuthProvider's top-level mount\n * effect - not tied to login state, since the handler itself is stateless\n * (it always attempts a real refresh call and returns null on failure,\n * which is exactly correct behavior whether or not a customer happens to be\n * logged in right now). `null` is accepted for a consumer that genuinely\n * unmounts its provider (e.g. route-level teardown) and wants to stop\n * apiRequest from calling a handler whose closure is about to go stale.\n */\nexport function registerRefreshHandler(handler: RefreshHandler | null): void {\n getRegistry().handler = handler\n}\n\n/**\n * Runs the registered refresh handler, coalescing concurrent callers into\n * the single in-flight attempt (mirrors withAuthInterceptors' `_isRefreshing`\n * / `_pendingQueue` exactly - several requests failing with a 401 at once\n * must never each independently call the refresh endpoint).\n */\nexport async function refreshAccessToken(): Promise<string | null> {\n const registry = getRegistry()\n if (!registry.handler) return null\n if (registry.inFlight) return registry.inFlight\n\n registry.inFlight = registry.handler().finally(() => {\n registry.inFlight = null\n })\n return registry.inFlight\n}\n\nexport function hasRefreshHandler(): boolean {\n return getRegistry().handler !== null\n}\n","import type { SdkConfig } from '../config'\nimport { refreshAccessToken, hasRefreshHandler } from './token-refresh'\n\n/**\n * Thrown by apiRequest on any non-2xx response. Carries the real HTTP status\n * and parsed body so a caller that needs to branch on status (e.g. a 409\n * \"confirmation required\" two-step flow) can catch this instead of the\n * generic client special-casing every such flow.\n */\nexport class ApiError extends Error {\n status: number\n body: unknown\n constructor(message: string, status: number, body: unknown) {\n super(message)\n this.name = 'ApiError'\n this.status = status\n this.body = body\n }\n}\n\n/**\n * Extract the real, specific error message from a Kasuvia backend's error\n * body, whichever of the two real shapes this platform's services return:\n *\n * - FastAPI/Pydantic (store-management, cart-management, cms, crm-go,\n * notification-go, payment-go): `{\"detail\": \"plain string\"}` for a\n * manually-raised HTTPException, or `{\"detail\": [{\"loc\": [...], \"msg\":\n * \"...\", \"type\": \"...\"}]}` for an automatic Pydantic validation failure.\n * - Django REST Framework (kasuvia-auth): `{\"detail\": \"plain string\"}` for\n * AuthenticationFailed/NotFound/PermissionDenied-style exceptions, or a\n * bare validation-error dict with no top-level `detail` at all -\n * `{\"non_field_errors\": [...]}` or `{\"email\": [...]}\"` - when a\n * serializer's own `is_valid(raise_exception=True)` fires.\n *\n * Previously two separately-named, independently-adopted copies of this\n * logic existed (`extractHttpErrorDetail`, `extractAuthErrorMessage`) - only\n * 7 of 18 SDK service files used either one at all. Merged into one function\n * every call site now goes through via apiRequest, so error quality no\n * longer depends on which service function happens to have remembered to\n * check for it.\n */\nexport function extractApiErrorMessage(body: unknown, fallback: string): string {\n if (typeof body !== 'object' || body === null) return fallback\n const record = body as Record<string, unknown>\n\n if (typeof record.detail === 'string') return record.detail\n\n if (Array.isArray(record.detail) && record.detail.length > 0) {\n const first = record.detail[0] as Record<string, unknown> | undefined\n if (first && typeof first.msg === 'string') {\n const loc = first.loc\n const field = Array.isArray(loc) ? loc[loc.length - 1] : undefined\n return typeof field === 'string' || typeof field === 'number' ? `${field}: ${first.msg}` : first.msg\n }\n }\n\n const firstStringOrArrayItem = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value\n if (Array.isArray(value) && typeof value[0] === 'string') return value[0]\n return undefined\n }\n\n const nonFieldMessage = firstStringOrArrayItem(record.non_field_errors)\n if (nonFieldMessage) return nonFieldMessage\n\n for (const [key, value] of Object.entries(record)) {\n if (key === 'detail' || key === 'non_field_errors') continue\n const message = firstStringOrArrayItem(value)\n if (message) return message\n }\n\n return fallback\n}\n\n/** `{'X-Storefront-Key': ..., 'X-Business-ID': ...}` - every storefront-scoped call. */\nexport function storefrontHeaders(config: SdkConfig): Record<string, string> {\n return {\n 'X-Storefront-Key': config.storefrontApiKey,\n 'X-Business-ID': config.businessId,\n }\n}\n\n/** storefrontHeaders plus `Authorization: Bearer <token>` - every authenticated customer call. */\nexport function authHeaders(config: SdkConfig, accessToken: string): Record<string, string> {\n return {\n ...storefrontHeaders(config),\n Authorization: `Bearer ${accessToken}`,\n }\n}\n\nexport const JSON_HEADERS: Record<string, string> = { 'Content-Type': 'application/json' }\n\nexport interface ApiRequestOptions extends RequestInit {\n /** Used when the response is a non-2xx status whose body carries nothing usable. */\n fallbackErrorMessage?: string\n}\n\n/**\n * The one real HTTP call path every REST SDK service function should use.\n * Replaces each function independently doing fetch + response.ok check +\n * error-body parsing (100 call sites across 18 files, only 7 of which\n * consistently surfaced the real backend error before this existed).\n *\n * A 204/empty body resolves to `undefined` rather than throwing on the\n * `response.json()` call - real for logout and a few other no-content\n * responses on this platform.\n *\n * Silent-refresh-and-retry on 401 (see token-refresh.ts's own doc comment\n * for the full real-world bug this fixes and the kasuvia/ pattern it\n * ports): only triggers for a request that actually carried an\n * `Authorization: Bearer` header AND has a refresh handler registered -\n * a storefront-key-only public call's 401 means something else entirely\n * (wrong key/business) and must never trigger a token refresh attempt.\n * Retries at most once per call, mirroring withAuthInterceptors' own\n * `_retry` guard - a fresh token that still 401s is a genuine, final\n * failure, not something to loop on.\n */\nexport async function apiRequest<T>(url: string, options: ApiRequestOptions = {}): Promise<T> {\n const { fallbackErrorMessage = 'Request failed', ...init } = options\n const headers = new Headers(init.headers)\n const hadBearerToken = headers.get('Authorization')?.startsWith('Bearer ') ?? false\n\n const response = await fetch(url, { ...init, headers })\n\n if (response.status === 401 && hadBearerToken && hasRefreshHandler()) {\n const freshToken = await refreshAccessToken()\n if (freshToken) {\n const retryHeaders = new Headers(headers)\n retryHeaders.set('Authorization', `Bearer ${freshToken}`)\n const retryResponse = await fetch(url, { ...init, headers: retryHeaders })\n if (retryResponse.ok) {\n const retryText = await retryResponse.text()\n return (retryText ? JSON.parse(retryText) : undefined) as T\n }\n const retryBody = await retryResponse.json().catch(() => ({}))\n throw new ApiError(extractApiErrorMessage(retryBody, fallbackErrorMessage), retryResponse.status, retryBody)\n }\n }\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}))\n throw new ApiError(extractApiErrorMessage(body, fallbackErrorMessage), response.status, body)\n }\n\n const text = await response.text()\n return (text ? JSON.parse(text) : undefined) as T\n}\n","/**\n * Cart Service\n *\n * Handles cart operations for both guest and authenticated users via\n * kasuvia-cart-management (Go/Huma). All cart operations target the\n * cart-management service, which is the single source of truth for cart state.\n *\n * KEY CONSTRAINT — backend-resolved fields:\n * kasuvia-cart-management resolves product_name, product_slug, image_url,\n * variant_attributes, unit_price, is_bespoke, and product_type entirely\n * server-side from kasuvia-store-management at add/merge time. These MUST NOT\n * be sent in request payloads — only product_id, variant_id, quantity, and\n * custom_measurements are accepted by the backend.\n *\n * Stateless — all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport { ProductTypeEnum, type CartItem, type CartResponse, type ProductType } from '../types/store'\nimport { apiRequest, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\n// REAL BUG FIXED (2026-09-21): every fetch() in this file targeted\n// `config.backendUrls.store` (kasuvia-store-management) even though this\n// file's own header comment already documented that cart moved to\n// kasuvia-cart-management (a separate Go/Huma service, strangler-fig\n// migration). kasuvia-store-management's own router.py explicitly says\n// \"Cart is NOT registered here anymore\" — every one of these calls 404s\n// against `store`. Fixed by routing through `backendUrls.cart` instead,\n// which callers must now provide (kasuvia-cart-management, same\n// `/api/v1/cart/...` route shape it was ported from — only the base URL\n// changes).\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\nfunction guestHeaders(config: SdkConfig, guestSessionId: string, extra?: Record<string, string>): Record<string, string> {\n return { ...extra, ...storefrontHeaders(config), 'X-Guest-Session': guestSessionId }\n}\n\n/**\n * Fetch guest cart from backend (Redis-backed).\n */\nexport async function getGuestCart(config: SdkConfig, guestSessionId: string): Promise<CartResponse> {\n if (!guestSessionId) throw new Error('Guest session ID is required to fetch guest cart');\n\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/`, {\n headers: guestHeaders(config, guestSessionId),\n fallbackErrorMessage: 'Failed to fetch guest cart',\n })\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Add item to guest cart (Redis-backed).\n * Only product_id, variant_id, quantity, and custom_measurements are sent —\n * all other fields are resolved server-side by kasuvia-cart-management.\n */\nexport async function addToGuestCart(\n config: SdkConfig,\n guestSessionId: string,\n item: {\n product_id: string\n variant_id?: string | null\n quantity: number\n custom_measurements?: string | null\n }\n): Promise<CartResponse> {\n if (!guestSessionId) throw new Error('Guest session ID is required to add to guest cart');\n\n const payload = {\n product_id: item.product_id,\n variant_id: item.variant_id ?? undefined,\n quantity: item.quantity,\n custom_measurements: item.custom_measurements ?? undefined,\n }\n\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/`, {\n method: 'POST',\n headers: guestHeaders(config, guestSessionId, JSON_HEADERS),\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to add to guest cart',\n })\n return { ...data, items: 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<CartResponse> {\n if (!guestSessionId) throw new Error('Guest session ID is required to update guest cart item');\n\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/${itemId}`, {\n method: 'PATCH',\n headers: guestHeaders(config, guestSessionId, JSON_HEADERS),\n body: JSON.stringify({ quantity }),\n fallbackErrorMessage: 'Failed to update guest cart item',\n })\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Remove an item from the guest cart.\n *\n * REAL BUG FIXED (2026-09-22), live-reproduced: this used to type its\n * result as `CartResponse` and read `data.items` off it, but the real\n * backend's `DELETE /cart/{item_id}` returns `204 No Content` with a\n * genuinely empty body (confirmed live: `HTTP_STATUS:204 BODY_LENGTH:0`) -\n * `apiRequest` resolves an empty body to `undefined`, so `data.items`\n * threw `TypeError: Cannot read properties of undefined (reading 'items')`\n * on every real delete. The item really was removed server-side (the\n * DELETE request itself succeeded), but the thrown error sent\n * `removeFromCartMutation` down `onError` instead of `onSuccess`, so\n * `queryClient.invalidateQueries` never ran - a customer's cart kept\n * showing the \"removed\" item until something else (a full page reload)\n * happened to trigger a fresh, uncached fetch. Matches `clearGuestCart`'s\n * existing `Promise<void>` shape, which was already correct for this same\n * \"backend returns no body\" pattern.\n */\nexport async function removeFromGuestCart(\n config: SdkConfig,\n guestSessionId: string,\n itemId: string\n): Promise<void> {\n if (!guestSessionId) throw new Error('Guest session ID is required to remove from guest cart');\n\n await apiRequest(`${config.backendUrls.cart}/cart/${itemId}`, {\n method: 'DELETE',\n headers: guestHeaders(config, guestSessionId),\n fallbackErrorMessage: 'Failed to remove item from guest cart',\n })\n}\n\n/**\n * Clear the entire guest cart.\n */\nexport async function clearGuestCart(config: SdkConfig, guestSessionId: string): Promise<void> {\n if (!guestSessionId) throw new Error('Guest session ID is required to clear guest cart');\n\n await apiRequest(`${config.backendUrls.cart}/cart/clear`, {\n method: 'DELETE',\n headers: guestHeaders(config, guestSessionId),\n fallbackErrorMessage: 'Failed to clear guest cart',\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 throw new Error('Access token is required to fetch authenticated cart');\n }\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch cart',\n })\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Add item to authenticated user's cart.\n * Only product_id, variant_id, quantity, and custom_measurements are sent —\n * all other fields are resolved server-side by kasuvia-cart-management.\n */\nexport async function addToCart(\n config: SdkConfig,\n accessToken: string,\n item: {\n product_id: string\n variant_id?: string | null\n quantity: number\n custom_measurements?: string | null\n // These fields are accepted from the caller for UI convenience but are\n // NOT forwarded to the backend — kasuvia-cart-management resolves them\n // server-side. Declared here so callers don't need to strip them.\n product_slug?: string\n product_name?: string\n image_url?: string\n variant_attributes?: string\n unit_price?: number\n is_bespoke?: boolean\n }\n): Promise<CartResponse> {\n // Only send the fields the backend accepts — strip everything else.\n const payload = {\n product_id: item.product_id,\n variant_id: item.variant_id ?? undefined,\n quantity: item.quantity,\n custom_measurements: item.custom_measurements ?? undefined,\n }\n\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to add to cart',\n })\n return { ...data, items: parseItems(data.items || []) }\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 data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/${itemId}`, {\n method: 'PATCH',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({ quantity }),\n fallbackErrorMessage: 'Failed to update cart item',\n })\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Remove item from authenticated user's cart.\n * Same real bug/fix as removeFromGuestCart above - see its doc comment.\n */\nexport async function removeFromCart(\n config: SdkConfig,\n accessToken: string,\n itemId: string\n): Promise<void> {\n await apiRequest(`${config.backendUrls.cart}/cart/${itemId}`, {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to remove cart item',\n })\n}\n\n/**\n * Clear authenticated user's cart.\n */\nexport async function clearCart(config: SdkConfig, accessToken: string): Promise<void> {\n await apiRequest(`${config.backendUrls.cart}/cart/clear`, {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to clear cart',\n })\n}\n\n/**\n * Merge guest cart items into the authenticated customer's cart.\n *\n * The backend (POST /api/v1/cart/merge) accepts only:\n * { items: [{ product_id, variant_id?, quantity, custom_measurements? }] }\n * Product name, image, price, type are all re-resolved server-side.\n *\n * Sends X-Guest-Session so the backend can atomically delete the guest\n * cart (best-effort) after merging.\n */\nexport async function mergeGuestCart(\n config: SdkConfig,\n accessToken: string,\n guestSessionId: string,\n guestItems: Pick<CartItem, 'product_id' | 'variant_id' | 'quantity' | 'custom_measurements'>[]\n): Promise<CartResponse> {\n const payloadItems = guestItems.map((item) => ({\n product_id: item.product_id,\n variant_id: item.variant_id ?? undefined,\n quantity: item.quantity,\n custom_measurements: item.custom_measurements ?? undefined,\n }))\n\n const headers: Record<string, string> = { ...JSON_HEADERS, ...authHeaders(config, accessToken) }\n if (guestSessionId) {\n headers[\"X-Guest-Session\"] = guestSessionId\n }\n\n const data = await apiRequest<CartResponse>(`${config.backendUrls.cart}/cart/merge`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ items: payloadItems }),\n fallbackErrorMessage: 'Failed to merge guest cart',\n })\n return { ...data, items: parseItems(data.items || []) }\n}\n\n/**\n * Convenience wrapper: fetch guest cart and merge 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 const guestCart = await getGuestCart(config, guestSessionId)\n if (!guestCart.items.length) return\n await mergeGuestCart(config, accessToken, guestSessionId, guestCart.items)\n}\n\n/**\n * Helper to get a guest cart's product type (for type-mismatch checks before adding an item).\n */\nexport function getGuestCartProductType(items?: CartItem[]): ProductType | null {\n if (!items || !items.length) return null;\n const types = new Set(items.map(i => i.product_type).filter(Boolean));\n if (types.size === 0) return null;\n if (types.size === 1) return ([...types][0] as ProductType) ?? null;\n return ProductTypeEnum.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 { components } from '../generated/store-openapi'\nimport { apiRequest, ApiError, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\n// ─── Generated types (openapi/README.md — regenerate via `pnpm run codegen:rest`) ─\n// REAL BUG FOUND (2026-09-23) via this exact codegen initiative: the real\n// OrderResponse schema (kasuvia-store-management's app/schemas/order.py)\n// carries NO tracking_number/delivery_status/carrier_name/carrier_slug/\n// terminal_rate_id/terminal_shipment_id/shipping_address/shipping_surcharge_*/\n// declared_weight_kg/actual_weight_kg/pickup_verification_*/pickup_qr_payload\n// fields at its top level at all - confirmed by reading OrderBase/\n// OrderResponse's actual field lists directly, not just the generated\n// output. Every one of these genuinely lives nested under\n// `physical_fulfillment` (see PhysicalFulfillmentResponse below) - \"One\n// nested block per product type, instead of ~35 flat fields on OrderBase\"\n// per that file's own Order Schema Refactor comment. RawOrder/\n// normaliseStorefrontOrder below used to read every one of these as a flat\n// top-level field, so they were silently undefined on every real order -\n// a customer's tracking number, carrier, delivery status, and shipping\n// address never actually rendered anywhere on the storefront. Fixed to\n// read from the real nested location, same pattern already correctly\n// applied to bespoke_fulfillment (see deriveCustomerName/\n// normaliseStorefrontOrder's existing bespoke_fulfillment-first reads).\ntype OrderResponseSchema = components['schemas']['OrderResponse']\ntype PhysicalFulfillmentSchema = components['schemas']['PhysicalFulfillmentResponse']\ntype DigitalFulfillmentSchema = components['schemas']['DigitalFulfillmentResponse']\n\nexport type { FindOrderParams, CreateOrderParams, OrderStatus }\n\n/**\n * Request body for the real POST /orders/storefront/bespoke atomic checkout\n * (kasuvia-store-management's BespokeBookingCheckoutRequest). Bespoke\n * products can never be added to a cart (ErrBespokeNotCartable) — this is\n * the only real path to a paid bespoke commission from the storefront.\n */\nexport interface CreateBespokeOrderParams {\n product_id: string\n brief: string\n reference_images?: string[]\n measurements?: Record<string, string>\n preferred_timeline?: string\n special_instructions?: string\n deposit_ratio?: number\n physical?: {\n shipping_address: Record<string, unknown>\n }\n notes?: string\n discount_code?: string\n guest_email?: string\n guest_name?: string\n guest_phone?: string\n checkout_session_id?: string\n}\n\n/**\n * Request body for the real POST /orders/storefront/service atomic PAID\n * checkout (kasuvia-store-management's ServiceBookingCheckoutRequest) —\n * distinct from the free self-service `bookAppointment` flow\n * (service-booking.service.ts, POST /service/bookings/schedule). Service\n * products can never be added to a cart (ErrServiceNotCartable) — this is\n * the only path to a PAID service booking from the storefront.\n */\nexport interface CreateServiceBookingOrderParams {\n product_id: string\n scheduled_date: string\n scheduled_time: string\n staff_id?: string\n notes?: string\n discount_code?: string\n guest_email?: string\n guest_name?: string\n guest_phone?: string\n checkout_session_id?: string\n}\n\ntype RawOrderItem = NonNullable<OrderResponseSchema['items']>[number]\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\n/**\n * The real backend response, typed from the generated schema (see the\n * codegen comment above `OrderResponseSchema`). `status` is narrowed from\n * the schema's bare `string` (OrderResponse.status has no Literal/Enum on\n * the backend either — it's genuinely just `str` there) to the SDK's own\n * real OrderStatus union.\n *\n * `cancellation_reason` and `bespoke_stage` are NOT part of this type\n * (confirmed absent from OrderResponse/PhysicalFulfillmentResponse/\n * BespokeFulfillmentResponse's real field lists) — see\n * normaliseStorefrontOrder's own comments on both for what actually backs\n * (or doesn't back) the public Order type's equivalent fields.\n */\n// NOTE: deliberately NOT `Omit<OrderResponseSchema, 'status'> & {...}` -\n// OrderResponseSchema is intersected with a string-index signature\n// (`& {[key: string]: unknown}`, from the backend's `extra: \"allow\"`\n// model_config), and `Omit`'s `Pick<T, Exclude<keyof T, K>>` definition\n// makes `keyof` collapse to just `string` on a type with a string index\n// signature, silently losing every specific field (every property access\n// on the \"Omit\" result then wrongly resolves to `{}`). A plain\n// intersection avoids `keyof` entirely and works correctly instead.\ntype RawOrder = OrderResponseSchema & { status: OrderStatus }\n\n/** The real, non-null shipping_address shape (PhysicalFulfillmentResponse's\n * own field types as a schemaless `Dict[str, Any]` on the backend, so\n * openapi-typescript can't infer it beyond \"some object\" — this is the same\n * defensive cast the code already did before this fix, just now sourced\n * from the real nested location). */\nfunction extractShippingAddress(raw: RawOrder): RawShippingAddress | null {\n const val = raw.physical_fulfillment?.shipping_address\n return typeof val === 'object' && val !== null ? val as unknown as RawShippingAddress : null\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 = extractShippingAddress(raw)\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 order_id: item.order_id,\n product_id: item.product_id ?? undefined,\n variant_id: item.variant_id ?? undefined,\n product_name: item.product_name ?? '',\n quantity: item.quantity,\n unit_price: item.unit_price,\n variant_details: item.variant_details as Record<string, unknown> | undefined,\n custom_measurements: item.custom_measurements as Record<string, unknown> | undefined,\n image_url: item.image_url ?? undefined,\n }))\n\n const addr = extractShippingAddress(raw)\n\n const customerName = deriveCustomerName(raw)\n const customerEmail = raw.guest_email ?? raw.customer_email ?? ''\n const physical = raw.physical_fulfillment\n\n // No silent fallback: an order's currency determines what a subsequent\n // payment actually gets charged in. A missing value here means the backend\n // response is malformed — defaulting to a guessed currency would make the\n // failure invisible until money changes hands in the wrong currency\n // (see plan: Order Currency Fix).\n if (!raw.currency) {\n throw new Error(`Order ${raw.id} response is missing a currency field.`)\n }\n // REAL BUG FIXED (2026-09-22): same class of bug as the currency check\n // above, previously missed. `created_at`/`updated_at` silently fell back\n // to `new Date().toISOString()` (right now) when absent — fabricating a\n // plausible but wrong \"placed on\" date instead of surfacing a malformed\n // response. `business_id` silently fell back to `''`.\n if (!raw.created_at) {\n throw new Error(`Order ${raw.id} response is missing a created_at field.`)\n }\n if (!raw.updated_at) {\n throw new Error(`Order ${raw.id} response is missing an updated_at field.`)\n }\n if (!raw.business_id) {\n throw new Error(`Order ${raw.id} response is missing a business_id field.`)\n }\n\n return {\n id: raw.id,\n display_id: raw.display_id || raw.id,\n business_id: raw.business_id,\n customer_id: raw.customer_id ?? undefined,\n items,\n status: raw.status,\n payment_status: raw.payment_status || 'pending',\n product_type: (raw.product_type ?? undefined) as Order['product_type'],\n\n // Canonical backend fields\n total_amount: raw.total_amount,\n currency: raw.currency,\n subtotal_amount: raw.subtotal_amount ?? undefined,\n shipping_amount: raw.shipping_amount ?? undefined,\n discount_amount: raw.discount_amount ?? undefined,\n tax_amount: raw.tax_amount ?? undefined,\n customer_name: customerName,\n customer_email: customerEmail,\n // REAL BUG FIXED (2026-09-23) via the REST codegen initiative: every\n // field below this point used to read a flat `raw.<field>` that does\n // NOT exist anywhere on the real OrderResponse - confirmed by reading\n // the actual Pydantic classes, not just the generated types. They\n // genuinely live nested under `physical_fulfillment` (shipping/\n // tracking/carrier/pickup/surcharge/weight) or `digital_fulfillment`\n // (buyer_country) - \"One nested block per product type, instead of\n // ~35 flat fields on OrderBase\" per that schema file's own Order\n // Schema Refactor comment. Every one of these was silently `undefined`\n // on every real order: a customer's tracking number, carrier, delivery\n // status, and shipping address never actually rendered anywhere on the\n // storefront's order tracking page.\n tracking_number: physical?.tracking_number ?? undefined,\n delivery_status: physical?.delivery_status ?? undefined,\n carrier_name: physical?.carrier_name ?? undefined,\n carrier_slug: physical?.carrier_slug ?? undefined,\n terminal_rate_id: physical?.terminal_rate_id ?? undefined,\n guest_token: raw.guest_token ?? undefined,\n guest_email: raw.guest_email ?? undefined,\n guest_phone: raw.guest_phone ?? undefined,\n guest_name: raw.guest_name ?? undefined,\n buyer_country: raw.digital_fulfillment?.buyer_country ?? undefined,\n created_at: raw.created_at,\n updated_at: raw.updated_at,\n\n // Weight discrepancy & surcharge fields (Task 2) — physical_fulfillment\n shipping_surcharge_amount: physical?.shipping_surcharge_amount ?? undefined,\n shipping_surcharge_reason: physical?.shipping_surcharge_reason ?? undefined,\n shipping_surcharge_description: physical?.shipping_surcharge_description ?? undefined,\n shipping_surcharge_applied_at: physical?.shipping_surcharge_applied_at ?? undefined,\n declared_weight_kg: physical?.declared_weight_kg ?? undefined,\n actual_weight_kg: physical?.actual_weight_kg ?? undefined,\n\n // Self-pickup verification fields (Task 3) — physical_fulfillment\n pickup_verification_code: physical?.pickup_verification_code ?? undefined,\n pickup_verification_code_generated_at: physical?.pickup_verification_code_generated_at ?? undefined,\n pickup_verification_code_used_at: physical?.pickup_verification_code_used_at ?? undefined,\n pickup_verification_failed_attempts: physical?.pickup_verification_failed_attempts,\n pickup_verification_locked_until: physical?.pickup_verification_locked_until ?? undefined,\n pickup_qr_payload: physical?.pickup_qr_payload ?? undefined,\n\n // Bespoke fields — real backend nests these under `bespoke_fulfillment`.\n bespoke_brief: raw.bespoke_fulfillment?.brief ?? undefined,\n bespoke_reference_images: raw.bespoke_fulfillment?.reference_images ?? undefined,\n bespoke_measurements: raw.bespoke_fulfillment?.measurements ?? undefined,\n bespoke_preferred_timeline: raw.bespoke_fulfillment?.preferred_timeline ?? undefined,\n bespoke_special_instructions: raw.bespoke_fulfillment?.special_instructions ?? undefined,\n bespoke_deposit_ratio: raw.bespoke_fulfillment?.deposit_ratio ?? undefined,\n bespoke_deposit_amount: raw.bespoke_fulfillment?.deposit_amount ?? undefined,\n bespoke_balance_amount: raw.bespoke_fulfillment?.balance_amount ?? undefined,\n bespoke_status: raw.bespoke_fulfillment?.status ?? undefined,\n bespoke_deliverable_submitted_at: raw.bespoke_fulfillment?.deliverable_submitted_at ?? undefined,\n bespoke_deliverable_url: raw.bespoke_fulfillment?.deliverable_url ?? undefined,\n bespoke_deliverable_notes: raw.bespoke_fulfillment?.deliverable_notes ?? undefined,\n bespoke_buyer_approved_at: raw.bespoke_fulfillment?.buyer_approved_at ?? undefined,\n bespoke_revision_count: raw.bespoke_fulfillment?.revision_count ?? 0,\n bespoke_revision_notes: raw.bespoke_fulfillment?.revision_notes ?? undefined,\n\n // SDK camelCase convenience aliases\n total: raw.total_amount ?? undefined,\n shippingAmount: raw.shipping_amount ?? undefined,\n discountAmount: raw.discount_amount ?? undefined,\n customerEmail: customerEmail,\n customerName: customerName,\n createdAt: new Date(raw.created_at).getTime(),\n updatedAt: new Date(raw.updated_at).getTime(),\n // REAL BUG FIXED (2026-09-23), found alongside the nesting bug above:\n // `deliveryMethod` reads physical_fulfillment.shipping_method now\n // (was reading a flat `delivery_method` field that never existed at\n // all, anywhere - not even nested). The real value is \"carrier\" or\n // \"self_pickup\" (PhysicalFulfillmentCreate.shipping_method's own\n // docstring) - see the matching fix in kasuvia-storefront's\n // OrderDeliveryInfo.tsx, which used to compare against the wrong\n // string \"pickup\".\n deliveryMethod: physical?.shipping_method ?? undefined,\n trackingNumber: physical?.tracking_number ?? undefined,\n deliveryAddress: 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 // REAL GAP (2026-09-23), NOT fixed here: confirmed cancellation_reason\n // does not exist anywhere in OrderResponse or any of its fulfillment\n // sub-schemas (kasuvia-store-management's app/schemas/order.py) - the\n // cancel-order endpoint accepts a `reason` in its request body but the\n // backend never persists/returns it back on the order. Permanently\n // undefined until the backend adds real storage for it; kept as a\n // field on the public Order type rather than silently removed, since\n // deleting a public SDK field is a breaking change this fix's scope\n // doesn't cover.\n cancellationReason: undefined,\n hasBespoke: raw.product_type === 'bespoke',\n // REAL GAP (2026-09-23), NOT fixed here: same as cancellationReason -\n // confirmed no `bespoke_stage` field exists anywhere; the real,\n // equivalent concept is bespoke_fulfillment.status (already exposed\n // above as `bespoke_status`). Reads that here rather than staying\n // permanently undefined, since it's genuinely the same real data the\n // consuming components (BespokeProgress) want to key off of.\n bespokeStage: raw.bespoke_fulfillment?.status ?? undefined,\n bespokeBrief: raw.bespoke_fulfillment?.brief ?? undefined,\n deliveryStatus: physical?.delivery_status ?? undefined,\n carrierName: physical?.carrier_name ?? undefined,\n terminalShipmentId: physical?.terminal_shipment_id ?? undefined,\n guestToken: raw.guest_token ?? undefined,\n guestEmail: raw.guest_email ?? undefined,\n guestPhone: raw.guest_phone ?? undefined,\n guestName: raw.guest_name ?? undefined,\n }\n}\n\n/**\n * REAL BUG FIXED (2026-09-22): `accessToken` was mandatory (`string`, not\n * optional) — the real backend endpoint (`POST /orders/storefront`,\n * create_storefront_order) explicitly supports guest checkout: `if not\n * user_id and not x_guest_session: raise 401`, matching the same\n * X-Guest-Session pattern cart.service.ts already uses. This endpoint\n * redeems the customer's real server-side cart (guest or authenticated) —\n * `payload.items`/`payload.product_type` are ignored by the backend\n * entirely regardless (see CreateOrderParams' own doc comment) — so a\n * guest with items already in their guest cart had no way to check out at\n * all through this SDK, even though the backend was built for exactly\n * that. `guestSessionId` is a separate parameter (not a body field) since\n * the backend reads it as a header, not JSON.\n */\nexport async function createOrder(\n config: SdkConfig,\n accessToken: string | undefined,\n payload: CreateOrderParams,\n guestSessionId?: string\n): Promise<Order> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n if (accessToken) {\n headers['Authorization'] = `Bearer ${accessToken}`\n } else if (guestSessionId) {\n headers['X-Guest-Session'] = guestSessionId\n }\n const data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/storefront`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to create order',\n })\n return normaliseStorefrontOrder(data)\n}\n\n/** Atomic, cart-less bespoke commission checkout — POST /orders/storefront/bespoke. */\nexport async function createBespokeOrder(config: SdkConfig, accessToken: string | undefined, payload: CreateBespokeOrderParams): Promise<Order> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n if (accessToken) headers[\"Authorization\"] = `Bearer ${accessToken}`\n\n const data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/storefront/bespoke`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to create bespoke order',\n })\n return normaliseStorefrontOrder(data)\n}\n\n/** Atomic, cart-less PAID service booking checkout — POST /orders/storefront/service. */\nexport async function createServiceBookingOrder(config: SdkConfig, accessToken: string | undefined, payload: CreateServiceBookingOrderParams): Promise<Order> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n if (accessToken) headers[\"Authorization\"] = `Bearer ${accessToken}`\n\n const data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/storefront/service`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to create service booking order',\n })\n return normaliseStorefrontOrder(data)\n}\n\n/**\n * REAL BUG FIXED (2026-09-22): called `GET /orders/find/?email=...&order_id=\n * ...&guest_token=...` — this route does not exist anywhere on the real\n * backend (confirmed against every route in app/api/v1/endpoints/sales/\n * orders.py). Every real call 404'd — the entire \"track my order by email +\n * order ID\" flow (`/track-order`, the actual page kasuvia-storefront's own\n * checkout confirmation links to) has been broken. The real, working\n * mechanism is `POST /orders/track` with a `GuestTrackRequest` body\n * (`{order_id, email}` — both required, no `guest_token` field exists on\n * this or any other real request shape). Fixed to match.\n */\nexport async function findOrder(config: SdkConfig, params: FindOrderParams): Promise<Order> {\n if (!params.email || !params.order_id) {\n throw new Error('Both email and order_id are required to find an order.')\n }\n const data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/track`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify({ order_id: params.order_id, email: params.email }),\n fallbackErrorMessage: 'Failed to find order',\n })\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 data = await apiRequest<RawOrder[] | { items: RawOrder[] }>(`${config.backendUrls.store}/orders/?${queryParams.toString()}`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to get orders',\n })\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 data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/${orderId}/cancel/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({ reason }),\n fallbackErrorMessage: 'Failed to cancel order',\n })\n return normaliseStorefrontOrder(data)\n}\n\n/**\n * REAL BUG FIXED (2026-09-22): called `GET /orders/track/{orderId}?token=\n * ...` — this route does not exist on the real backend at all (confirmed\n * against every route in orders.py). The `token` query param has no\n * corresponding capability anywhere: the real single-order lookup (`GET\n * /{order_id}`) requires a genuine authenticated JWT\n * (`Depends(get_current_user_claims)`) and grants access only to the\n * order's own customer (matching customer_id, or matching guest_email\n * against the JWT's email for a guest-checkout order that later registered)\n * — it has no anonymous/guest-token path at all. There is no real backend\n * capability today for \"look up one order by ID + a standalone token, no\n * login required\" — the only real guest lookup is findOrder (email +\n * order_id via POST /orders/track, a different, plural-sounding but\n * distinct endpoint). Fixed to call the real endpoint with its real,\n * mandatory-JWT contract; the fictional guest-token parameter is removed\n * rather than kept as a parameter that can never do anything.\n */\nexport async function trackOrder(config: SdkConfig, orderId: string, accessToken: string): Promise<Order> {\n const data = await apiRequest<RawOrder>(`${config.backendUrls.store}/orders/${orderId}`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to track order',\n })\n return normaliseStorefrontOrder(data)\n}\n\nexport interface PromoValidationResult {\n valid: boolean;\n discount_amount: number;\n discount_type: 'percentage' | 'fixed';\n message: string;\n}\n\n/**\n * Validate a promo / discount code against kasuvia-store-management.\n *\n * Routes directly to POST /sales/discounts/validate on the store backend\n * using X-Storefront-Key + X-Business-ID for tenant isolation.\n * The backend is the single source of truth for discount validity,\n * amount calculation, and usage tracking.\n */\nexport async function validatePromoCode(\n config: SdkConfig,\n code: string,\n cartTotal: number,\n): Promise<PromoValidationResult> {\n try {\n return await apiRequest<PromoValidationResult>(`${config.backendUrls.store}/sales/discounts/validate`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify({ code, cart_total: cartTotal }),\n fallbackErrorMessage: 'Invalid promo code',\n })\n } catch (err) {\n const message = err instanceof ApiError ? err.message : 'Invalid promo code'\n return { valid: false, discount_amount: 0, discount_type: 'fixed', message }\n }\n}\n\n// ── Digital download delivery ───────────────────────────────────────────────\n// REAL GAP FIXED (2026-09-22): GET /orders/{order_id}/download/{token} (the\n// exact link every \"your download is ready\" email sends) had ZERO kasuvia-sdk\n// coverage - the raw backend URL was embedded directly in the email instead,\n// and for a 2+-file product the route returns a raw JSON listing with no\n// page anywhere to render it (a customer clicking \"Download\" would see raw\n// JSON text in their browser). These are server-only functions (real,\n// un-proxied config.backendUrls.store, like legal.service.ts) meant to be\n// called from a storefront Server Component, never client-side - the real\n// backend route itself needs no business/storefront headers at all (the\n// token IS the capability, by design - see the route's own doc comment),\n// so no config beyond backendUrls.store is required either.\n//\n// Single file: the real route does an HTTP redirect straight to a freshly\n// presigned R2 URL - `redirect: 'manual'` lets a server-side fetch read\n// that Location header directly instead of the runtime silently following\n// it (which would otherwise download the whole file server-side for no\n// reason). 2+ files: the real route returns JSON instead, since a redirect\n// can only ever point at one destination.\n\nexport interface DigitalDownloadRedirect {\n type: 'redirect'\n url: string\n}\n\nexport interface DigitalDownloadFileEntry {\n id: string\n display_name: string\n sort_order: number\n /** Raw backend URL - never render this directly; resolve it via resolveDigitalDownloadFile instead. */\n download_url: string\n}\n\nexport interface DigitalDownloadListing {\n type: 'listing'\n order_id: string\n product_name: string\n download_count: number\n max_downloads: number\n expires_at: string | null\n files: DigitalDownloadFileEntry[]\n}\n\nexport type DigitalDownloadResult = DigitalDownloadRedirect | DigitalDownloadListing\n\nasync function resolveRedirectOrJson<T>(url: string, fallbackErrorMessage: string): Promise<{ type: 'redirect'; url: string } | { type: 'json'; data: T }> {\n const response = await fetch(url, { redirect: 'manual' })\n\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location')\n if (!location) {\n throw new Error(`${fallbackErrorMessage}: server redirected with no destination URL.`)\n }\n return { type: 'redirect', url: location }\n }\n\n const body = await response.json().catch(() => ({}))\n if (!response.ok) {\n throw new ApiError(extractDigitalDownloadError(body, fallbackErrorMessage), response.status, body)\n }\n return { type: 'json', data: body as T }\n}\n\nfunction extractDigitalDownloadError(body: unknown, fallback: string): string {\n if (typeof body === 'object' && body !== null && 'detail' in body && typeof (body as { detail?: unknown }).detail === 'string') {\n return (body as { detail: string }).detail\n }\n return fallback\n}\n\n/** GET /orders/{order_id}/download/{token} - server-only, no config beyond backendUrls.store needed. */\nexport async function resolveDigitalDownload(\n config: Pick<SdkConfig, 'backendUrls'>,\n orderId: string,\n token: string\n): Promise<DigitalDownloadResult> {\n const result = await resolveRedirectOrJson<Omit<DigitalDownloadListing, 'type'>>(\n `${config.backendUrls.store}/orders/${orderId}/download/${token}`,\n 'Failed to resolve digital download link'\n )\n if (result.type === 'redirect') return result\n return { type: 'listing', ...result.data }\n}\n\n/** GET /orders/{order_id}/download/{token}/{file_id} - resolves ONE file's real, freshly-presigned URL. */\nexport async function resolveDigitalDownloadFile(\n config: Pick<SdkConfig, 'backendUrls'>,\n orderId: string,\n token: string,\n fileId: string\n): Promise<string> {\n const result = await resolveRedirectOrJson<never>(\n `${config.backendUrls.store}/orders/${orderId}/download/${token}/${fileId}`,\n 'Failed to resolve this file\\'s download link'\n )\n if (result.type !== 'redirect') {\n throw new Error('Failed to resolve this file\\'s download link: server did not return a redirect.')\n }\n return result.url\n}\n\n\n","/**\n * Consultation Service\n *\n * REAL BUG FIXED (2026-09-21): a \"consultation\" service existed earlier this\n * session pointed at a fictional `/social/consultations/...` route that\n * matched nothing in any backend — deleted along with its dead storefront\n * pages. That deletion was correct (the URL was wrong), but a later audit\n * of kasuvia-crm-go found the underlying feature is real:\n * `POST /api/v1/consultations/` (customer-JWT-gated, real bespoke-slot-\n * reservation side effect when product_id references a bespoke product).\n * There is deliberately no list/get function here — kasuvia-crm-go's own\n * code comment confirms \"there is no customer-facing GET/list consultation\n * endpoint at all\" (admin_consultations.go). Create-only, by design.\n */\nimport type { SdkConfig } from '../config'\nimport { apiRequest, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\nexport interface CreateConsultationParams {\n product_id?: string\n structured_details?: Record<string, unknown>\n}\n\nexport interface Consultation {\n id: string\n business_id: string\n customer_id: string | null\n product_id: string | null\n status: string\n quote_amount: number | null\n structured_details: Record<string, unknown>\n capacity_config_id: string | null\n slot_booking_id: string | null\n created_at: string\n updated_at: string\n}\n\nexport async function createConsultation(\n config: SdkConfig,\n accessToken: string,\n params: CreateConsultationParams\n): Promise<Consultation> {\n return apiRequest<Consultation>(`${config.backendUrls.crm}/consultations/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(params),\n fallbackErrorMessage: 'Failed to submit your request',\n })\n}\n","/**\n * Feedback Service\n *\n * REAL FEATURE WIRED (2026-09-21): kasuvia-crm-go's feedback.go (`POST\n * /api/v1/feedback/`, `GET /api/v1/feedback/my`) is a complete, real,\n * customer-JWT-gated support-ticket system — private business<->customer\n * correspondence, distinct from a public, purchase-verified product Review —\n * with zero SDK coverage anywhere before this file.\n */\nimport type { SdkConfig } from '../config'\nimport { apiRequest, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\n/** Mirrors kasuvia-crm-go's models.ValidFeedbackCategories exactly. */\nexport type FeedbackCategory = 'general' | 'complaint' | 'suggestion'\n\n/** Mirrors kasuvia-crm-go's models.ValidFeedbackStatuses exactly. */\nexport type FeedbackStatus = 'open' | 'in_progress' | 'resolved'\n\nexport interface CreateFeedbackParams {\n subject: string\n body: string\n /** Defaults to 'general' server-side if omitted. */\n category?: FeedbackCategory\n order_id?: string\n}\n\nexport interface Feedback {\n id: string\n business_id: string\n customer_id: string\n order_id: string | null\n category: FeedbackCategory\n subject: string\n body: string\n status: FeedbackStatus\n merchant_reply: string | null\n merchant_reply_at: string | null\n replied_by: string | null\n created_at: string\n updated_at: string\n}\n\nexport interface FeedbackListResponse {\n results: Feedback[]\n count: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport async function createFeedback(\n config: SdkConfig,\n accessToken: string,\n params: CreateFeedbackParams\n): Promise<Feedback> {\n return apiRequest<Feedback>(`${config.backendUrls.crm}/feedback/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(params),\n fallbackErrorMessage: 'Failed to submit your message',\n })\n}\n\nexport async function getMyFeedback(\n config: SdkConfig,\n accessToken: string,\n params?: { page?: number; page_size?: number }\n): Promise<FeedbackListResponse> {\n const query = new URLSearchParams()\n if (params?.page) query.set('page', String(params.page))\n if (params?.page_size) query.set('page_size', String(params.page_size))\n return apiRequest<FeedbackListResponse>(`${config.backendUrls.crm}/feedback/my?${query.toString()}`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to load your requests',\n })\n}\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","/**\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 { apiRequest, ApiError, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\nimport { buildFullName, splitFullName } from '../utils/customer'\nimport type {\n CustomerAuthResponse,\n CustomerLoginPayload,\n CustomerRegisterPayload,\n CustomerPasswordlessRequestPayload,\n CustomerPasswordlessVerifyPayload,\n CustomerForgotPasswordPayload,\n CustomerResetPasswordPayload,\n CustomerDeactivatePayload,\n DeactivateAccountResult,\n DeactivateConfirmationRequired,\n CustomerReactivatePayload,\n CustomerReactivateVerifyPayload,\n LogoutPayload,\n RefreshTokenResponse,\n CustomerUser,\n AuthUserResponse,\n UpdateProfilePayload,\n StorefrontBusinessInfo,\n ChangePasswordPayload,\n CustomerAddress,\n CreateCustomerAddressPayload,\n UpdateCustomerAddressPayload,\n} from '../types/auth'\n\nimport type { MediaAsset } from '../types/media'\n\n// ── Auth API Calls ────────────────────────────────────────────────────────────\n\n/**\n * POST /auth/login/customer/\n * Business is identified by the X-Storefront-Key + X-Business-ID headers\n * (config.storefrontApiKey / config.businessId) — never a body field (see\n * plan: Customer Storefront Identity Enforcement).\n */\nexport async function loginCustomer(\n config: SdkConfig,\n payload: CustomerLoginPayload,\n guestSessionId?: string | null\n): Promise<CustomerAuthResponse> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n // REAL FEATURE FOUND (2026-09-21): kasuvia-auth's login/register/OTP-verify\n // views already run a real server-side guest-cart merge the moment tokens\n // are minted (customer.py's _run_post_login_merge, reading this exact\n // header) — deliberately built to replace depending on a frontend\n // remembering to call kasuvia-cart-management's /cart/merge afterward (see\n // cart_merge_client.py's own doc comment). This was simply never wired:\n // nothing in the storefront ever sent this header on login.\n if (guestSessionId) {\n headers['X-Guest-Session'] = guestSessionId\n }\n return apiRequest<CustomerAuthResponse>(`${config.backendUrls.auth}/auth/login/customer/`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Login failed',\n })\n}\n\n/**\n * POST /auth/register/customer/\n * Business identified via headers, see loginCustomer.\n */\nexport async function registerCustomer(\n config: SdkConfig,\n payload: CustomerRegisterPayload,\n guestSessionId?: string | null\n): Promise<CustomerAuthResponse> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n // See loginCustomer's identical comment — same real, already-built\n // server-side merge, same header.\n if (guestSessionId) {\n headers['X-Guest-Session'] = guestSessionId\n }\n return apiRequest<CustomerAuthResponse>(`${config.backendUrls.auth}/auth/register/customer/`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Registration failed',\n })\n}\n\n/** POST /auth/token/refresh/\n */\nexport async function refreshToken(\n config: SdkConfig,\n refresh: string\n): Promise<RefreshTokenResponse> {\n return apiRequest<RefreshTokenResponse>(`${config.backendUrls.auth}/auth/token/refresh/`, {\n method: 'POST',\n headers: JSON_HEADERS,\n body: JSON.stringify({ refresh }),\n fallbackErrorMessage: 'Token refresh failed',\n })\n}\n\n/**\n * POST /auth/logout/ — revokes the server-side session.\n *\n * Never throws: a customer's own logout must always clear their local\n * session client-side (caller does this regardless of this promise's\n * outcome) even if the backend is unreachable — an unrevoked server-side\n * session in that case is a availability tradeoff, not a security one (the\n * refresh token still expires on its own TTL). What CLAUDE.md forbids is\n * failing SILENTLY; the failure is now always logged with real context so\n * it's visible to whoever is debugging a report of \"sessions not clearing\n * server-side\", instead of vanishing into a bare `catch {}`.\n */\nexport async function logout(\n config: SdkConfig,\n refresh?: string\n): Promise<void> {\n const payload: LogoutPayload = refresh ? { refresh } : {}\n try {\n await apiRequest(`${config.backendUrls.auth}/auth/logout/`, {\n method: 'POST',\n headers: JSON_HEADERS,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Server-side logout failed',\n })\n } catch (err) {\n if (err instanceof ApiError) {\n console.error(`[auth.service] Server-side logout failed with status ${err.status}; local session will still be cleared.`)\n } else {\n console.error('[auth.service] Server-side logout request failed; local session will still be cleared.', err)\n }\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 return apiRequest<CustomerAuthResponse>(`${config.backendUrls.auth}/auth/social/verify/${provider}/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify({ id_token: token }),\n fallbackErrorMessage: 'Social token verification failed',\n })\n}\n\n/**\n * POST /auth/login/customer/passwordless/request/\n * Sends a one-time login code to the customer's email. Always resolves\n * successfully (the backend never reveals whether the email is registered).\n * Business identified via headers, see loginCustomer.\n */\nexport async function requestCustomerOtp(\n config: SdkConfig,\n payload: CustomerPasswordlessRequestPayload\n): Promise<void> {\n await apiRequest(`${config.backendUrls.auth}/auth/login/customer/passwordless/request/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to send login code',\n })\n}\n\n/**\n * POST /auth/login/customer/passwordless/verify/\n * Verifies a one-time login code and returns tokens, auto-creating the\n * customer account on first use (same as social login).\n * Business identified via headers, see loginCustomer.\n */\nexport async function verifyCustomerOtp(\n config: SdkConfig,\n payload: CustomerPasswordlessVerifyPayload,\n guestSessionId?: string | null\n): Promise<CustomerAuthResponse> {\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n // See loginCustomer's identical comment — same real, already-built\n // server-side merge, same header.\n if (guestSessionId) {\n headers['X-Guest-Session'] = guestSessionId\n }\n return apiRequest<CustomerAuthResponse>(`${config.backendUrls.auth}/auth/login/customer/passwordless/verify/`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Invalid or expired code',\n })\n}\n\n/**\n * POST /auth/forgot-password/customer/\n * Request a customer password reset OTP (business-scoped via headers).\n */\nexport async function forgotPasswordCustomer(\n config: SdkConfig,\n payload: CustomerForgotPasswordPayload\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/forgot-password/customer/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to request password reset',\n })\n}\n\n/**\n * POST /auth/reset-password/customer/\n * Verify OTP and reset customer password (business-scoped via headers).\n */\nexport async function resetPasswordCustomer(\n config: SdkConfig,\n payload: CustomerResetPasswordPayload\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/reset-password/customer/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Invalid or expired reset code',\n })\n}\n\n/**\n * POST /auth/customer/deactivate/\n * Self-service account deactivation for customers.\n */\nexport async function deactivateCustomerAccount(\n config: SdkConfig,\n accessToken: string,\n payload?: CustomerDeactivatePayload\n): Promise<DeactivateAccountResult> {\n try {\n const data = await apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/customer/deactivate/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload || {}),\n fallbackErrorMessage: 'Failed to deactivate account',\n })\n return { status: 'success', detail: data.detail }\n } catch (err) {\n // REAL BUG FIXED (2026-09-20): a 409 here is NOT a failure — it's step 1\n // of require_destructive_confirmation's real two-step contract (see\n // DeactivateConfirmationRequired's doc comment). The FIRST call with no\n // confirmation_code ALWAYS 409s by design, so this function as written\n // before could never actually succeed — it threw a generic Error on every\n // real call, discarding the impact list and confirmation_code the caller\n // needs to complete the flow.\n if (err instanceof ApiError && err.status === 409) {\n return { status: 'confirmation_required', data: err.body as DeactivateConfirmationRequired }\n }\n throw err\n }\n}\n\n/**\n * POST /auth/customer/reactivate/\n * Request reactivation code for a deactivated customer account.\n */\nexport async function requestCustomerReactivation(\n config: SdkConfig,\n payload: CustomerReactivatePayload\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/customer/reactivate/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to request reactivation',\n })\n}\n\n/**\n * POST /auth/customer/reactivate/verify/\n * Verify reactivation OTP and restore customer account.\n */\nexport async function verifyCustomerReactivation(\n config: SdkConfig,\n payload: CustomerReactivateVerifyPayload\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/customer/reactivate/verify/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Invalid or expired reactivation code',\n })\n}\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 // `/api/auth/me` proxies the raw AuthUserResponse shape (nested\n // `.profile.firstname` etc) under `data.user` — it must be mapped the\n // same way the config+accessToken branch below maps it, otherwise every\n // field on the returned \"CustomerUser\" is silently undefined.\n const data = await apiRequest<{ user: AuthUserResponse }>('/api/auth/me', {\n credentials: 'include',\n fallbackErrorMessage: 'Failed to fetch profile',\n })\n return mapAuthUserToCustomer(data.user)\n }\n\n const data = await apiRequest<AuthUserResponse>(`${config.backendUrls.auth}/auth/profile/`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch profile',\n })\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 data = await apiRequest<{ user: AuthUserResponse }>('/api/auth/me', {\n credentials: 'include',\n fallbackErrorMessage: 'Failed to fetch auth user',\n })\n return data.user\n }\n\n return apiRequest<AuthUserResponse>(`${config.backendUrls.auth}/auth/profile/`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch auth user',\n })\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 return apiRequest<CustomerUser>('/api/auth/profile', {\n method: 'PUT',\n headers: JSON_HEADERS,\n credentials: 'include',\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to update profile',\n })\n }\n\n const config = configOrPayload as SdkConfig\n const accessToken = accessTokenOrPayload as string\n const payload = payloadParam as UpdateProfilePayload\n\n // REAL BUG FIXED (2026-09-20): hardcoded generic message discarded real\n // CustomerProfileUpdateSerializer validation errors (e.g. invalid phone\n // format) — apiRequest's shared extractor handles this DRF dict shape.\n const data = await apiRequest<AuthUserResponse>(`${config.backendUrls.auth}/auth/profile/`, {\n method: 'PUT',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to update profile',\n })\n return mapAuthUserToCustomer(data)\n}\n\n/**\n * POST /auth/change-password/ — identity-mode-agnostic; the backend\n * branches on the JWT's identity_mode (kasuvia-auth/authentication/api/v1/\n * views/core.py:353, ChangePasswordView) to mutate the right underlying\n * profile (customer/staff/owner). Used here for a logged-in storefront\n * customer. `old_password` may be omitted only if the account genuinely has\n * no password yet (a social/passwordless-only customer setting one for the\n * first time) — the backend itself enforces this, not the frontend.\n */\nexport async function changePassword(\n config: SdkConfig,\n accessToken: string,\n payload: ChangePasswordPayload\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.auth}/auth/change-password/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to change password',\n })\n}\n\n/**\n * GET /auth/storefront/business-info/\n * Public, unauthenticated — only needs the storefront key (no access token,\n * no X-Business-ID; PublicBusinessInfoView resolves the business from the\n * key itself). Real gap fixed 2026-09-17: this endpoint existed on the\n * backend with zero SDK coverage.\n */\nexport async function getStorefrontBusinessInfo(config: SdkConfig): Promise<StorefrontBusinessInfo> {\n // PublicBusinessInfoView resolves the business from X-Storefront-Key alone\n // and never reads X-Business-ID — storefrontHeaders() sends both anyway\n // for consistency with every other call site; the extra header is inert\n // here (verified against the real view before making this change).\n return apiRequest<StorefrontBusinessInfo>(`${config.backendUrls.auth}/auth/storefront/business-info/`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to fetch business info',\n })\n}\n\nexport interface PresignedUploadUrlParams {\n filename: string\n content_type: string\n business_id: string\n context: string\n entity_id: string\n owner_id?: string\n affiliation?: string\n}\n\nexport interface PresignedUploadUrlResponse {\n presigned_url: string\n storage_path: string\n bucket: string\n expires_in: number\n asset_id?: string\n}\n\n/**\n * POST /auth/media/presigned-url/ — kasuvia-auth's thin proxy in front of\n * kasuvia-media-system. Params are sent as a query string (not a JSON\n * body) to match every other caller of this endpoint.\n */\nexport async function getPresignedUploadUrl(\n config: SdkConfig,\n accessToken: string,\n params: PresignedUploadUrlParams\n): Promise<PresignedUploadUrlResponse> {\n const query = new URLSearchParams(\n Object.entries(params).filter(([, v]) => v !== undefined) as [string, string][]\n )\n // Bearer-only, deliberately not storefrontHeaders() — this endpoint's real\n // header contract was never verified to also accept/require X-Storefront-\n // Key/X-Business-ID, unlike getStorefrontBusinessInfo above.\n return apiRequest<PresignedUploadUrlResponse>(\n `${config.backendUrls.auth}/auth/media/presigned-url/?${query.toString()}`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${accessToken}` },\n fallbackErrorMessage: 'Failed to get presigned upload URL',\n }\n )\n}\n\nexport interface ConfirmMediaUploadParams {\n storage_path: string\n business_id: string\n entity_id: string\n original_filename: string\n content_type: string\n size: number\n context: string\n owner_id?: string\n affiliation?: string\n}\n\n/**\n * POST /auth/media/confirm-upload/ — confirms a completed direct-to-R2\n * upload and returns the resulting MediaAsset. Params are sent as a query\n * string (not a JSON body) to match every other caller of this endpoint.\n */\nexport async function confirmMediaUpload(\n config: SdkConfig,\n accessToken: string,\n params: ConfirmMediaUploadParams\n): Promise<MediaAsset> {\n const query = new URLSearchParams(\n Object.entries(params).filter(([, v]) => v !== undefined) as [string, string][]\n )\n return apiRequest<MediaAsset>(\n `${config.backendUrls.auth}/auth/media/confirm-upload/?${query.toString()}`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${accessToken}` },\n fallbackErrorMessage: 'Failed to confirm upload',\n }\n )\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 (err) {\n // REAL BUG FIXED (2026-09-20): bare `catch {}` silently discarded the\n // real reason (network failure vs. an actually-revoked/expired refresh\n // token) — `null` here correctly means \"not currently logged in\" to the\n // caller (a legitimate outcome, not swallowed), but CLAUDE.md still\n // requires the failure itself be logged, not silently dropped.\n console.error('[auth.service] Silent token refresh failed:', err)\n return null\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// ── Customer saved-address book ─────────────────────────────────────────────\n// REAL FEATURE WIRED (2026-09-22): CustomerProfile.address_book existed as a\n// backend JSONField with no real write path anywhere (see\n// CustomerAddressListView's own doc comment in kasuvia-auth). This is the\n// SDK-side coverage for the real, now-validated endpoints.\n\n/** GET /auth/profile/addresses/ */\nexport async function getCustomerAddresses(config: SdkConfig, accessToken: string): Promise<CustomerAddress[]> {\n const data = await apiRequest<{ results: CustomerAddress[] }>(`${config.backendUrls.auth}/auth/profile/addresses/`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch saved addresses',\n })\n return data.results\n}\n\n/** POST /auth/profile/addresses/ */\nexport async function createCustomerAddress(\n config: SdkConfig,\n accessToken: string,\n payload: CreateCustomerAddressPayload\n): Promise<CustomerAddress> {\n return apiRequest<CustomerAddress>(`${config.backendUrls.auth}/auth/profile/addresses/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to save address',\n })\n}\n\n/** PATCH /auth/profile/addresses/{id}/ */\nexport async function updateCustomerAddress(\n config: SdkConfig,\n accessToken: string,\n addressId: string,\n payload: UpdateCustomerAddressPayload\n): Promise<CustomerAddress> {\n return apiRequest<CustomerAddress>(`${config.backendUrls.auth}/auth/profile/addresses/${addressId}/`, {\n method: 'PATCH',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to update address',\n })\n}\n\n/** DELETE /auth/profile/addresses/{id}/ */\nexport async function deleteCustomerAddress(config: SdkConfig, accessToken: string, addressId: string): Promise<void> {\n await apiRequest(`${config.backendUrls.auth}/auth/profile/addresses/${addressId}/`, {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to delete address',\n })\n}\n","import { GraphQLClient } from 'graphql-request'\nimport type { SdkConfig } from '../config'\n\n/**\n * REAL BUG FIXED (2026-09-21), live-reproduced in the browser console:\n * `graphql-request`'s `GraphQLClient` constructs a `new URL(endpoint)`\n * internally when issuing a request. Client-side SDK config deliberately\n * uses a same-origin relative path (`/api/proxy/store`) so the real backend\n * host is never exposed to the browser — but the native `URL` constructor\n * throws `TypeError: Failed to construct 'URL': Invalid URL` for a relative\n * string with no base, which is exactly what broke every client-side\n * GraphQL call (products, collections, wishlist): `Failed to fetch\n * products`/`Failed to fetch collections` in ProductsListing.tsx.\n *\n * Server-side config already uses an absolute real-backend URL, so this is\n * a no-op there — only the browser case (a relative path, `window` defined)\n * needs the current origin prepended.\n */\nexport function resolveGraphQLEndpoint(url: string): string {\n if (typeof window === 'undefined') return url\n try {\n // Absolute already (real backend URL, e.g. in a server-rendered client bundle edge case) — leave as-is.\n new URL(url)\n return url\n } catch {\n return `${window.location.origin}${url}`\n }\n}\n\n/**\n * REAL DUPLICATION FIXED (2026-09-22): this exact function (same headers,\n * same endpoint resolution) was hand-copied identically into\n * product.service.ts, collection.service.ts, and wishlist.service.ts — the\n * SDK's three GraphQL-backed services. One shared implementation now.\n */\nexport function 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(resolveGraphQLEndpoint(`${config.backendUrls.store}/graphql`), { headers })\n}\n","/** Internal type. DO NOT USE DIRECTLY. */\ntype Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };\n/** Internal type. DO NOT USE DIRECTLY. */\nexport type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };\nimport { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';\nexport type CollectionStatus =\n | 'ACTIVE'\n | 'ARCHIVED'\n | 'HIDDEN';\n\nexport type CollectionType =\n | 'MANUAL'\n | 'SMART';\n\nexport type ProductType =\n | 'BESPOKE'\n | 'DIGITAL'\n | 'PHYSICAL'\n | 'SERVICE';\n\nexport type CollectionFieldsFragment = { id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown };\n\nexport type GetStorefrontCollectionsQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontCollectionsQuery = { storefront_collections: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> } };\n\nexport type GetStorefrontCollectionBySlugQueryVariables = Exact<{\n slug: string;\n}>;\n\n\nexport type GetStorefrontCollectionBySlugQuery = { storefront_collection_by_slug: { id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown } | null };\n\nexport type ProductFieldsFragment = { id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> };\n\nexport type GetStorefrontProductsQueryVariables = Exact<{\n page: number;\n pageSize: number;\n collectionSlug?: string | null | undefined;\n search?: string | null | undefined;\n productType?: string | null | undefined;\n}>;\n\n\nexport type GetStorefrontProductsQuery = { storefront_products: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontProductBySlugQueryVariables = Exact<{\n slug: string;\n}>;\n\n\nexport type GetStorefrontProductBySlugQuery = { storefront_product_by_slug: { id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> } | null };\n\nexport type GetStorefrontPopularQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontPopularQuery = { storefront_popular: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontFeaturedQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontFeaturedQuery = { storefront_featured: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontNewQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontNewQuery = { storefront_new: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontOnSaleQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontOnSaleQuery = { storefront_on_sale: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontRecommendedQueryVariables = Exact<{\n page: number;\n pageSize: number;\n excludeProductId?: string | null | undefined;\n}>;\n\n\nexport type GetStorefrontRecommendedQuery = { storefront_recommended: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, business_id: string, name: string, slug: string, description: string | null, brand: string | null, product_type: ProductType, requires_shipping: boolean, is_consumable: boolean, is_bespoke: boolean, is_physical: boolean | null, is_non_returnable: boolean, deposit_percentage: number, base_price: number, currency: string, sale_price: number | null, sale_start: unknown, sale_end: unknown, images: Array<string>, tags: Array<string>, is_published: boolean, is_featured: boolean, is_popular: boolean, is_new: boolean, is_temporary: boolean, average_rating: number | null, rating_count: number, source_channel: string, source_channel_ref_id: string | null, service_type: string | null, service_duration_minutes: number | null, service_location_type: string | null, service_coverage_radius_km: number | null, service_requires_consultation: boolean, service_max_capacity_per_slot: number | null, service_buffer_minutes: number, service_is_recurring: boolean, service_recurring_interval: string | null, service_project_based: boolean, download_limit: number | null, download_expires_at: unknown, weight_kg: number, length_cm: number | null, width_cm: number | null, height_cm: number | null, created_at: unknown, updated_at: unknown, custom_fields: Array<{ label: string, unit: string | null, required: boolean, field_type: string, options: Array<string> }>, digital_files: Array<{ id: string, file_key: string, display_name: string, sort_order: number }>, variants: Array<{ id: string, product_id: string, sku: string | null, attributes: string | null, price: number | null, images: Array<string>, weight_kg: number | null, is_active: boolean, created_at: unknown, updated_at: unknown, inventory: { id: string, product_id: string, variant_id: string | null, quantity: number, reserved: number, reorder_point: number, reorder_quantity: number, track_quantity: boolean, allow_backorder: boolean, available: number, is_in_stock: boolean, is_low_stock: boolean, updated_at: unknown } | null }>, collections: Array<{ id: string, business_id: string | null, name: string, slug: string, description: string | null, image_url: string | null, collection_type: CollectionType, rules: string | null, status: CollectionStatus, sort_order: number, created_at: unknown, updated_at: unknown }> }> } };\n\nexport type GetStorefrontWishlistQueryVariables = Exact<{\n page: number;\n pageSize: number;\n}>;\n\n\nexport type GetStorefrontWishlistQuery = { storefront_wishlist: { total: number, page: number, page_size: number, total_pages: number, items: Array<{ id: string, product_id: string, notes: string | null, created_at: unknown, product_name: string | null, product_slug: string | null, product_price: number | null, currency: string | null, product_image: string | null }> } };\n\nexport type CheckInStorefrontWishlistQueryVariables = Exact<{\n productId: string;\n}>;\n\n\nexport type CheckInStorefrontWishlistQuery = { check_in_storefront_wishlist: { in_wishlist: boolean } };\n\nexport const CollectionFieldsFragmentDoc = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"CollectionFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Collection\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]} as unknown as DocumentNode<CollectionFieldsFragment, unknown>;\nexport const ProductFieldsFragmentDoc = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<ProductFieldsFragment, unknown>;\nexport const GetStorefrontCollectionsDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontCollections\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_collections\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"CollectionFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"CollectionFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Collection\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]} as unknown as DocumentNode<GetStorefrontCollectionsQuery, GetStorefrontCollectionsQueryVariables>;\nexport const GetStorefrontCollectionBySlugDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontCollectionBySlug\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_collection_by_slug\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"CollectionFields\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"CollectionFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Collection\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]} as unknown as DocumentNode<GetStorefrontCollectionBySlugQuery, GetStorefrontCollectionBySlugQueryVariables>;\nexport const GetStorefrontProductsDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontProducts\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"collectionSlug\"}},\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"search\"}},\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"productType\"}},\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_products\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"collectionSlug\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"collectionSlug\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"search\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"search\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"productType\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"productType\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontProductsQuery, GetStorefrontProductsQueryVariables>;\nexport const GetStorefrontProductBySlugDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontProductBySlug\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_product_by_slug\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontProductBySlugQuery, GetStorefrontProductBySlugQueryVariables>;\nexport const GetStorefrontPopularDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontPopular\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_popular\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontPopularQuery, GetStorefrontPopularQueryVariables>;\nexport const GetStorefrontFeaturedDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontFeatured\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_featured\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontFeaturedQuery, GetStorefrontFeaturedQueryVariables>;\nexport const GetStorefrontNewDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontNew\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_new\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontNewQuery, GetStorefrontNewQueryVariables>;\nexport const GetStorefrontOnSaleDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontOnSale\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_on_sale\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontOnSaleQuery, GetStorefrontOnSaleQueryVariables>;\nexport const GetStorefrontRecommendedDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontRecommended\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"excludeProductId\"}},\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_recommended\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"excludeProductId\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"excludeProductId\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"FragmentSpread\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}},{\"kind\":\"FragmentDefinition\",\"name\":{\"kind\":\"Name\",\"value\":\"ProductFields\"},\"typeCondition\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Product\"}},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"brand\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"requires_shipping\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_consumable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_bespoke\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_physical\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_non_returnable\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"deposit_percentage\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"base_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_start\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sale_end\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"tags\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"custom_fields\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"label\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"unit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"required\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"field_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"options\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_published\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_featured\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_popular\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_new\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_temporary\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"average_rating\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rating_count\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"source_channel_ref_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_duration_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_location_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_coverage_radius_km\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_requires_consultation\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_max_capacity_per_slot\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_buffer_minutes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_is_recurring\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_recurring_interval\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"service_project_based\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"digital_files\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"file_key\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"display_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_limit\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"download_expires_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"length_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"width_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"height_cm\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variants\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sku\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"attributes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"images\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"weight_kg\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_active\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"inventory\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"variant_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reserved\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_point\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"reorder_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"track_quantity\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"allow_backorder\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"available\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_in_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"is_low_stock\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collections\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"business_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"description\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"image_url\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"collection_type\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"rules\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"status\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"sort_order\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"updated_at\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontRecommendedQuery, GetStorefrontRecommendedQueryVariables>;\nexport const GetStorefrontWishlistDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"GetStorefrontWishlist\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}},{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"Int\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"storefront_wishlist\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}}},{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"pageSize\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"items\"},\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_id\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"notes\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"created_at\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_name\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_slug\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_price\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"currency\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"product_image\"}}]}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"page_size\"}},{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"total_pages\"}}]}}]}}]} as unknown as DocumentNode<GetStorefrontWishlistQuery, GetStorefrontWishlistQueryVariables>;\nexport const CheckInStorefrontWishlistDocument = {\"kind\":\"Document\",\"definitions\":[{\"kind\":\"OperationDefinition\",\"operation\":\"query\",\"name\":{\"kind\":\"Name\",\"value\":\"CheckInStorefrontWishlist\"},\"variableDefinitions\":[{\"kind\":\"VariableDefinition\",\"variable\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"productId\"}},\"type\":{\"kind\":\"NonNullType\",\"type\":{\"kind\":\"NamedType\",\"name\":{\"kind\":\"Name\",\"value\":\"String\"}}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"check_in_storefront_wishlist\"},\"arguments\":[{\"kind\":\"Argument\",\"name\":{\"kind\":\"Name\",\"value\":\"productId\"},\"value\":{\"kind\":\"Variable\",\"name\":{\"kind\":\"Name\",\"value\":\"productId\"}}}],\"selectionSet\":{\"kind\":\"SelectionSet\",\"selections\":[{\"kind\":\"Field\",\"name\":{\"kind\":\"Name\",\"value\":\"in_wishlist\"}}]}}]}}]} as unknown as DocumentNode<CheckInStorefrontWishlistQuery, CheckInStorefrontWishlistQueryVariables>;","/**\n * Product Service\n *\n * Handles product operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport type { Product, PaginatedResponse, ListParams } from '../types/store'\nimport { ProductTypeEnum } from '../types/store'\nimport type { SdkConfig } from '../config'\nimport { createGraphQLClient } from '../utils/graphql-url'\nimport {\n GetStorefrontProductsDocument,\n GetStorefrontProductBySlugDocument,\n GetStorefrontPopularDocument,\n GetStorefrontFeaturedDocument,\n GetStorefrontNewDocument,\n GetStorefrontOnSaleDocument,\n GetStorefrontRecommendedDocument,\n type ProductFieldsFragment,\n type ProductType as GeneratedProductType,\n} from '../generated/graphql'\n\n/**\n * REAL BUG FIXED (2026-09-21), live-reproduced — the root cause of \"nothing\n * e-commerce-related works\": kasuvia-store-management's ProductType is a\n * Python Enum (`PHYSICAL = \"physical\"`, schema.py:16-20). Strawberry\n * GraphQL serializes an enum field using the member NAME over the wire —\n * standard, spec-correct GraphQL behavior (GraphQL enum values are\n * conventionally ALL_CAPS) — so `storefront_products { items { product_type\n * } } }` has always actually returned `\"PHYSICAL\"`/`\"DIGITAL\"`/`\"SERVICE\"`/\n * `\"BESPOKE\"`, never the lowercase value every frontend `product_type ===\n * \"physical\"` check (ProductCTA, ProductInfo, ProductTypeDetails,\n * ProductCard, CheckoutClient, getGuestCartProductType — every one of them)\n * was written assuming. Every type-aware branch silently fell through to\n * whatever its default/fallback case was, for every single product,\n * platform-wide — confirmed live: a real SERVICE product rendered a plain\n * \"Add to Cart\" button instead of any service-specific flow.\n *\n * Originally fixed with a blind `.toLowerCase()` at the single point every\n * product enters the SDK from GraphQL. Now that `product_type` is a real\n * generated union (`GeneratedProductType`, from graphql-codegen against the\n * live schema — see graphql/schema.graphql), this is an exhaustive switch\n * instead: if kasuvia-store-management ever adds a 5th ProductType member,\n * this function fails to COMPILE until it's handled here, rather than\n * silently lowercasing an unrecognised string at runtime.\n */\nfunction mapProductType(raw: GeneratedProductType): ProductTypeEnum {\n switch (raw) {\n case 'PHYSICAL':\n return ProductTypeEnum.PHYSICAL\n case 'DIGITAL':\n return ProductTypeEnum.DIGITAL\n case 'SERVICE':\n return ProductTypeEnum.SERVICE\n case 'BESPOKE':\n return ProductTypeEnum.BESPOKE\n default: {\n const _exhaustive: never = raw\n throw new Error(`Unhandled GraphQL ProductType member: ${_exhaustive}`)\n }\n }\n}\n\n/**\n * `field_type` is a plain GraphQL String (CustomField isn't a GraphQL enum),\n * but the real backend (CustomFieldSchema's `Literal[\"text\", \"choice\"]`)\n * only ever writes one of these two values — validated at save time, not\n * guessed here. An unrecognised value means the backend and this mapping\n * have drifted, which should fail loud rather than silently coerce to a\n * default that would misrender the field.\n */\nfunction mapCustomFieldType(raw: string): \"text\" | \"choice\" {\n if (raw === \"text\" || raw === \"choice\") return raw\n throw new Error(`Unrecognised custom field field_type from backend: \"${raw}\"`)\n}\n\n/**\n * Maps the raw, generated GraphQL fragment shape to the SDK's public\n * `Product` type. `satisfies Product` (not `as Product`) is deliberate: it\n * keeps this a real compile-time check against the public type rather than\n * an unchecked assertion — if `ProductFieldsFragment` and `Product` ever\n * drift (a field renamed on one side, a nullability change), this function\n * fails to compile instead of quietly shipping a mismatched shape.\n */\nfunction mapProduct(raw: ProductFieldsFragment): Product {\n return {\n ...raw,\n product_type: mapProductType(raw.product_type),\n custom_fields: raw.custom_fields.map((f) => ({\n ...f,\n unit: f.unit ?? undefined,\n field_type: mapCustomFieldType(f.field_type),\n })),\n description: raw.description ?? undefined,\n brand: raw.brand ?? undefined,\n is_physical: raw.is_physical ?? undefined,\n sale_price: raw.sale_price ?? undefined,\n sale_start: (raw.sale_start as string | null) ?? undefined,\n sale_end: (raw.sale_end as string | null) ?? undefined,\n source_channel_ref_id: raw.source_channel_ref_id ?? undefined,\n download_limit: raw.download_limit ?? undefined,\n download_expires_at: (raw.download_expires_at as string | null) ?? undefined,\n service_type: (raw.service_type as Product['service_type']) ?? undefined,\n service_duration_minutes: raw.service_duration_minutes ?? undefined,\n service_location_type: (raw.service_location_type as Product['service_location_type']) ?? undefined,\n service_coverage_radius_km: raw.service_coverage_radius_km ?? undefined,\n service_max_capacity_per_slot: raw.service_max_capacity_per_slot ?? undefined,\n service_recurring_interval: (raw.service_recurring_interval as Product['service_recurring_interval']) ?? undefined,\n length_cm: raw.length_cm ?? undefined,\n width_cm: raw.width_cm ?? undefined,\n height_cm: raw.height_cm ?? undefined,\n average_rating: raw.average_rating ?? undefined,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n variants: raw.variants.map((v) => ({\n ...v,\n sku: v.sku ?? undefined,\n attributes: v.attributes ? JSON.parse(v.attributes) : {},\n price: v.price ?? undefined,\n weight_kg: v.weight_kg ?? undefined,\n inventory: v.inventory\n ? {\n ...v.inventory,\n variant_id: v.inventory.variant_id ?? undefined,\n updated_at: v.inventory.updated_at as string,\n }\n : undefined,\n created_at: v.created_at as string,\n updated_at: v.updated_at as string,\n })),\n collections: raw.collections.map((c) => ({\n ...c,\n business_id: c.business_id ?? undefined,\n description: c.description ?? undefined,\n image_url: c.image_url ?? undefined,\n rules: c.rules ?? undefined,\n created_at: c.created_at as string,\n updated_at: c.updated_at as string,\n })),\n } satisfies Product\n}\n\nfunction mapProductConnection<T extends { items: ProductFieldsFragment[]; total: number; page: number; page_size: number; total_pages: number }>(\n connection: T\n): PaginatedResponse<Product> {\n return { ...connection, items: connection.items.map(mapProduct) }\n}\n\n/**\n * Create GraphQL client with provided config\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 data = await client.request(GetStorefrontProductsDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n collectionSlug: params?.collectionSlug,\n search: params?.search,\n productType: params?.productType,\n })\n return mapProductConnection(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(GetStorefrontProductBySlugDocument, { slug })\n if (!data.storefront_product_by_slug) {\n throw new Error(`Product not found: ${slug}`)\n }\n return mapProduct(data.storefront_product_by_slug)\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 data = await client.request(GetStorefrontPopularDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n })\n return mapProductConnection(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 data = await client.request(GetStorefrontFeaturedDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n })\n return mapProductConnection(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 data = await client.request(GetStorefrontNewDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n })\n return mapProductConnection(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 data = await client.request(GetStorefrontOnSaleDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n })\n return mapProductConnection(data.storefront_on_sale)\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 data = await client.request(GetStorefrontRecommendedDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 4,\n excludeProductId: params?.excludeProductId,\n })\n return mapProductConnection(data.storefront_recommended)\n}\n","/**\n * Collection Service\n *\n * Handles collection operations using GraphQL.\n * Stateless - all configuration passed as parameters.\n */\nimport type { Collection, PaginatedResponse, ListParams } from '../types/store'\nimport type { SdkConfig } from '../config'\nimport { createGraphQLClient } from '../utils/graphql-url'\nimport {\n GetStorefrontCollectionsDocument,\n GetStorefrontCollectionBySlugDocument,\n type CollectionFieldsFragment,\n} from '../generated/graphql'\n\nfunction mapCollection(raw: CollectionFieldsFragment): Collection {\n return {\n ...raw,\n business_id: raw.business_id ?? undefined,\n description: raw.description ?? undefined,\n image_url: raw.image_url ?? undefined,\n rules: raw.rules ?? undefined,\n created_at: raw.created_at as string,\n updated_at: raw.updated_at as string,\n } satisfies Collection\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 data = await client.request(GetStorefrontCollectionsDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n })\n return { ...data.storefront_collections, items: data.storefront_collections.items.map(mapCollection) }\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(GetStorefrontCollectionBySlugDocument, { slug })\n if (!data.storefront_collection_by_slug) {\n throw new Error(`Collection not found: ${slug}`)\n }\n return mapCollection(data.storefront_collection_by_slug)\n}\n","/**\n * Wishlist Service\n * \n * Handles wishlist operations.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { WishlistItem, WishlistListResponse, WishlistCheckResponse } from '../types/store'\nimport { createGraphQLClient } from '../utils/graphql-url'\nimport { GetStorefrontWishlistDocument, CheckInStorefrontWishlistDocument } from '../generated/graphql'\nimport { apiRequest, authHeaders, JSON_HEADERS } from '../utils/http-client'\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 data = await client.request(GetStorefrontWishlistDocument, {\n page: params?.page || 1,\n pageSize: params?.pageSize || 20,\n })\n return {\n ...data.storefront_wishlist,\n items: data.storefront_wishlist.items.map((item) => ({\n ...item,\n created_at: item.created_at as string,\n notes: item.notes ?? undefined,\n product_name: item.product_name ?? undefined,\n product_slug: item.product_slug ?? undefined,\n product_price: item.product_price ?? undefined,\n currency: item.currency ?? undefined,\n product_image: item.product_image ?? undefined,\n })) satisfies WishlistItem[],\n }\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(CheckInStorefrontWishlistDocument, { 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 return apiRequest<WishlistItem>(`${config.backendUrls.store}/wishlist/`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({\n product_id: productId,\n notes: notes || undefined,\n }),\n fallbackErrorMessage: 'Failed to add to wishlist',\n })\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 await apiRequest(`${config.backendUrls.store}/wishlist/${itemId}`, {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to remove from wishlist',\n })\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 await apiRequest(`${config.backendUrls.store}/wishlist/product/${productId}`, {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to remove product from wishlist',\n })\n}\n","/**\n * Payment Service\n *\n * Customer-facing payment API for payment initiation and verification via\n * kasuvia-payment-system-go.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n DVACreateRequest,\n DVADetails,\n GatewayMethods,\n PaymentInitiateRequest,\n PaymentInitiateResponse,\n TransactionVerifyResponse,\n WalletBalanceResponse,\n WalletLedgerResponse,\n} from '../types/payments/index'\nimport { apiRequest, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\nfunction isValidUUID(str: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(str)\n}\n\n/**\n * Fetch available payment methods and gateways for a storefront region.\n *\n * REAL BUG FIXED (2026-09-22): `currency`/`countryCode` used to default to\n * 'NGN'/'NG' as SDK-level JS defaults — an independent copy of a value the\n * real backend already declares itself (`query:\"currency\" default:\"NGN\"` /\n * `query:\"country_code\" default:\"NG\"`, kasuvia-payment-system-go's own real,\n * documented default for this route). Duplicating it client-side risks the\n * two silently drifting apart if the backend's real default is ever\n * changed. Now optional with no client-side default at all — when omitted,\n * the query param is left out entirely and the backend's own declared\n * default applies, the single source of truth for what \"unspecified\"\n * means here.\n */\nexport async function getAvailablePaymentMethods(\n config: SdkConfig,\n currency?: string,\n countryCode?: string\n): Promise<GatewayMethods[]> {\n const params: Record<string, string> = {}\n if (currency) params.currency = currency\n if (countryCode) params.country_code = countryCode\n const query = new URLSearchParams(params).toString()\n return apiRequest<GatewayMethods[]>(`${config.backendUrls.payment}/payments/storefront/methods${query ? `?${query}` : ''}`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to fetch available payment methods',\n })\n}\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 | null | undefined,\n request: DVACreateRequest\n): Promise<DVADetails> {\n const origin = request.storefront_origin || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n if (accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`\n }\n if (origin) {\n headers[\"Origin\"] = origin\n }\n\n return apiRequest<DVADetails>(`${config.backendUrls.payment}/payments/storefront/dedicated-account`, {\n method: 'POST',\n headers,\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 gateway: request.gateway,\n idempotency_key: request.idempotency_key,\n }),\n fallbackErrorMessage: 'Failed to create dedicated account',\n })\n}\n\n/**\n * Initiate a payment (customer → business owner).\n * Routes to Monnify, Flutterwave, or Paystack on the backend based on region/selection.\n * Returns a checkout_url to redirect the customer to the gateway.\n */\nexport async function initiatePayment(\n config: SdkConfig,\n accessToken: string | null | undefined,\n request: PaymentInitiateRequest\n): Promise<PaymentInitiateResponse> {\n const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined;\n const origin = request.storefront_origin || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const headers: Record<string, string> = { ...JSON_HEADERS, ...storefrontHeaders(config) }\n if (accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`\n }\n if (origin) {\n headers[\"Origin\"] = origin\n }\n\n const data = await apiRequest<PaymentInitiateResponse & { metadata_json?: { checkout_url?: string } }>(\n `${config.backendUrls.payment}/payments/storefront/initiate`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n amount: request.amount,\n currency: request.currency,\n // Same real backend default as getAvailablePaymentMethods above\n // (huma's own `default:\"NG\"` on this field) — omit rather than\n // hardcode a client-side copy of it.\n country_code: request.country_code,\n gateway: request.gateway,\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 fallbackErrorMessage: 'Failed to initiate payment',\n }\n )\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 * Verify a payment after the gateway redirects back to /checkout/verify.\n */\nexport async function verifyTransaction(\n config: SdkConfig,\n reference: string\n): Promise<TransactionVerifyResponse> {\n return apiRequest<TransactionVerifyResponse>(`${config.backendUrls.payment}/payments/verify/${reference}`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n fallbackErrorMessage: 'Failed to verify transaction',\n })\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 return apiRequest<TransactionVerifyResponse>(`${config.backendUrls.payment}/payments/transactions/${transactionId}`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get transaction status',\n })\n}\n\n/**\n * Fetch authenticated customer's wallet balance.\n */\nexport async function getWalletBalance(\n config: SdkConfig,\n accessToken: string\n): Promise<WalletBalanceResponse> {\n return apiRequest<WalletBalanceResponse>(`${config.backendUrls.payment}/wallet/balance`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch wallet balance',\n })\n}\n\n/**\n * Fetch authenticated customer's wallet ledger (transaction history).\n */\nexport async function getWalletLedger(\n config: SdkConfig,\n accessToken: string,\n params?: { page?: number; page_size?: number }\n): Promise<WalletLedgerResponse> {\n const page = params?.page ?? 1\n const pageSize = params?.page_size ?? 20\n return apiRequest<WalletLedgerResponse>(\n `${config.backendUrls.payment}/wallet/ledger?page=${page}&page_size=${pageSize}`,\n {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to fetch wallet ledger',\n }\n )\n}\n\n/**\n * Claim a pending guest wallet credit into the authenticated customer's wallet.\n */\nexport async function claimWalletCredit(\n config: SdkConfig,\n accessToken: string,\n claimToken: string\n): Promise<WalletBalanceResponse> {\n return apiRequest<WalletBalanceResponse>(`${config.backendUrls.payment}/wallet/claim`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({ claim_token: claimToken }),\n fallbackErrorMessage: 'Failed to claim wallet credit',\n })\n}\n\nexport const paymentService = {\n getAvailablePaymentMethods,\n createDedicatedAccount,\n initiatePayment,\n verifyTransaction,\n getTransactionStatus,\n getWalletBalance,\n getWalletLedger,\n claimWalletCredit,\n} as const\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 { components } from '../generated/store-openapi'\nimport { apiRequest, storefrontHeaders, JSON_HEADERS } from '../utils/http-client'\n\nexport interface RateAddress {\n city: string\n state: string\n country: string\n}\n\n/**\n * REAL BUG FIXED (2026-09-20): this request shape used to be `{cart_items,\n * origin_address, destination_address, currency?, shipping_method?}` —\n * completely stale against the real backend. Confirmed against the real\n * Pydantic schema (kasuvia-store-management/app/schemas/logistics.py:121-144,\n * `ShippingRatesRequest`), which explicitly documents why: \"No origin_address\n * field — the server resolves the fulfilling StoreLocation itself... A\n * client-supplied origin would either have to be silently ignored or\n * silently trusted over the resolved location; neither is acceptable, so it\n * isn't accepted at all.\" The server also fetches cart items itself from\n * `cart_id` (server-side cart as source of truth, preventing client-side\n * cart manipulation) rather than trusting a client-submitted item list.\n * Sending the old shape meant every physical checkout's shipping-rates call\n * was missing the required `cart_id` field entirely and would always 422.\n */\nexport interface ShippingRatesRequest {\n cart_id: string\n destination_address: RateAddress\n currency: string\n shipping_method?: 'carrier' | 'self_pickup'\n /** Required when shipping_method is 'self_pickup' — see GET /logistics/pickup-locations. */\n pickup_location_id?: 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 return apiRequest<ShippingRatesResponse>(`${config.backendUrls.store}/logistics/shipping/rates`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to get shipping rates',\n })\n}\n\n/**\n * Result of independently forward-geocoding the typed street address via\n * LocationIQ and cross-checking it against Terminal Africa's own (city/\n * state/country-only, street-line-blind) validation. See\n * app/services/address_trust_service.py on the backend. Only present when\n * Terminal Africa itself reported the address valid.\n */\nexport interface AddressTrustResult {\n trusted: boolean\n confidence: 'high' | 'medium' | 'low' | 'unavailable'\n reason: string | null\n resolved: {\n latitude: number\n longitude: number\n display_name: string\n city: string | null\n state: string | null\n country: string | null\n } | null\n plus_code: string | null\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 /** Street-level trust check — only present when valid is true. See AddressTrustResult. */\n address_trust?: AddressTrustResult\n}> {\n return apiRequest(`${config.backendUrls.store}/logistics/shipping-address/validate`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to validate shipping address',\n })\n}\n\nexport interface PickupLocation {\n id: string\n name: string\n description: string | null\n address: {\n line1: string\n line2: string | null\n city: string\n state: string\n country: string\n postal_code: string\n }\n coordinates: { latitude: number; longitude: number }\n /** km from the coordinates passed to listPickupLocations, or null if none were passed. */\n distance_km: number | null\n operating_hours: Record<string, string> | null\n}\n\n/**\n * List the business's active pickup locations, so the customer can choose\n * one at checkout for shipping_method=\"self_pickup\" instead of the merchant\n * assigning one blindly after the fact. Pass the customer's shipping\n * coordinates to sort nearest-first.\n */\nexport interface PickupLocationsResult {\n locations: PickupLocation[]\n}\n\nasync function fetchLocationList(\n config: SdkConfig,\n path: 'pickup-locations' | 'locations',\n coords: { latitude: number; longitude: number } | undefined,\n fallbackErrorMessage: string\n): Promise<PickupLocationsResult> {\n const params = new URLSearchParams()\n if (coords) {\n params.set('latitude', String(coords.latitude))\n params.set('longitude', String(coords.longitude))\n }\n const qs = params.toString()\n return apiRequest(`${config.backendUrls.store}/logistics/${path}${qs ? `?${qs}` : ''}`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage,\n })\n}\n\nexport async function listPickupLocations(\n config: SdkConfig,\n coords?: { latitude: number; longitude: number }\n): Promise<PickupLocationsResult> {\n return fetchLocationList(config, 'pickup-locations', coords, 'Failed to list pickup locations')\n}\n\n/**\n * List ALL of the business's active locations (not just pickup-eligible\n * ones) — the set a customer needs to choose from for an 'at_business'\n * service appointment when the business runs more than one branch. Sibling\n * of listPickupLocations, same response shape (PickupLocationsResult),\n * different backend filter (GET /logistics/locations, no\n * is_pickup_location gate).\n */\nexport async function listBusinessLocations(\n config: SdkConfig,\n coords?: { latitude: number; longitude: number }\n): Promise<PickupLocationsResult> {\n return fetchLocationList(config, 'locations', coords, 'Failed to list business locations')\n}\n\n/**\n * Reverse geocode coordinates to address components using backend LocationIQ service.\n */\nexport interface ReverseGeocodeResult {\n city: string | null\n state: string | null\n country: string | null\n country_code: string | null\n display_name: string | null\n}\n\nexport async function reverseGeocode(\n config: SdkConfig,\n payload: { latitude: number; longitude: number }\n): Promise<ReverseGeocodeResult> {\n return apiRequest(`${config.backendUrls.store}/logistics/reverse-geocode`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to reverse geocode coordinates',\n })\n}\n\n/**\n * Decode a Plus Code to coordinates.\n */\nexport interface PlusCodeDecodeResult {\n latitude: number\n longitude: number\n latitude_lo: number\n longitude_hi: number\n plus_code: string\n}\n\nexport async function decodePlusCode(\n config: SdkConfig,\n payload: { plus_code: string }\n): Promise<PlusCodeDecodeResult> {\n return apiRequest(`${config.backendUrls.store}/logistics/plus-code/decode`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to decode Plus Code',\n })\n}\n\n/**\n * As-you-type address autocomplete suggestions.\n */\nexport interface AddressSuggestionResult {\n place_id: string\n display_name: string\n line1: string\n city: string | null\n state: string | null\n postal_code: string | null\n country: string | null\n country_code: string | null\n latitude: number | null\n longitude: number | null\n}\n\nexport interface AddressAutocompleteResult {\n results: AddressSuggestionResult[]\n}\n\nexport async function autocompleteAddress(\n config: SdkConfig,\n q: string,\n country?: string\n): Promise<AddressAutocompleteResult> {\n const params = new URLSearchParams()\n params.set('q', q)\n if (country) params.set('country', country)\n\n return apiRequest(`${config.backendUrls.store}/logistics/address/autocomplete?${params.toString()}`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to autocomplete address',\n })\n}\n\n// ─── Codegen drift-proofs (openapi/README.md — regenerate via `pnpm run codegen:rest`) ─\n// Same approach as the other 3 target files' own comments. `getShippingRates`\n// and `validateShippingAddress` are deliberately NOT checked here:\n// GET /logistics/shipping/rates passes through Terminal Africa's own\n// response envelope as a raw dict (no Kasuvia-owned schema exists to check\n// against - a third party's contract, not this platform's), and\n// POST /logistics/shipping-address/validate similarly has no\n// response_model= (confirmed absent, same underlying gap class as\n// pickup-locations was until this pass, but out of scope for this initial\n// sweep - flagged here rather than silently left unchecked with no\n// explanation). PickupLocationsResult/ReverseGeocodeResult/\n// PlusCodeDecodeResult/AddressAutocompleteResult all have real backend\n// schemas and are checked below - PickupLocationsResponse's\n// response_model was added to the backend as part of this exact change\n// (previously also a raw-dict gap).\n// `operating_hours` is excluded from this check: it's a schemaless\n// `Dict[str, Any]` on the backend, which openapi-typescript can only infer\n// as `Record<string, never>` (an empty object) - a known tooling\n// imprecision (same class as shipping_address/variant_details elsewhere),\n// not a real type mismatch, so it would fail this check even when correct.\ntype _PickupLocationsMatchesSchema = Omit<PickupLocationsResult['locations'][number], 'operating_hours'> extends Omit<components['schemas']['PickupLocationItem'], 'operating_hours'> ? true : never\ntype _ReverseGeocodeMatchesSchema = ReverseGeocodeResult extends components['schemas']['ReverseGeocodeResponse'] ? true : never\ntype _PlusCodeDecodeMatchesSchema = PlusCodeDecodeResult extends components['schemas']['PlusCodeDecodeResponse'] ? true : never\ntype _AddressAutocompleteMatchesSchema = AddressAutocompleteResult extends components['schemas']['AddressAutocompleteResponse'] ? true : never\nconst _pickupLocationsCheck: _PickupLocationsMatchesSchema = true\nconst _reverseGeocodeCheck: _ReverseGeocodeMatchesSchema = true\nconst _plusCodeDecodeCheck: _PlusCodeDecodeMatchesSchema = true\nconst _addressAutocompleteCheck: _AddressAutocompleteMatchesSchema = true\nvoid _pickupLocationsCheck\nvoid _reverseGeocodeCheck\nvoid _plusCodeDecodeCheck\nvoid _addressAutocompleteCheck\n\n// Service object for backward compatibility\nexport const logisticsService = {\n getShippingRates,\n validateShippingAddress,\n listPickupLocations,\n listBusinessLocations,\n reverseGeocode,\n decodePlusCode,\n autocompleteAddress,\n}\n","/**\n * Bespoke Service\n *\n * Handles bespoke product availability checks and the buyer side of the\n * bespoke order deliverable proofing flow.\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { BespokeAvailability, BespokeDeliverableStatus } from '../types/consultations'\nimport type { components } from '../generated/store-openapi'\nimport { apiRequest, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\n// ─── Codegen drift-proofs (openapi/README.md — regenerate via `pnpm run codegen:rest`) ─\n// Same approach as service-booking.service.ts's own comment: these prove\n// the hand-written types still match the real backend schema at compile\n// time, without a risky full rewrite of working code. Found and fixed one\n// real gap this way: BespokeDeliverableStatus was missing\n// bespoke_revision_notes entirely, a field the real backend has always\n// returned.\ntype _BespokeAvailabilityMatchesSchema = BespokeAvailability extends components['schemas']['BespokeAvailabilityResponse'] ? true : never\ntype _BespokeDeliverableStatusMatchesSchema = BespokeDeliverableStatus extends components['schemas']['BespokeStatusResponse'] ? true : never\nconst _bespokeAvailabilityCheck: _BespokeAvailabilityMatchesSchema = true\nconst _bespokeDeliverableStatusCheck: _BespokeDeliverableStatusMatchesSchema = true\nvoid _bespokeAvailabilityCheck\nvoid _bespokeDeliverableStatusCheck\n\n/**\n * REAL BUG FIXED (2026-09-20): was calling `/bespoke/availability/{id}` —\n * missing the `/capacity` segment. Confirmed against the real router\n * (kasuvia-store-management/app/api/v1/endpoints/bespoke/capacity.py:184,\n * registered under the `/bespoke/capacity` prefix): the real route is\n * `/bespoke/capacity/availability/{id}`. Every bespoke availability check\n * was 404ing.\n */\nexport async function checkAvailability(config: SdkConfig, product_id: string): Promise<BespokeAvailability> {\n return apiRequest<BespokeAvailability>(`${config.backendUrls.store}/bespoke/capacity/availability/${product_id}`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to check bespoke availability',\n })\n}\n\n/**\n * POST /orders/{order_id}/bespoke/approve — buyer approves the seller's\n * submitted deliverable, starting the escrow release clock.\n */\nexport async function approveBespokeDeliverable(\n config: SdkConfig,\n accessToken: string,\n orderId: string\n): Promise<BespokeDeliverableStatus> {\n return apiRequest<BespokeDeliverableStatus>(`${config.backendUrls.store}/orders/${orderId}/bespoke/approve`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({}),\n fallbackErrorMessage: 'Failed to approve deliverable',\n })\n}\n\n/**\n * POST /orders/{order_id}/bespoke/request-revision — buyer asks the seller\n * to revise the submitted deliverable. Capped at 2 revisions server-side;\n * beyond that, the backend escalates to manual review rather than refusing\n * silently (see the real endpoint's own doc comment).\n */\nexport async function requestBespokeRevision(\n config: SdkConfig,\n accessToken: string,\n orderId: string,\n notes: string\n): Promise<BespokeDeliverableStatus> {\n return apiRequest<BespokeDeliverableStatus>(`${config.backendUrls.store}/orders/${orderId}/bespoke/request-revision`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify({ notes }),\n fallbackErrorMessage: 'Failed to request revision',\n })\n}\n\n// Service object export for backward compatibility\nexport const bespokeService = {\n checkAvailability,\n approveBespokeDeliverable,\n requestBespokeRevision,\n}\n","/**\n * Service Booking Service\n *\n * Handles service appointments (bookings) and their milestone/escrow\n * sub-resource. Stateless - all configuration passed as parameters.\n *\n * REAL BUGS FIXED (2026-09-20) — every function in this file was rewritten\n * against the real backend (kasuvia-store-management/app/api/v1/endpoints/\n * service/bookings.py, app/schemas/service.py). Before this fix:\n * - getAvailableSlots called a nonexistent route (/service/available-slots/\n * {id}) with the wrong params (date_from/date_to) — the real route is\n * GET /catalog/products/{id}/available-slots?date=..., a single date.\n * - bookAppointment POSTed to a nonexistent route (/service/appointments/)\n * — the real route is POST /service/bookings/schedule.\n * - getAppointments typed its result as a plain array, but the real\n * response is the standard Kasuvia paginated envelope\n * ({results,count,page,page_size,total_pages}) — this was a CONFIRMED\n * LIVE CRASH: DashboardClient.tsx/DashboardAppointments.tsx called\n * .length/.filter() directly on the envelope object.\n * - cancelAppointment sent DELETE /service/bookings/{id} — that route is\n * owner/staff-only (require_permission(\"services:manage\")), so a\n * customer got a 403; the real customer route is POST .../{id}/cancel.\n * It also never checked response.ok at all, silently swallowing failures.\n * - getDeliverables/approveDeliverable/requestRevision referenced a\n * \"/service/projects/{order_id}/deliverables/...\" resource that does not\n * exist anywhere in the codebase — replaced with the real milestone\n * endpoints (a different resource: escrow-style payment milestones on\n * a booking, not free-form deliverable files).\n * - No coverage existed for reschedule, dispute, or buyer-confirm — all\n * real, customer-facing routes.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n ServiceAppointment,\n ServiceAppointmentCreatePayload,\n CancelAppointmentPayload,\n RescheduleAppointmentPayload,\n DisputeAppointmentPayload,\n ConfirmAppointmentPayload,\n AvailableSlotsResponse,\n ServiceMilestone,\n ApproveMilestonePayload,\n} from '../types/services'\nimport type { components } from '../generated/store-openapi'\nimport { apiRequest, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\n\n// ─── Codegen drift-proofs (openapi/README.md — regenerate via `pnpm run codegen:rest`) ─\n// Unlike order.service.ts, this file's hand-written types (types/services/\n// index.ts) were already verified field-for-field correct against the real\n// backend Pydantic schemas (see that file's own header comment) - full\n// replacement would only add risk for zero gain. These type-level\n// assignments instead prove the match at compile time: if the real backend\n// schema ever adds/renames/retypes a field these three interfaces declare,\n// the corresponding line below fails to compile immediately (at `pnpm run\n// codegen:rest` + `tsc` time), the same drift-detection value Workstream 1\n// already proved for the GraphQL side, without touching working code.\n// (One real drift WAS found and fixed this way: ServiceMilestone.amount\n// was typed `number` but the real field is a Decimal-as-string.)\ntype _ServiceAppointmentMatchesSchema = ServiceAppointment extends components['schemas']['ServiceBookingResponse'] ? true : never\ntype _AvailableSlotsResponseMatchesSchema = AvailableSlotsResponse extends components['schemas']['AvailableSlotsResponse'] ? true : never\ntype _ServiceMilestoneMatchesSchema = ServiceMilestone extends components['schemas']['ServiceMilestoneResponse'] ? true : never\nconst _serviceAppointmentCheck: _ServiceAppointmentMatchesSchema = true\nconst _availableSlotsCheck: _AvailableSlotsResponseMatchesSchema = true\nconst _serviceMilestoneCheck: _ServiceMilestoneMatchesSchema = true\nvoid _serviceAppointmentCheck\nvoid _availableSlotsCheck\nvoid _serviceMilestoneCheck\n\n/** Standard Kasuvia pagination envelope — matches app/core/pagination.py's PaginatedResponse exactly. */\nexport interface ServiceBookingsPage {\n results: ServiceAppointment[]\n count: number\n page: number\n page_size: number\n total_pages: number\n}\n\n/**\n * GET /catalog/products/{product_id}/available-slots — real \"what times are\n * open\" for a SERVICE product on one date. `serviceable: false` means the\n * business has no/ambiguous location config for this product (check\n * `reason`); `available_slots` is always empty in that case, not an error.\n */\nexport async function getAvailableSlots(\n config: SdkConfig,\n productId: string,\n date: string,\n params?: { staffId?: string; locationId?: string; customerLatitude?: number; customerLongitude?: number }\n): Promise<AvailableSlotsResponse> {\n const query = new URLSearchParams({ date })\n if (params?.staffId) query.set('staff_id', params.staffId)\n if (params?.locationId) query.set('location_id', params.locationId)\n if (params?.customerLatitude !== undefined) query.set('customer_latitude', String(params.customerLatitude))\n if (params?.customerLongitude !== undefined) query.set('customer_longitude', String(params.customerLongitude))\n\n return apiRequest<AvailableSlotsResponse>(\n `${config.backendUrls.store}/catalog/products/${productId}/available-slots?${query.toString()}`,\n {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get available slots',\n }\n )\n}\n\n/** POST /service/bookings/schedule */\nexport async function bookAppointment(\n config: SdkConfig,\n accessToken: string,\n payload: ServiceAppointmentCreatePayload\n): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/schedule`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to book appointment',\n })\n}\n\n/** GET /service/bookings/my — paginated. */\nexport async function getAppointments(\n config: SdkConfig,\n accessToken: string,\n params?: { status?: ServiceAppointment['status']; page?: number; page_size?: number }\n): Promise<ServiceBookingsPage> {\n const query = new URLSearchParams()\n if (params?.status) query.set('status', params.status)\n if (params?.page) query.set('page', String(params.page))\n if (params?.page_size) query.set('page_size', String(params.page_size))\n\n return apiRequest<ServiceBookingsPage>(`${config.backendUrls.store}/service/bookings/my?${query.toString()}`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to get appointments',\n })\n}\n\n/**\n * GET /service/bookings/{id} — customer-reachable single-booking lookup,\n * used by the paginated list's detail view (PATCH .../{id} is a separate,\n * owner/staff-only route).\n *\n * REAL BUG FIXED (2026-09-22): this call shape was already correct, but the\n * backend route it targeted didn't exist at all — `ServiceBookingRepository\n * .get_by_id_and_business` was used internally by every merchant action\n * (cancel/reschedule/dispute/assign/etc.) but never exposed as a customer\n * GET route. Every real call to `AppointmentDetail.tsx` (via `useAppointment`)\n * 404'd. Fixed by adding `GET /{booking_id}` to kasuvia-store-management's\n * `service/bookings.py` (customer_id-scoped, same pattern as\n * `customer_cancel_booking` — service bookings have no guest-checkout path,\n * so no guest_email fallback is needed here unlike orders).\n */\nexport async function getAppointment(config: SdkConfig, accessToken: string, id: string): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/${id}`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to get appointment',\n })\n}\n\n/** POST /service/bookings/{id}/cancel — the real customer-cancel route (DELETE .../{id} is owner/staff-only). */\nexport async function cancelAppointment(\n config: SdkConfig,\n accessToken: string,\n id: string,\n payload?: CancelAppointmentPayload\n): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/${id}/cancel`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload ?? {}),\n fallbackErrorMessage: 'Failed to cancel appointment',\n })\n}\n\n/** POST /service/bookings/{id}/reschedule — subject to the same cancellation_window_hours as a cancel. */\nexport async function rescheduleAppointment(\n config: SdkConfig,\n accessToken: string,\n id: string,\n payload: RescheduleAppointmentPayload\n): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/${id}/reschedule`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to reschedule appointment',\n })\n}\n\n/** POST /service/bookings/{id}/dispute — freezes the escrow auto-release timer; requires a real reason. */\nexport async function disputeAppointment(\n config: SdkConfig,\n accessToken: string,\n id: string,\n payload: DisputeAppointmentPayload\n): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/${id}/dispute`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to open dispute',\n })\n}\n\n/** POST /service/bookings/{id}/confirm — buyer confirms the service was completed. */\nexport async function confirmAppointmentCompletion(\n config: SdkConfig,\n accessToken: string,\n id: string,\n payload?: ConfirmAppointmentPayload\n): Promise<ServiceAppointment> {\n return apiRequest<ServiceAppointment>(`${config.backendUrls.store}/service/bookings/${id}/confirm`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload ?? {}),\n fallbackErrorMessage: 'Failed to confirm completion',\n })\n}\n\n/** GET /service/bookings/{id}/milestones — escrow-style payment milestones for a milestone-based booking. */\nexport async function getMilestones(config: SdkConfig, accessToken: string, bookingId: string): Promise<ServiceMilestone[]> {\n return apiRequest<ServiceMilestone[]>(`${config.backendUrls.store}/service/bookings/${bookingId}/milestones`, {\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to get milestones',\n })\n}\n\n/** POST /service/bookings/{id}/milestones/{milestone_id}/approve — buyer approves a submitted milestone, triggering escrow release. */\nexport async function approveMilestone(\n config: SdkConfig,\n accessToken: string,\n bookingId: string,\n milestoneId: string,\n payload?: ApproveMilestonePayload\n): Promise<ServiceMilestone> {\n return apiRequest<ServiceMilestone>(\n `${config.backendUrls.store}/service/bookings/${bookingId}/milestones/${milestoneId}/approve`,\n {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(payload ?? {}),\n fallbackErrorMessage: 'Failed to approve milestone',\n }\n )\n}\n\n// Service object export for backward compatibility\nexport const serviceBookingService = {\n getAvailableSlots,\n bookAppointment,\n getAppointments,\n getAppointment,\n cancelAppointment,\n rescheduleAppointment,\n disputeAppointment,\n confirmAppointmentCompletion,\n getMilestones,\n approveMilestone,\n}\n","/**\n * Notification Service\n *\n * Handles contact form submissions, email notifications, and notification\n * channel preferences (customer self-service + merchant-level policy).\n * Stateless - all configuration passed as parameters.\n */\nimport type { SdkConfig } from '../config'\nimport type { NotificationPreferences } from '../types/auth'\nimport { apiRequest, storefrontHeaders, JSON_HEADERS } from '../utils/http-client'\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}\n\nfunction bearerHeaders(accessToken: string): Record<string, string> {\n return { Authorization: `Bearer ${accessToken}` }\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 return apiRequest<{ detail: string }>(`${config.backendUrls.notifications}/contact/send-contact-email`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to send contact email',\n })\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: ContactFormData\n): Promise<{ detail: string }> {\n return apiRequest<{ detail: string }>(`${config.backendUrls.notifications}/contact/send-contact-confirmation`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...storefrontHeaders(config) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to send contact confirmation',\n })\n}\n\n/**\n * Get the caller's own notification preferences (customer or business\n * owner self-service — whoever's access token is passed).\n * GET /notifications/preferences/\n */\nexport async function getNotificationPreferences(\n config: SdkConfig,\n accessToken: string\n): Promise<NotificationPreferences> {\n return apiRequest<NotificationPreferences>(`${config.backendUrls.notifications}/notifications/preferences/`, {\n headers: bearerHeaders(accessToken),\n fallbackErrorMessage: 'Failed to fetch notification preferences',\n })\n}\n\n/**\n * Update the caller's own notification preferences.\n * PATCH /notifications/preferences/\n */\nexport async function updateNotificationPreferences(\n config: SdkConfig,\n accessToken: string,\n payload: Partial<NotificationPreferences>\n): Promise<NotificationPreferences> {\n return apiRequest<NotificationPreferences>(`${config.backendUrls.notifications}/notifications/preferences/`, {\n method: 'PATCH',\n headers: { ...JSON_HEADERS, ...bearerHeaders(accessToken) },\n body: JSON.stringify(payload),\n fallbackErrorMessage: 'Failed to update notification preferences',\n })\n}\n\n// ── Push subscriptions ───────────────────────────────────────────────────\n// REAL FEATURE WIRED (2026-09-21): kasuvia-notification-system-go's push.go\n// (VAPID key, subscribe/unsubscribe, device list) already works correctly\n// for both owner/staff and customer callers (role-branched server-side) but\n// had zero SDK coverage. Auth here is JWT-bearer-only (AuthMiddleware —\n// no X-Storefront-Key/X-Business-ID requirement), matching\n// getNotificationPreferences above.\n\nexport interface VapidPublicKeyResponse {\n public_key: string\n subject: string\n}\n\nexport interface PushSubscriptionKeys {\n p256dh: string\n auth: string\n}\n\nexport interface SubscribeToPushParams {\n subscription: {\n endpoint: string\n keys: PushSubscriptionKeys\n }\n user_agent: string\n}\n\nexport async function getVapidPublicKey(config: SdkConfig): Promise<VapidPublicKeyResponse> {\n return apiRequest<VapidPublicKeyResponse>(`${config.backendUrls.notifications}/push/vapid-public-key`, {\n fallbackErrorMessage: 'Failed to fetch VAPID public key',\n })\n}\n\nexport async function subscribeToPush(\n config: SdkConfig,\n accessToken: string,\n params: SubscribeToPushParams\n): Promise<{ status: string; subscription_id: string; vapid_key_version: number }> {\n return apiRequest(`${config.backendUrls.notifications}/push/subscribe`, {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...bearerHeaders(accessToken) },\n body: JSON.stringify(params),\n fallbackErrorMessage: 'Failed to subscribe to push notifications',\n })\n}\n\nexport async function unsubscribeFromPush(\n config: SdkConfig,\n accessToken: string,\n endpoint: string\n): Promise<{ status: string }> {\n return apiRequest(`${config.backendUrls.notifications}/push/subscribe`, {\n method: 'DELETE',\n headers: { ...JSON_HEADERS, ...bearerHeaders(accessToken) },\n body: JSON.stringify({ endpoint }),\n fallbackErrorMessage: 'Failed to unsubscribe from push notifications',\n })\n}\n\n// ── Notification inbox ──────────────────────────────────────────────────\n// REAL FEATURE WIRED (2026-09-21): kasuvia-notification-system-go's\n// notification_inbox.go (list/mark-read/mark-all-read/click) — fixed\n// alongside this to actually work for a customer caller (see that file's\n// own doc comments: it used to always query/check by user_id, which a\n// customer-facing notification never has set).\n\nexport type NotificationPriority = 'urgent' | 'normal' | 'low'\n\nexport interface NotificationInboxItem {\n id: string\n title: string\n body: string\n icon_url?: string | null\n image_url?: string | null\n priority: NotificationPriority\n action_type?: string | null\n action_url?: string | null\n entity_id?: string | null\n entity_type?: string | null\n category: string\n source_event_type: string\n read: boolean\n read_at?: string | null\n clicked: boolean\n clicked_at?: string | null\n action_performed: boolean\n created_at: string\n expires_at?: string | null\n}\n\nexport interface NotificationInboxResponse {\n results: NotificationInboxItem[]\n count: number\n page: number\n page_size: number\n total_pages: number\n}\n\nexport async function getNotificationInbox(\n config: SdkConfig,\n accessToken: string,\n params?: { page?: number; limit?: number; unread_only?: boolean }\n): Promise<NotificationInboxResponse> {\n const query = new URLSearchParams()\n if (params?.page) query.set('page', String(params.page))\n if (params?.limit) query.set('limit', String(params.limit))\n if (params?.unread_only) query.set('unread_only', 'true')\n return apiRequest<NotificationInboxResponse>(`${config.backendUrls.notifications}/notifications?${query.toString()}`, {\n headers: bearerHeaders(accessToken),\n fallbackErrorMessage: 'Failed to fetch notifications',\n })\n}\n\nexport async function markNotificationRead(\n config: SdkConfig,\n accessToken: string,\n notificationId: string\n): Promise<{ status: string }> {\n return apiRequest(`${config.backendUrls.notifications}/notifications/${notificationId}/read`, {\n method: 'POST',\n headers: bearerHeaders(accessToken),\n fallbackErrorMessage: 'Failed to mark notification as read',\n })\n}\n\nexport async function markAllNotificationsRead(\n config: SdkConfig,\n accessToken: string\n): Promise<{ status: string }> {\n return apiRequest(`${config.backendUrls.notifications}/notifications/mark-all-read`, {\n method: 'POST',\n headers: bearerHeaders(accessToken),\n fallbackErrorMessage: 'Failed to mark all notifications as read',\n })\n}\n\nexport async function trackNotificationClick(\n config: SdkConfig,\n accessToken: string,\n notificationId: string\n): Promise<{ status: string }> {\n return apiRequest(`${config.backendUrls.notifications}/notifications/${notificationId}/click`, {\n method: 'POST',\n headers: bearerHeaders(accessToken),\n fallbackErrorMessage: 'Failed to track notification click',\n })\n}\n\nexport const notificationsService = {\n sendContactEmail,\n sendContactConfirmation,\n getNotificationPreferences,\n updateNotificationPreferences,\n getVapidPublicKey,\n subscribeToPush,\n unsubscribeFromPush,\n getNotificationInbox,\n markNotificationRead,\n markAllNotificationsRead,\n trackNotificationClick,\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'\nimport { apiRequest, storefrontHeaders } from '../utils/http-client'\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 return apiRequest<SupportedLanguagesResponse>(`${config.backendUrls.payment}/config/supported-languages`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get supported languages',\n })\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 return apiRequest<SupportedCurrenciesResponse>(`${config.backendUrls.payment}/config/supported-currencies`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get supported currencies',\n })\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 return apiRequest<BusinessConfig>(`${config.backendUrls.auth}/internal/businesses/${config.businessId}/`, {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get business config',\n })\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 *\n * REAL BUG FIXED (2026-09-21), live-reproduced: every URL here used\n * `config.businessId` (the public BID, e.g. \"B-2W9EC07\") as the\n * `{business_id}` path segment. kasuvia-cms's SDK routes\n * (`app/core/security/base.py`'s `get_storefront_business_uuid`, used by\n * every route in `cms_sdk.py`) explicitly require the INTERNAL UUID there —\n * \"CmsModel/CmsEntry documents are keyed by the UUID business_id... SDK\n * routes need this, not the BID\" (its own docstring) — and 403s with\n * \"Business ID mismatch\" on anything else. Every CMS entry call from the\n * storefront has been failing since the feature was built. Fixed by\n * requiring an explicit `businessUuid` parameter (resolved via\n * `getBusinessConfig`'s real `business_id` field, cached by\n * `useBusinessConfig()` at the hook layer) instead of silently reusing the\n * wrong config field.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n CmsEntry,\n CmsEntryListResponse,\n CreateCmsEntryParams,\n UpdateCmsEntryParams,\n ListCmsEntriesParams,\n} from '../types/cms'\nimport { apiRequest, storefrontHeaders, authHeaders, JSON_HEADERS } from '../utils/http-client'\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 businessUuid: string,\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 return apiRequest<CmsEntryListResponse>(\n `${config.backendUrls.cms}/sdk/${businessUuid}/${modelSlug}/entries?${queryParams.toString()}`,\n {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to list CMS entries',\n }\n )\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 businessUuid: string,\n modelSlug: string,\n entryId: string\n): Promise<CmsEntry> {\n return apiRequest<CmsEntry>(\n `${config.backendUrls.cms}/sdk/${businessUuid}/${modelSlug}/entries/${entryId}`,\n {\n headers: storefrontHeaders(config),\n fallbackErrorMessage: 'Failed to get CMS entry',\n }\n )\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 businessUuid: string,\n accessToken: string,\n modelSlug: string,\n params: CreateCmsEntryParams\n): Promise<CmsEntry> {\n return apiRequest<CmsEntry>(\n `${config.backendUrls.cms}/sdk/${businessUuid}/${modelSlug}/entries`,\n {\n method: 'POST',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(params),\n fallbackErrorMessage: 'Failed to create CMS entry',\n }\n )\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 businessUuid: string,\n accessToken: string,\n modelSlug: string,\n entryId: string,\n params: UpdateCmsEntryParams\n): Promise<CmsEntry> {\n return apiRequest<CmsEntry>(\n `${config.backendUrls.cms}/sdk/${businessUuid}/${modelSlug}/entries/${entryId}`,\n {\n method: 'PUT',\n headers: { ...JSON_HEADERS, ...authHeaders(config, accessToken) },\n body: JSON.stringify(params),\n fallbackErrorMessage: 'Failed to update CMS entry',\n }\n )\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 businessUuid: string,\n accessToken: string,\n modelSlug: string,\n entryId: string\n): Promise<void> {\n await apiRequest(\n `${config.backendUrls.cms}/sdk/${businessUuid}/${modelSlug}/entries/${entryId}`,\n {\n method: 'DELETE',\n headers: authHeaders(config, accessToken),\n fallbackErrorMessage: 'Failed to delete CMS entry',\n }\n )\n}\n","/**\n * Legal Service\n *\n * Fetches this business's own currently-active storefront legal document\n * (Terms, Privacy, or Refund Policy) from kasuvia-cms — public, no auth,\n * the same endpoint the registration flow's consent record is checked against\n * (see kasuvia-auth's CustomerTermsAcceptance).\n *\n * website-builder-system auto-generates storefront_terms/storefront_privacy\n * the first time a business publishes (_ensure_storefront_legal_documents).\n * A business that hasn't published yet, or whose auto-generation failed,\n * genuinely has none yet. Returns null in that case rather than throwing;\n * the page decides how to render that honestly — never substituting placeholder\n * text for real legal text.\n */\nimport type { SdkConfig } from '../config';\nimport type { MerchantLegalDocument } from '../types/cms/legal';\n\nexport type { MerchantLegalDocument };\nexport type { LegalSection } from '../types/cms/legal';\n\n/**\n * Fetch a storefront legal document from kasuvia-cms.\n *\n * REAL BUG FIXED (2026-09-22): took a raw `cmsBaseUrl` string instead of\n * `SdkConfig` — the only function across this SDK's ~90 service functions\n * that broke that convention, which is exactly why kasuvia-storefront's\n * `lib/legal.ts` wrapper existed at all (bridging this one odd signature\n * back to the app's real config). `businessUuid` is kept as its own\n * explicit parameter rather than silently reading `config.businessId`:\n * this real backend route (`GET /cms/legal/storefront/{business_id}/...`,\n * confirmed against kasuvia-cms's `get_business_id` dependency and\n * `MerchantLegalDocument.business_id` field) is keyed by the internal\n * business UUID, never the public BID `config.businessId` actually is —\n * the same UUID-vs-BID class of bug already found and fixed in\n * `cms.service.ts`. Resolve it the same way (`useBusinessConfig`'s real\n * `business_id` field) before calling this.\n *\n * @param config - SdkConfig; only `backendUrls.cms` is read from it here.\n * @param businessUuid - The tenant's real business UUID (not the public BID).\n * @param documentType - e.g. \"storefront_terms\", \"storefront_privacy\",\n * \"storefront_refund_policy\"\n * @param fetchOptions - Optional native fetch options (e.g. Next.js `next: { revalidate }`)\n */\nexport async function getMerchantLegalDocument(\n config: SdkConfig,\n businessUuid: string,\n documentType: string,\n fetchOptions?: RequestInit,\n): Promise<MerchantLegalDocument | null> {\n if (!businessUuid || !config?.backendUrls?.cms) return null;\n try {\n const res = await fetch(\n `${config.backendUrls.cms}/cms/legal/storefront/${businessUuid}/${documentType}`,\n fetchOptions,\n );\n if (!res.ok) return null;\n return (await res.json()) as MerchantLegalDocument;\n } catch {\n return null;\n }\n}\n","/**\n * Review and Comment Service\n *\n * Handles review and comment operations using REST API.\n * Stateless - all configuration passed as parameters.\n *\n * REAL BUG FIXED (2026-09-21): every URL here hardcoded a literal `/api/v1`\n * prefix AND used a completely different path shape than the real\n * kasuvia-crm-go backend (`kasuvia-crm-go/internal/api/v1/endpoints/\n * reviews.go` + `admin_reviews.go`) — e.g. `POST /api/v1/reviews/comments`\n * vs the real `POST /api/v1/comments`, `GET /api/v1/reviews/products/{id}`\n * vs the real `GET /api/v1/products/{id}/reviews`. Every function 404'd.\n * `config.backendUrls.crm` already includes `/api/v1` (same convention as\n * every other backendUrls.* entry — see payment.service.ts/order.service.ts)\n * so the hardcoded prefix also risked doubling to `/api/v1/api/v1/...` once\n * KASUVIA_CRM_URL was actually set.\n */\nimport type { SdkConfig } from '../config'\nimport type {\n Review, Comment, ReviewCreate, ReviewUpdate, CommentCreate, CommentUpdate,\n MerchantReplyCreate, ReviewModerationAction, CommentModerationAction,\n ProductReviewsResponse, ProductCommentsResponse\n} from '../types/reviews'\nimport { apiRequest, JSON_HEADERS, type ApiRequestOptions } from '../utils/http-client'\n\nexport type {\n Review, Comment, ReviewCreate, ReviewUpdate, CommentCreate, CommentUpdate,\n MerchantReplyCreate, ReviewModerationAction, CommentModerationAction,\n ProductReviewsResponse, ProductCommentsResponse\n}\n\n/**\n * This service takes its identity from `config.authToken`/`config.\n * storefrontApiKey`/`config.businessId` directly (unlike every other SDK\n * service, which takes an explicit `accessToken` parameter) - preserved as-\n * is here since callers (use-reviews.ts) already depend on this exact\n * calling convention; only the underlying transport moved onto the shared\n * client.\n */\nfunction fetchWithConfig<T>(url: string, config: SdkConfig, options: ApiRequestOptions = {}): Promise<T> {\n const headers: Record<string, string> = {\n ...JSON_HEADERS,\n Accept: 'application/json',\n ...(options.headers as Record<string, string> | undefined),\n }\n if (config.storefrontApiKey) headers['X-Storefront-Key'] = config.storefrontApiKey\n if (config.businessId) headers['X-Business-ID'] = config.businessId\n if (config.authToken) headers['Authorization'] = `Bearer ${config.authToken}`\n\n return apiRequest<T>(url, { ...options, headers, fallbackErrorMessage: options.fallbackErrorMessage ?? 'Request failed' })\n}\n\n/**\n * Create a new review\n */\nexport async function createReview(\n reviewData: ReviewCreate,\n config: SdkConfig\n): Promise<Review> {\n const url = `${config.backendUrls.crm}/reviews`\n return fetchWithConfig<Review>(url, config, {\n method: 'POST',\n body: JSON.stringify(reviewData),\n fallbackErrorMessage: 'Failed to create review',\n })\n}\n\n/**\n * Update an existing review\n */\nexport async function updateReview(\n reviewId: string,\n reviewData: ReviewUpdate,\n config: SdkConfig\n): Promise<Review> {\n const url = `${config.backendUrls.crm}/reviews/${reviewId}`\n return fetchWithConfig<Review>(url, config, {\n method: 'PUT',\n body: JSON.stringify(reviewData),\n fallbackErrorMessage: 'Failed to update review',\n })\n}\n\n/**\n * Get paginated reviews for a product\n */\nexport async function getProductReviews(\n productId: string,\n params: { page?: number; page_size?: number; moderation_status?: string } = {},\n config: SdkConfig\n): Promise<ProductReviewsResponse> {\n const queryParams = new URLSearchParams()\n if (params.page) queryParams.append('page', params.page.toString())\n if (params.page_size) queryParams.append('page_size', params.page_size.toString())\n if (params.moderation_status) queryParams.append('moderation_status', params.moderation_status)\n\n const url = `${config.backendUrls.crm}/products/${productId}/reviews?${queryParams.toString()}`\n return fetchWithConfig<ProductReviewsResponse>(url, config, { fallbackErrorMessage: 'Failed to fetch product reviews' })\n}\n\n/**\n * Create a new comment\n */\nexport async function createComment(\n commentData: CommentCreate,\n config: SdkConfig\n): Promise<Comment> {\n const url = `${config.backendUrls.crm}/comments`\n return fetchWithConfig<Comment>(url, config, {\n method: 'POST',\n body: JSON.stringify(commentData),\n fallbackErrorMessage: 'Failed to create comment',\n })\n}\n\n/**\n * Update an existing comment\n */\nexport async function updateComment(\n commentId: string,\n commentData: CommentUpdate,\n config: SdkConfig\n): Promise<Comment> {\n const url = `${config.backendUrls.crm}/comments/${commentId}`\n return fetchWithConfig<Comment>(url, config, {\n method: 'PUT',\n body: JSON.stringify(commentData),\n fallbackErrorMessage: 'Failed to update comment',\n })\n}\n\n/**\n * Get paginated comments for a product\n */\nexport async function getProductComments(\n productId: string,\n params: { page?: number; page_size?: number; moderation_status?: string } = {},\n config: SdkConfig\n): Promise<ProductCommentsResponse> {\n const queryParams = new URLSearchParams()\n if (params.page) queryParams.append('page', params.page.toString())\n if (params.page_size) queryParams.append('page_size', params.page_size.toString())\n if (params.moderation_status) queryParams.append('moderation_status', params.moderation_status)\n\n const url = `${config.backendUrls.crm}/products/${productId}/comments?${queryParams.toString()}`\n return fetchWithConfig<ProductCommentsResponse>(url, config, { fallbackErrorMessage: 'Failed to fetch product comments' })\n}\n\n/**\n * Get pending reviews for moderation (merchant/staff only)\n */\nexport async function getPendingReviews(config: SdkConfig): Promise<Review[]> {\n const url = `${config.backendUrls.crm}/admin/reviews/pending`\n return fetchWithConfig<Review[]>(url, config, { fallbackErrorMessage: 'Failed to fetch pending reviews' })\n}\n\n/**\n * Get pending comments for moderation (merchant/staff only)\n */\nexport async function getPendingComments(config: SdkConfig): Promise<Comment[]> {\n const url = `${config.backendUrls.crm}/admin/comments/pending`\n return fetchWithConfig<Comment[]>(url, config, { fallbackErrorMessage: 'Failed to fetch pending comments' })\n}\n\n/**\n * Moderate a review (approve/reject) - merchant/staff only\n */\nexport async function moderateReview(\n reviewId: string,\n action: ReviewModerationAction,\n config: SdkConfig\n): Promise<Review> {\n const url = `${config.backendUrls.crm}/admin/reviews/${reviewId}/moderate`\n return fetchWithConfig<Review>(url, config, {\n method: 'POST',\n body: JSON.stringify(action),\n fallbackErrorMessage: 'Failed to moderate review',\n })\n}\n\n/**\n * Moderate a comment (approve/reject) - merchant/staff only\n */\nexport async function moderateComment(\n commentId: string,\n action: CommentModerationAction,\n config: SdkConfig\n): Promise<Comment> {\n const url = `${config.backendUrls.crm}/admin/comments/${commentId}/moderate`\n return fetchWithConfig<Comment>(url, config, {\n method: 'POST',\n body: JSON.stringify(action),\n fallbackErrorMessage: 'Failed to moderate comment',\n })\n}\n\n/**\n * Post a merchant reply to a review - merchant/staff only\n */\nexport async function merchantReplyToReview(\n reviewId: string,\n replyData: MerchantReplyCreate,\n config: SdkConfig\n): Promise<Review> {\n const url = `${config.backendUrls.crm}/admin/reviews/${reviewId}/reply`\n return fetchWithConfig<Review>(url, config, {\n method: 'POST',\n body: JSON.stringify(replyData),\n fallbackErrorMessage: 'Failed to post merchant reply',\n })\n}\n","/**\n * Media Upload Service\n *\n * The real 3-step direct-to-R2 upload orchestration (presigned URL → PUT →\n * confirm) that a browser client actually needs to run. Distinct from\n * `auth.service.ts`'s `getPresignedUploadUrl`/`confirmMediaUpload`, which\n * take an explicit bearer `accessToken` and are meant for server-side use\n * (Next.js Route Handlers reading a customer's httpOnly cookie) — a \"use\n * client\" component has no access token value in JS at all in that model,\n * only the cookie, so it calls two thin same-origin proxy routes instead\n * (`credentials: 'include'`) that wrap those same two SDK functions\n * server-side.\n *\n * REAL DUPLICATION FIXED (2026-09-22): this exact 3-step sequence had been\n * hand-written independently in two different kasuvia-storefront components\n * (BespokeStep.tsx, ProductReviews.tsx) — identical logic, copy-pasted, with\n * no shared SDK function to reuse. A second storefront project would have\n * had to write it a third time. The two endpoint paths are parameterized\n * (defaulting to the same `/api/auth/media/*` convention this storefront\n * already uses) precisely so a *different* storefront that names its proxy\n * routes differently can still use this function without a fork.\n */\nimport { apiRequest, JSON_HEADERS } from '../utils/http-client'\nimport type { MediaAsset } from '../types/media'\nimport type { PresignedUploadUrlResponse } from './auth.service'\n\nexport interface UploadMediaFileParams {\n file: File\n /** e.g. \"review\", \"digital_product\" — matches kasuvia-media-system's context_validation.py. */\n context: string\n entityId: string\n affiliation?: string\n ownerId?: string\n presignedUrlEndpoint?: string\n confirmUploadEndpoint?: string\n}\n\n/**\n * Upload one file end-to-end: request a presigned URL, PUT the file\n * directly to R2, then confirm the upload to get back a real MediaAsset.\n */\nexport async function uploadMediaFile(params: UploadMediaFileParams): Promise<MediaAsset> {\n const presignedUrlEndpoint = params.presignedUrlEndpoint ?? '/api/auth/media/presigned-url'\n const confirmUploadEndpoint = params.confirmUploadEndpoint ?? '/api/auth/media/confirm-upload'\n\n const { presigned_url, storage_path } = await apiRequest<PresignedUploadUrlResponse>(presignedUrlEndpoint, {\n method: 'POST',\n headers: JSON_HEADERS,\n credentials: 'include',\n body: JSON.stringify({\n filename: params.file.name,\n content_type: params.file.type,\n context: params.context,\n entity_id: params.entityId,\n affiliation: params.affiliation,\n owner_id: params.ownerId,\n }),\n fallbackErrorMessage: 'Could not start upload',\n })\n\n const putResponse = await fetch(presigned_url, {\n method: 'PUT',\n headers: { 'Content-Type': params.file.type },\n body: params.file,\n })\n if (!putResponse.ok) {\n throw new Error(`Failed to upload ${params.file.name}`)\n }\n\n return apiRequest<MediaAsset>(confirmUploadEndpoint, {\n method: 'POST',\n headers: JSON_HEADERS,\n credentials: 'include',\n body: JSON.stringify({\n storage_path,\n entity_id: params.entityId,\n original_filename: params.file.name,\n content_type: params.file.type,\n size: params.file.size,\n context: params.context,\n affiliation: params.affiliation,\n owner_id: params.ownerId,\n }),\n fallbackErrorMessage: `Could not confirm upload of ${params.file.name}`,\n })\n}\n\nexport interface UploadMediaFilesResult {\n assets: MediaAsset[]\n errors: { file: string; message: string }[]\n}\n\n/**\n * Upload several files, one at a time (sequential — real progress feedback\n * per file rather than an opaque Promise.all batch). A single file's\n * failure does not abort the rest: matches the original BespokeStep/\n * ProductReviews behaviour of keeping whatever succeeded before a later\n * file failed, rather than discarding it. The caller decides how to present\n * `errors` (e.g. one toast per failed filename).\n */\nexport async function uploadMediaFiles(\n files: File[],\n params: Omit<UploadMediaFileParams, 'file'>\n): Promise<UploadMediaFilesResult> {\n const assets: MediaAsset[] = []\n const errors: { file: string; message: string }[] = []\n for (const file of files) {\n try {\n assets.push(await uploadMediaFile({ ...params, file }))\n } catch (err) {\n errors.push({ file: file.name, message: err instanceof Error ? err.message : 'Upload failed' })\n }\n }\n return { assets, errors }\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","/**\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","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 { buildFullName } from \"./customer\";\nimport type { CheckoutCustomer, DeliveryAddress, Order, ShippingLocation } from \"../types\";\nimport { ProductTypeEnum, type ProductType, type CartItem } from \"../types/store\";\n\nexport function buildDeliveryAddress(customer: CheckoutCustomer, location: ShippingLocation): DeliveryAddress {\n if (!customer.first_name || !customer.last_name || !customer.phone) {\n throw new Error(\"Customer first_name, last_name, and phone are required for delivery address\");\n }\n if (!location.street || !location.city || !location.state || !location.country) {\n throw new Error(\"Location street, city, state, and country are required for delivery address\");\n }\n return {\n first_name: customer.first_name,\n last_name: customer.last_name,\n phone: customer.phone,\n street: location.street,\n city: location.city,\n state: location.state,\n lga: location.lga,\n country: location.country,\n postal: location.postal,\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?: ProductType | null;\n },\n): Order {\n const customerName = getCheckoutCustomerName(options.customer);\n\n return {\n ...order,\n customer_name: order.customer_name || customerName,\n customer_email: order.customer_email || options.customer.email,\n customerName: order.customerName || customerName,\n customerEmail: order.customerEmail || options.customer.email,\n shippingAddress:\n order.shippingAddress ??\n (options.productType === ProductTypeEnum.PHYSICAL && options.location\n ? buildDeliveryAddress(options.customer, options.location)\n : undefined),\n bespoke_brief: order.bespoke_brief ?? options.bespokeBrief,\n bespokeBrief: order.bespokeBrief ?? options.bespokeBrief,\n };\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 * format.ts\n * Comprehensive number formatting utility with multiple format styles.\n * Migrated from kasuvia-storefront to kasuvia-sdk for shared use.\n */\n\nexport type FormatStyle =\n | \"compact\" // 1000000 → \"1M\"\n | \"compact-lower\" // 1000000 → \"1m\"\n | \"compact-full\" // 1000000 → \"1 Million\"\n | \"compact-full-lower\" // 1000000 → \"1 million\"\n | \"currency\" // 1000000 → \"$1,000,000.00\"\n | \"currency-compact\" // 1000000 → \"$1M\"\n | \"decimal\" // 1000000 → \"1,000,000\"\n | \"decimal-dot\" // 1000000 → \"1.000.000\" (European style)\n | \"decimal-space\" // 1000000 → \"1 000 000\" (French/SI style)\n | \"plain\" // 1000000 → \"1000000\"\n | \"scientific\" // 1000000 → \"1.00e+6\"\n | \"ordinal\" // 1 → \"1st\", 2 → \"2nd\", etc.\n | \"percent\" // 0.75 → \"75%\"\n | \"bytes\" // 1048576 → \"1.00 MB\"\n | \"roman\"; // 14 → \"XIV\"\n\nexport interface FormatOptions {\n style?: FormatStyle;\n /** Number of decimal places (where applicable). Default: auto */\n decimals?: number;\n /** Currency symbol for \"currency\" styles. Default: \"$\" */\n currencySymbol?: string;\n /** Locale for Intl-based formatting. Default: \"en-US\" */\n locale?: string;\n /** If true, always show + sign for positive numbers */\n showSign?: boolean;\n}\n\n// ─── Thresholds ───────────────────────────────────────────────────────────────\n\nconst COMPACT_THRESHOLDS = [\n { value: 1e12, suffixUpper: \"T\", suffixLower: \"t\", full: \"Trillion\" },\n { value: 1e9, suffixUpper: \"B\", suffixLower: \"b\", full: \"Billion\" },\n { value: 1e6, suffixUpper: \"M\", suffixLower: \"m\", full: \"Million\" },\n { value: 1e3, suffixUpper: \"K\", suffixLower: \"k\", full: \"Thousand\" },\n] as const;\n\nconst BYTE_THRESHOLDS = [\n { value: 1024 ** 5, label: \"PB\" },\n { value: 1024 ** 4, label: \"TB\" },\n { value: 1024 ** 3, label: \"GB\" },\n { value: 1024 ** 2, label: \"MB\" },\n { value: 1024 ** 1, label: \"KB\" },\n] as const;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction trimDecimals(value: number, decimals?: number): string {\n if (decimals !== undefined) return value.toFixed(decimals);\n // Auto: trim unnecessary trailing zeros\n const fixed = value.toFixed(10);\n return parseFloat(fixed).toString();\n}\n\nfunction autoDecimals(value: number, defaultDecimals: number, decimals?: number): string {\n return (decimals !== undefined ? value.toFixed(decimals) : value.toFixed(defaultDecimals))\n .replace(/\\.?0+$/, \"\");\n}\n\nfunction applySign(str: string, num: number, showSign?: boolean): string {\n if (showSign && num > 0) return `+${str}`;\n return str;\n}\n\n// ─── Ordinal ──────────────────────────────────────────────────────────────────\n\nfunction toOrdinal(n: number): string {\n const abs = Math.abs(Math.round(n));\n const mod100 = abs % 100;\n const mod10 = abs % 10;\n if (mod100 >= 11 && mod100 <= 13) return `${abs}th`;\n if (mod10 === 1) return `${abs}st`;\n if (mod10 === 2) return `${abs}nd`;\n if (mod10 === 3) return `${abs}rd`;\n return `${abs}th`;\n}\n\n// ─── Roman Numerals ───────────────────────────────────────────────────────────\n\nfunction toRoman(n: number): string {\n if (n <= 0 || n > 3999 || !Number.isInteger(n)) {\n throw new RangeError(\"Roman numerals only support integers between 1 and 3999.\");\n }\n const vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];\n const syms = [\"M\", \"CM\", \"D\", \"CD\", \"C\", \"XC\", \"L\", \"XL\", \"X\", \"IX\", \"V\", \"IV\", \"I\"];\n let result = \"\";\n let remaining = n;\n for (let i = 0; i < vals.length; i++) {\n while (remaining >= vals[i]) {\n result += syms[i];\n remaining -= vals[i];\n }\n }\n return result;\n}\n\n// ─── Compact ─────────────────────────────────────────────────────────────────\n\nfunction formatCompact(\n n: number,\n suffixKey: \"suffixUpper\" | \"suffixLower\" | \"full\",\n lowerFull: boolean,\n decimals?: number,\n): string {\n const abs = Math.abs(n);\n for (const tier of COMPACT_THRESHOLDS) {\n if (abs >= tier.value) {\n const divided = n / tier.value;\n const suffix = suffixKey === \"full\"\n ? (lowerFull ? tier.full.toLowerCase() : tier.full)\n : tier[suffixKey];\n const spacer = suffixKey === \"full\" ? \" \" : \"\";\n return `${autoDecimals(divided, 2, decimals)}${spacer}${suffix}`;\n }\n }\n return trimDecimals(n, decimals ?? 0);\n}\n\n// ─── Decimal ─────────────────────────────────────────────────────────────────\n\nfunction formatDecimal(n: number, separator: string, decimalChar = \".\", decimals?: number): string {\n const fixed = decimals !== undefined ? Math.abs(n).toFixed(decimals) : Math.abs(n).toFixed(0);\n const [intPart, decPart] = fixed.split(\".\");\n const grouped = intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n const sign = n < 0 ? \"-\" : \"\";\n return decPart !== undefined ? `${sign}${grouped}${decimalChar}${decPart}` : `${sign}${grouped}`;\n}\n\n// ─── Bytes ────────────────────────────────────────────────────────────────────\n\nfunction formatBytes(n: number, decimals = 2): string {\n if (n === 0) return \"0 B\";\n const abs = Math.abs(n);\n for (const tier of BYTE_THRESHOLDS) {\n if (abs >= tier.value) {\n return `${(n / tier.value).toFixed(decimals)} ${tier.label}`;\n }\n }\n return `${n.toFixed(0)} B`;\n}\n\n// ─── Main Export ──────────────────────────────────────────────────────────────\n\n/**\n * Format a number in a variety of styles.\n *\n * @example\n * formatNumber(1_000_000) // \"1M\"\n * formatNumber(1_000_000, { style: \"compact-lower\" }) // \"1m\"\n * formatNumber(1_000_000, { style: \"compact-full\" }) // \"1 Million\"\n * formatNumber(1_000_000, { style: \"currency\" }) // \"$1,000,000.00\"\n * formatNumber(1_000_000, { style: \"decimal\" }) // \"1,000,000\"\n * formatNumber(1_234_567.89, { style: \"decimal-dot\" }) // \"1.234.567\"\n * formatNumber(0.754, { style: \"percent\" }) // \"75.4%\"\n * formatNumber(1_048_576, { style: \"bytes\" }) // \"1.00 MB\"\n * formatNumber(14, { style: \"roman\" }) // \"XIV\"\n */\nexport function formatNumber(value: number, options: FormatOptions = {}): string {\n const {\n style = \"compact\",\n decimals,\n currencySymbol = \"$\",\n locale = \"en-US\",\n showSign,\n } = options;\n\n if (!isFinite(value)) return String(value); // Handle Infinity / NaN\n\n let result: string;\n\n switch (style) {\n case \"compact\":\n result = formatCompact(value, \"suffixUpper\", false, decimals);\n break;\n\n case \"compact-lower\":\n result = formatCompact(value, \"suffixLower\", false, decimals);\n break;\n\n case \"compact-full\":\n result = formatCompact(value, \"full\", false, decimals);\n break;\n\n case \"compact-full-lower\":\n result = formatCompact(value, \"full\", true, decimals);\n break;\n\n case \"currency\": {\n const d = decimals ?? 2;\n const formatted = formatDecimal(value, \",\", \".\", d);\n result = `${currencySymbol}${formatted}`;\n break;\n }\n\n case \"currency-compact\": {\n const compact = formatCompact(Math.abs(value), \"suffixUpper\", false, decimals);\n const sign = value < 0 ? \"-\" : \"\";\n result = `${sign}${currencySymbol}${compact}`;\n break;\n }\n\n case \"decimal\":\n result = formatDecimal(value, \",\", \".\", decimals);\n break;\n\n case \"decimal-dot\":\n result = formatDecimal(value, \".\", \",\", decimals);\n break;\n\n case \"decimal-space\":\n result = formatDecimal(value, \"\\u00A0\", \".\", decimals); // non-breaking space\n break;\n\n case \"plain\":\n result = decimals !== undefined ? value.toFixed(decimals) : String(value);\n break;\n\n case \"scientific\": {\n const d = decimals ?? 2;\n result = value.toExponential(d);\n break;\n }\n\n case \"ordinal\":\n return toOrdinal(value); // sign not applicable\n\n case \"percent\": {\n const d = decimals ?? 1;\n result = `${(value * 100).toFixed(d).replace(/\\.?0+$/, \"\")}%`;\n break;\n }\n\n case \"bytes\":\n result = formatBytes(value, decimals);\n break;\n\n case \"roman\":\n return toRoman(Math.round(value)); // sign not applicable\n\n default:\n result = String(value);\n }\n\n return applySign(result, value, showSign);\n}\n\n// ─── Convenience wrappers ─────────────────────────────────────────────────────\n\n/** 1000000 → \"1M\" */\nexport const compact = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"compact\", decimals });\n\n/** 1000000 → \"1m\" */\nexport const compactLower = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"compact-lower\", decimals });\n\n/** 1000000 → \"1 Million\" */\nexport const compactFull = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"compact-full\", decimals });\n\n/** 1000000 → \"$1,000,000.00\" */\nexport const currencyFormat = (n: number, symbol = \"$\", decimals = 2) =>\n formatNumber(n, { style: \"currency\", currencySymbol: symbol, decimals });\n\n/** 1000000 → \"$1M\" */\nexport const currencyCompact = (n: number, symbol = \"$\") =>\n formatNumber(n, { style: \"currency-compact\", currencySymbol: symbol });\n\n/** 1000000 → \"1,000,000\" */\nexport const decimal = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"decimal\", decimals });\n\n/** 0.75 → \"75%\" */\nexport const percent = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"percent\", decimals });\n\n/** 1048576 → \"1.00 MB\" */\nexport const bytes = (n: number, decimals?: number) =>\n formatNumber(n, { style: \"bytes\", decimals });\n\n/** 14 → \"XIV\" */\nexport const roman = (n: number) => formatNumber(n, { style: \"roman\" });\n\n/** 1 → \"1st\", 2 → \"2nd\" */\nexport const ordinal = (n: number) => formatNumber(n, { style: \"ordinal\" });\n\n// ─── Currency Formatting (Multi-Currency Support) ─────────────────────────────\n\n/**\n * NOTE: Currency and language data should be fetched from KASUVIA_PAYMENT backend API\n * using the useSupportedLanguages hook. Do not hardcode currency values here.\n * Use the formatPrice, getCurrencySymbol, and formatCompactPrice functions with\n * currency/locale parameters from the API response.\n */\n\n/**\n * Format a bare \"HH:mm\" / \"HH:mm:ss\" time string (no date component) as a\n * human-readable 12-hour time, e.g. \"14:30:00\" -> \"2:30 PM\".\n *\n * Owner-flagged cleanup (2026-09-20): call sites needing this used to build\n * a `new Date(\\`1970-01-01T${time}\\`)` just to borrow Date's own formatting\n * — a hardcoded, arbitrary epoch date standing in for a value that was\n * never actually a date. Pure string/number parsing instead — no Date\n * object, no dependency on the JS engine's date-string parsing behavior for\n * a value with no real date component at all.\n */\nexport function formatTimeString(time: string): string {\n const [hoursStr, minutesStr] = time.split(\":\");\n const hours = parseInt(hoursStr, 10);\n if (isNaN(hours) || minutesStr === undefined) return time;\n const period = hours >= 12 ? \"PM\" : \"AM\";\n const displayHours = hours % 12 || 12;\n return `${displayHours}:${minutesStr} ${period}`;\n}\n\n/**\n * Format a price amount with currency symbol and proper decimal places.\n * Uses Intl.NumberFormat for accurate currency formatting.\n *\n * REAL BUG FIXED (2026-09-20): a missing/omitted `currency` used to\n * silently default to \"USD\" — displaying a real price with a fabricated,\n * likely WRONG currency (most Kasuvia businesses price in NGN or another\n * non-USD currency) instead of flagging that the caller never passed the\n * real one. Confirmed this is the actual reachable `formatPrice` (exported\n * via utils/index.ts + src/index.ts) that ~26 call sites across\n * kasuvia-storefront call — most of them WITHOUT a currency argument at\n * all, meaning every one of those was silently mislabeling real prices as\n * USD. Prefer `useAppContext().formatPrice` in storefront components — it\n * reads the actual business currency from real config; this stateless\n * function should only be used where a real currency is already in hand.\n *\n * @param amount - The amount to format (null/undefined returns '')\n * @param currency - ISO 4217 currency code (e.g., USD, NGN, EUR). Required —\n * there is no default; a missing value returns an explicit \"N/A\" marker\n * rather than guessing.\n * @param locale - Locale string for formatting (default: en-US)\n * @returns Formatted currency string\n */\nexport function formatPrice(\n amount: number | null | undefined,\n currency: string | null | undefined,\n locale: string = \"en-US\",\n): string {\n if (amount == null || isNaN(amount)) return \"\";\n if (!currency) return `N/A ${amount.toLocaleString()}`;\n const code = currency.toUpperCase();\n try {\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency: code,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(amount);\n } catch {\n return `${code} ${amount.toLocaleString()}`;\n }\n}\n\n/**\n * Get the currency symbol for a given currency code.\n *\n * REAL BUG FIXED (2026-09-20): a missing `currency` used to silently\n * default to \"USD\" (same class of bug as formatPrice above) — required now,\n * no default.\n *\n * @param currency - ISO 4217 currency code\n * @param locale - Locale string (default: en-US)\n * @returns Currency symbol (e.g., $, ₦, €)\n */\nexport function getCurrencySymbol(currency: string, locale: string = \"en-US\"): string {\n const formatter = new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency: currency,\n });\n const parts = formatter.formatToParts(0);\n const symbolPart = parts.find(part => part.type === \"currency\");\n return symbolPart?.value || currency;\n}\n\n/**\n * Format a price in compact notation (e.g., $1M, ₦250K).\n *\n * REAL BUG FIXED (2026-09-20): a missing `currency` used to silently\n * default to \"USD\" (same class of bug as formatPrice above) — required now,\n * no default; a missing value returns an explicit \"N/A\" marker.\n *\n * @param amount - The amount to format\n * @param currency - ISO 4217 currency code (e.g., USD, NGN, EUR)\n * @param locale - Locale string for formatting (default: en-US)\n * @returns Formatted compact currency string\n */\nexport function formatCompactPrice(\n amount: number,\n currency: string | null | undefined,\n locale: string = \"en-US\",\n): string {\n if (!currency) return `N/A ${formatNumber(amount, { style: \"compact\", decimals: 0 })}`;\n const symbol = getCurrencySymbol(currency, locale);\n const compactStr = formatNumber(amount, { style: \"compact\", decimals: 0 });\n return `${symbol}${compactStr}`;\n}\n","/**\n * Geolocation Helpers\n *\n * Helper functions for handling geolocation data including:\n * - Map pin-drop coordinate handling\n * - Plus Code input handling\n * - Reverse geocoding integration via SDK logistics service\n * - Applying an AddressAutocomplete suggestion onto ShippingLocation state\n */\n\nimport type { SdkConfig } from \"../config\";\nimport { reverseGeocode, decodePlusCode } from \"../services/logistics.service\";\nimport type { CoordinateSource, ShippingLocation } from \"../types\";\nimport type { AddressSuggestion } from \"../components/shared/AddressAutocomplete\";\nimport { logger } from \"./logger\";\n\ntype AddressUpdater = (updater: ShippingLocation | ((prev: ShippingLocation) => ShippingLocation)) => void;\n\nexport async function handlePinDrop(\n coords: { latitude: number; longitude: number },\n setAddress: AddressUpdater,\n setIsReverseGeocoding?: (loading: boolean) => void,\n config?: SdkConfig\n): Promise<void> {\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n latitude: coords.latitude,\n longitude: coords.longitude,\n coordinate_source: \"pin_drop\" as CoordinateSource,\n }));\n\n if (setIsReverseGeocoding) {\n setIsReverseGeocoding(true);\n try {\n if (config) {\n const data = await reverseGeocode(config, {\n latitude: coords.latitude,\n longitude: coords.longitude,\n });\n\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n city: data.city || prev.city,\n state: data.state || prev.state,\n country: data.country_code || prev.country,\n }));\n } else {\n logger.warn(\"[GeolocationHelper] SdkConfig is required to perform reverse geocoding.\");\n }\n } catch (error) {\n logger.error(\"[GeolocationHelper] Reverse geocoding failed:\", error);\n } finally {\n setIsReverseGeocoding(false);\n }\n }\n}\n\nexport async function handlePlusCodeChange(\n plusCode: string,\n setAddress: AddressUpdater,\n config?: SdkConfig\n): Promise<void> {\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n plus_code: plusCode,\n }));\n\n if (plusCode) {\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n plus_code: plusCode,\n coordinate_source: \"plus_code\" as CoordinateSource,\n }));\n\n try {\n if (config) {\n const data = await decodePlusCode(config, { plus_code: plusCode });\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n latitude: data.latitude,\n longitude: data.longitude,\n }));\n } else {\n logger.warn(\"[GeolocationHelper] SdkConfig is required to decode Plus Code.\");\n }\n } catch (error) {\n logger.error(\"[GeolocationHelper] Plus Code decoding failed:\", error);\n }\n } else {\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n plus_code: \"\",\n coordinate_source: undefined,\n }));\n }\n}\n\n/**\n * Applies a picked AddressAutocomplete suggestion onto ShippingLocation\n * state in one place, so a caller wiring the shared component doesn't have\n * to hand-map its fields itself. Only overwrites a field the suggestion\n * actually returned a value for - never blanks out something the customer\n * had already filled in manually that this particular result happens to\n * lack (e.g. a suggestion with no postal_code shouldn't erase one already\n * typed). `coordinate_source` is set to \"manual\" (the closest of the\n * backend's 3 fixed values - `pin_drop`/`plus_code`/`manual`, strictly\n * validated server-side, see kasuvia-store-management's\n * schemas/logistics.py) only when the suggestion actually carried real\n * coordinates - an autocomplete pick is a distinct real source from either\n * of the two interactive geolocation tools, and there is no 4th backend\n * value for it.\n */\nexport function applyAddressSuggestion(\n suggestion: AddressSuggestion,\n setAddress: AddressUpdater\n): void {\n setAddress((prev: ShippingLocation) => ({\n ...prev,\n street: suggestion.line1 || prev.street,\n city: suggestion.city || prev.city,\n state: suggestion.state || prev.state,\n postal: suggestion.postal_code || prev.postal,\n country: suggestion.country || prev.country,\n latitude: suggestion.latitude ?? prev.latitude,\n longitude: suggestion.longitude ?? prev.longitude,\n coordinate_source:\n suggestion.latitude != null && suggestion.longitude != null\n ? (\"manual\" as CoordinateSource)\n : prev.coordinate_source,\n }));\n}\n\n\n\n","/**\n * Status colour mappings for Kasuvia entity statuses.\n * These are Tailwind CSS class strings; consuming apps must have Tailwind configured.\n * Migrated from kasuvia-storefront to kasuvia-sdk for shared use.\n */\n\nimport type { ServiceBookingStatus, MilestoneStatus } from \"../types/services\";\nimport type { OrderStatus } from \"../types/store\";\n\n// REAL BUG FIXED (2026-09-20): keyed on a fictional `AppointmentStatus`\n// (\"pending\" as the initial state) that never matched the real backend enum\n// (kasuvia-store-management's ServiceBookingStatus — the initial state is\n// \"scheduled\", not \"pending\"). Renamed/rekeyed to match reality.\nexport const appointmentStatusColors: Record<ServiceBookingStatus, string> = {\n scheduled: \"bg-yellow-100 text-yellow-800 hover:bg-yellow-200\",\n confirmed: \"bg-green-100 text-green-800 hover:bg-green-200\",\n in_progress: \"bg-blue-100 text-blue-800 hover:bg-blue-200\",\n completed: \"bg-gray-100 text-gray-800 hover:bg-gray-200\",\n voided: \"bg-red-100 text-red-800 hover:bg-red-200\",\n no_show: \"bg-red-100 text-red-800 hover:bg-red-200\",\n};\n\n// REAL BUG FIXED (2026-09-20): the \"deliverable\" concept these colors were\n// keyed on (pending/in_progress/review/approved/rejected) has no backend\n// counterpart at all — the real analogous feature is the service booking's\n// milestone/escrow sub-resource (MilestoneStatus), a different status set.\nexport const milestoneStatusColors: Record<MilestoneStatus, string> = {\n pending: \"bg-gray-100 text-gray-800\",\n funded: \"bg-blue-100 text-blue-800\",\n submitted: \"bg-yellow-100 text-yellow-800\",\n approved: \"bg-green-100 text-green-800\",\n released: \"bg-green-100 text-green-800\",\n disputed: \"bg-red-100 text-red-800\",\n refunded: \"bg-gray-100 text-gray-800\",\n};\n\n/**\n * REAL GAP FIXED (2026-09-22): no shared order-status mapping existed at\n * all (only appointments/milestones did) — kasuvia-storefront's\n * `OrderStatusCard.tsx` and `DashboardOrders.tsx` each independently\n * rendered order status differently (one a hand-rolled ternary chain with\n * friendlier labels like \"Preparing\"/\"On the way\", the other the raw\n * backend enum value capitalized, no color at all) — the same order shows\n * two different things depending which page the customer is on. Keyed on\n * the real `OrderStatus` union (types/store/index.ts).\n */\nexport const orderStatusColors: Record<OrderStatus, string> = {\n pending: \"bg-gray-100 text-gray-800\",\n confirmed: \"bg-blue-100 text-blue-800\",\n processing: \"bg-yellow-100 text-yellow-800\",\n packed: \"bg-yellow-100 text-yellow-800\",\n picked_up: \"bg-blue-100 text-blue-800\",\n ready_for_pickup: \"bg-blue-100 text-blue-800\",\n picked_up_by_customer: \"bg-green-100 text-green-800\",\n in_transit: \"bg-blue-100 text-blue-800\",\n shipped: \"bg-blue-100 text-blue-800\",\n delivered: \"bg-green-100 text-green-800\",\n voided: \"bg-red-100 text-red-800\",\n refunded: \"bg-gray-100 text-gray-800\",\n failed: \"bg-red-100 text-red-800\",\n};\n\n/** Human-friendly order status labels — the single source every page should use instead of its own ternary chain or the raw enum value. */\nexport const orderStatusLabels: Record<OrderStatus, string> = {\n pending: \"Order Placed\",\n confirmed: \"Confirmed\",\n processing: \"Preparing\",\n packed: \"Packed\",\n picked_up: \"Picked Up\",\n ready_for_pickup: \"Ready for Pickup\",\n picked_up_by_customer: \"Collected\",\n in_transit: \"In Transit\",\n shipped: \"On the Way\",\n delivered: \"Delivered\",\n voided: \"Voided\",\n refunded: \"Refunded\",\n failed: \"Failed\",\n};\n\n","/**\n * YouTube utility functions\n */\n\n/**\n * Extract YouTube video ID from various URL formats.\n * Supports:\n * - youtube.com/watch?v=VIDEO_ID\n * - youtu.be/VIDEO_ID\n * - youtube.com/embed/VIDEO_ID\n * - youtube.com/v/VIDEO_ID\n * - youtube.com/u/USERNAME/watch?v=VIDEO_ID\n */\nexport function getYouTubeID(url: string): string | null {\n const regExp = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n const match = url.match(regExp);\n return (match && match[2].length === 11) ? match[2] : null;\n}\n","/**\n * Cookie Consent Utilities\n *\n * Cookie consent state — read/written to localStorage only (per-browser, never\n * sent to any server). \"accepted\" | \"rejected\" | null (no choice made yet).\n *\n * localStorage is intentionally used here: this is a GDPR/NDPR UI preference\n * flag, not business data. It is never sent to the backend. The banner simply\n * reappears on the next visit if localStorage is unavailable (private browsing).\n */\n\nexport type CookieConsentValue = \"accepted\" | \"rejected\" | null;\n\nconst STORAGE_KEY = \"kasuvia_cookie_consent\";\nexport const COOKIE_CONSENT_CHANGED_EVENT = \"kasuvia:cookie-consent-changed\";\n\nexport function getCookieConsent(): CookieConsentValue {\n try {\n const value = window.localStorage.getItem(STORAGE_KEY);\n return value === \"accepted\" || value === \"rejected\" ? value : null;\n } catch {\n return null;\n }\n}\n\nexport function setCookieConsent(value: \"accepted\" | \"rejected\"): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, value);\n window.dispatchEvent(new Event(COOKIE_CONSENT_CHANGED_EVENT));\n } catch {\n // localStorage unavailable (private browsing, blocked site data) — the banner\n // will just reappear next visit rather than crash; nothing else depends on this.\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\n/**\n * Validates that a country code is a proper 2-letter ISO 3166-1 alpha-2 code.\n * Defensive guard against backend or session data that might send full country names.\n *\n * @param code - The country code string to validate\n * @returns true when the code is a valid 2-uppercase-letter ISO code\n */\nexport function isValidCountryCode(code: string | undefined): code is string {\n if (!code) return false;\n // Must be exactly 2 uppercase letters (valid ISO 3166-1 alpha-2)\n return /^[A-Z]{2}$/.test(code) && code.length === 2;\n}\n","/**\n * Guest Cart Session\n *\n * REAL BUG FIXED (2026-09-21): kasuvia-cart-management's real\n * `POST /api/v1/cart/*` routes hard-require an `X-Guest-Session` header for\n * any anonymous (unauthenticated) caller — confirmed against the live\n * backend (cart.go's `resolveTenant`/guest-path branches): with no\n * Authorization and no X-Guest-Session, add-to-cart returns 401\n * \"Authentication required. Please log in or provide a guest session.\"\n * `useCart()` has always accepted a `guestSessionId` parameter for exactly\n * this, but nothing anywhere in kasuvia-storefront ever generated or passed\n * one — every real `useCart()` call site called it with zero arguments. That\n * meant anonymous add-to-cart has never worked at all on the real storefront:\n * `addToCartMutation` throws 'Cannot add to cart: no access token or guest\n * session ID provided.' client-side before a request is even sent.\n *\n * This generates and persists one real guest session id per browser (via the\n * existing tenant-isolated `localStore` — already prefixed per business_id,\n * so multiple businesses tested on the same origin never collide), reused by\n * `SdkProvider` to feed every `useCart()` call through context automatically\n * (see sdk-context.tsx), the same way `config`/`accessToken` already are.\n */\nimport { localStore } from './storage'\n\nconst GUEST_SESSION_KEY = 'guest_session_id'\n\n/**\n * Returns the current browser's guest cart session id for this business,\n * generating and persisting one on first call. SSR-safe: returns null on\n * the server (no localStorage) — callers should only invoke this from a\n * client-side effect, matching every other browser-storage read in this SDK.\n */\nexport function getOrCreateGuestSessionId(businessId: string): string | null {\n if (typeof window === 'undefined') return null\n try {\n const existing = localStore.get(businessId, GUEST_SESSION_KEY)\n if (existing) return existing\n const generated = crypto.randomUUID()\n localStore.set(businessId, GUEST_SESSION_KEY, generated)\n return generated\n } catch {\n return null\n }\n}\n\n/**\n * Clears the persisted guest session id — call after a successful guest\n * cart merge into an authenticated customer's cart, so a subsequent logout\n * on the same browser starts a fresh guest session rather than reusing one\n * the backend has already deleted server-side.\n */\nexport function clearGuestSessionId(businessId: string): void {\n if (typeof window === 'undefined') return\n try {\n localStore.remove(businessId, GUEST_SESSION_KEY)\n } catch {\n // Best-effort cleanup — a failure here shouldn't surface to the caller.\n }\n}\n"],"mappings":"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","names":["ProductTypeEnum","ServiceTypeEnum","ServiceLocationTypeEnum","ServiceRecurringIntervalEnum","PaymentGatewayEnum","PaymentMethodTypeEnum","ModerationStatus","data","payload","refreshToken","isDevelopment","compact"]}
|