@managesales/storefront 1.2.0 → 1.2.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to `@managesales/storefront`. This project adheres to
4
4
  [Semantic Versioning](https://semver.org).
5
5
 
6
+ ## 1.2.1 — 2026-07-26
7
+
8
+ ### Changed
9
+ - **Default `apiUrl`** now points to production (`https://api.managesales.io/api/v1`)
10
+ instead of the Railway staging deployment. Override with `apiUrl` in
11
+ `createStorefrontClient()` or `PUBLIC_API_URL` at build time for self-hosted /
12
+ staging environments.
13
+
6
14
  ## 1.2.0 — 2026-07-21
7
15
 
8
16
  ### Added
package/README.md CHANGED
@@ -466,7 +466,7 @@ Prefer no dependency? The identical client is served as a single file — downlo
466
466
 
467
467
  ```bash
468
468
  curl -o managesales-storefront.ts \
469
- "https://managesales-backend-phase1test.up.railway.app/api/v1/sdk/storefront.ts"
469
+ "https://api.managesales.io/api/v1/sdk/storefront.ts"
470
470
  ```
471
471
 
472
472
  Then `import { createStorefrontClient } from "./managesales-storefront"`. The npm package, the curl
package/dist/index.cjs CHANGED
@@ -11,7 +11,7 @@ var StorefrontError = class extends Error {
11
11
  }
12
12
  };
13
13
  function createStorefrontClient(config) {
14
- const apiUrl = (config.apiUrl ?? "https://managesales-backend-phase1test.up.railway.app/api/v1").replace(/\/$/, "");
14
+ const apiUrl = (config.apiUrl ?? "https://api.managesales.io/api/v1").replace(/\/$/, "");
15
15
  const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);
16
16
  let accessToken = null;
17
17
  let refreshToken = null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ManageSales Storefront SDK\n * --------------------------\n * Resource-based client for building online storefronts.\n * Works with any framework: Next.js, Remix, Nuxt, Astro, plain HTML.\n *\n * Usage:\n * import { createStorefrontClient } from \"./managesales-storefront\";\n * const client = createStorefrontClient({ workspaceId: \"<workspace_id>\" });\n * const products = await client.products.list();\n */\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface RetryConfig {\n /** Max retry attempts for a failed request (default: 2) */\n retries?: number;\n /** Base delay in ms used for exponential backoff (default: 300) */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay, in ms (default: 4000) */\n maxDelayMs?: number;\n /** HTTP status codes that are retried, GET/HEAD only (default: [408,425,429,500,502,503,504]) */\n retryOnStatus?: number[];\n}\n\nexport interface StorefrontConfig {\n /** Your workspace ID (required) */\n workspaceId: string;\n /** API base URL — defaults to production */\n apiUrl?: string;\n /** Custom fetch implementation (for SSR / edge) */\n customFetch?: typeof fetch;\n /** Default locale for content */\n locale?: string;\n /**\n * Retry behavior for transient failures (network errors, and 5xx/408/425/429\n * responses on idempotent GET/HEAD requests). Pass `false` to disable retries\n * entirely. Defaults to 2 retries with exponential backoff.\n */\n retry?: RetryConfig | false;\n /**\n * Persist the stateful cart (`client.cart`) to `localStorage` so it survives\n * page reloads. Defaults to `true`. Has no effect in environments without\n * `localStorage` (e.g. Node/SSR) — the cart simply stays in-memory.\n */\n persistCart?: boolean;\n}\n\nexport interface ListParams {\n page?: number;\n limit?: number;\n search?: string;\n sort?: string;\n order?: \"asc\" | \"desc\";\n [key: string]: unknown;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n// ── Product types ──\n\nexport interface Product {\n id: string;\n name: string;\n slug: string;\n description: string;\n status: string;\n price: number;\n compareAtPrice?: number;\n currency: string;\n images: ProductImage[];\n variants: ProductVariant[];\n category?: { id: string; name: string };\n brand?: { id: string; name: string };\n tags: string[];\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProductImage {\n id: string;\n url: string;\n alt: string;\n position: number;\n}\n\nexport interface ProductVariant {\n id: string;\n name: string;\n sku: string;\n price: number;\n compareAtPrice?: number;\n inventory: number;\n options: Record<string, string>;\n}\n\n// ── Collection types ──\n\nexport interface Collection {\n id: string;\n name: string;\n slug: string;\n description: string;\n image?: string;\n productCount: number;\n}\n\n// ── Cart & Checkout types ──\n\nexport interface CheckoutLineItem {\n productId: string;\n variantId?: string;\n productName: string;\n quantity: number;\n unitPrice: number;\n imageUrl?: string;\n}\n\nexport interface CheckoutSessionLine {\n productId?: string;\n variantId?: string;\n productName: string;\n sku?: string;\n imageUrl?: string;\n quantity: number;\n unitPrice: number;\n}\n\nexport interface ShippingMethod {\n id: string;\n name: string;\n price: number;\n estimatedDays?: string;\n}\n\nexport interface CheckoutShippingAddress {\n name?: string;\n phone?: string;\n address?: string;\n city?: string;\n region?: string;\n country?: string;\n postalCode?: string;\n}\n\nexport interface CheckoutSession {\n id: string;\n status: \"open\" | \"completed\" | \"expired\";\n lines: CheckoutSessionLine[];\n subtotal: number;\n discountAmount: number;\n discountCode?: string;\n discountLabel?: string;\n taxAmount: number;\n taxLabel?: string;\n shippingAmount: number;\n shippingMethodId?: string;\n shippingMethodName?: string;\n shipping?: CheckoutShippingAddress;\n giftCardAmount?: number;\n giftCardCode?: string;\n availableShippingMethods?: ShippingMethod[];\n total: number;\n currency: string;\n createdAt?: string;\n /** @deprecated Never populated by the API — use `lines` */\n items?: CheckoutLineItem[];\n /** @deprecated Never populated by the API — use `taxAmount` */\n tax?: number;\n /** @deprecated Never populated by the API — use `discountAmount` */\n discount?: number;\n /** @deprecated Never populated by the API — use `discountCode` */\n couponCode?: string;\n}\n\nexport interface CartLine {\n id: string;\n productId: string;\n variantId?: string;\n quantity: number;\n unitPrice: number;\n productName: string;\n imageUrl?: string;\n}\n\nexport interface CartState {\n id: string;\n lines: CartLine[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AddCartLineItemInput {\n productId: string;\n variantId?: string;\n quantity: number;\n /** Skip the `products.get` price lookup by supplying these directly */\n unitPrice?: number;\n productName?: string;\n imageUrl?: string;\n}\n\nexport interface StorefrontCart {\n readonly id: string;\n readonly lines: CartLine[];\n readonly itemCount: number;\n readonly subtotal: number;\n /** Adds a line item. Supplying `unitPrice` also requires `productName`, otherwise this falls through to a `products.get` network lookup. */\n addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart>;\n updateLineItem(lineId: string, quantity: number): StorefrontCart;\n removeLineItem(lineId: string): StorefrontCart;\n clear(): StorefrontCart;\n checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession>;\n}\n\nexport interface Order {\n id: string;\n orderNumber: string;\n status: string;\n total: number;\n currency: string;\n items: OrderItem[];\n createdAt: string;\n}\n\nexport interface OrderItem {\n productId: string;\n name: string;\n quantity: number;\n price: number;\n}\n\n// ── Discount types ──\n\nexport interface DiscountValidationInput {\n /** Cart subtotal; omit when supplying `items` */\n subtotal?: number;\n items?: Array<{ productId?: string; variantId?: string; quantity: number; unitPrice: number }>;\n /** Known customer id — enables per-customer limit checks */\n customerId?: string;\n}\n\nexport interface DiscountValidationResult {\n valid: boolean;\n discountId?: string;\n code?: string;\n label?: string;\n amount?: number;\n freeShipping?: boolean;\n /** Present when `valid` is false — customer-safe explanation */\n reason?: string;\n}\n\nexport interface AutomaticPromotion {\n id: string;\n title: string;\n type: \"percentage\" | \"fixed_amount\" | \"buy_x_get_y\" | \"free_shipping\";\n value: number;\n minOrderAmount?: number | null;\n minQuantity?: number | null;\n endsAt?: string | null;\n}\n\nexport interface CreateCheckoutOptions {\n /** Coupon code applied server-side at session creation */\n couponCode?: string;\n}\n\n// ── Customer types ──\n\nexport interface Customer {\n id: string;\n email: string;\n name: string;\n phone?: string;\n createdAt: string;\n}\n\nexport interface AuthSession {\n customer: Customer;\n accessToken: string;\n refreshToken: string;\n}\n\nexport interface Address {\n id: string;\n label?: string;\n line1: string;\n line2?: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n isDefault: boolean;\n}\n\n// ── Blog types ──\n\nexport interface BlogPost {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage?: string;\n tags: string[];\n publishedAt: string;\n}\n\n// ── Booking types ──\n\nexport interface BookableService {\n id: string;\n name: string;\n duration: number;\n price: number;\n description: string;\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n id: string;\n serviceId: string;\n date: string;\n startTime: string;\n endTime: string;\n status: string;\n customer: { name: string; email: string };\n}\n\n// ── Form types ──\n\nexport interface FormDefinition {\n id: string;\n title: string;\n description: string;\n fields: FormField[];\n}\n\nexport interface FormField {\n id: string;\n type: string;\n label: string;\n required: boolean;\n options?: string[];\n placeholder?: string;\n}\n\n// ── Store config ──\n\nexport interface StoreConfig {\n name: string;\n slug: string;\n logo?: string;\n theme: Record<string, unknown>;\n currency: string;\n locale: string;\n}\n\n// ── SDK Error ──\n\nexport class StorefrontError extends Error {\n status: number;\n code: string;\n details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"StorefrontError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n// ── Core client ────────────────────────────────────────────────────\n\nexport function createStorefrontClient(config: StorefrontConfig) {\n const apiUrl = (config.apiUrl ?? \"https://managesales-backend-phase1test.up.railway.app/api/v1\").replace(/\\/$/, \"\");\n const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);\n let accessToken: string | null = null;\n let refreshToken: string | null = null;\n\n // ── Retry configuration ──\n\n const RETRY_DEFAULTS = {\n retries: 2,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n retryOnStatus: [408, 425, 429, 500, 502, 503, 504],\n };\n const rc =\n config.retry === false\n ? { ...RETRY_DEFAULTS, retries: 0 }\n : { ...RETRY_DEFAULTS, ...(config.retry || {}) };\n const IDEMPOTENT = new Set([\"GET\", \"HEAD\"]);\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n function backoff(attempt: number): number {\n return Math.min(rc.maxDelayMs, Math.round(Math.random() * rc.baseDelayMs * Math.pow(2, attempt)));\n }\n\n // ── Internal helpers ──\n\n async function request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n params?: Record<string, unknown>;\n auth?: boolean;\n },\n ): Promise<T> {\n const url = new URL(`${apiUrl}${path}`);\n if (options?.params) {\n for (const [k, v] of Object.entries(options.params)) {\n if (v !== undefined && v !== null) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n \"X-Workspace-Id\": config.workspaceId,\n };\n\n if (options?.auth && accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n }\n\n if (options?.body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n };\n\n let attempt = 0;\n let res: Response;\n while (true) {\n try {\n res = await fetchFn(url.toString(), fetchOptions);\n } catch (err) {\n if (attempt < rc.retries) {\n await sleep(backoff(attempt));\n attempt++;\n continue;\n }\n throw err;\n }\n if (attempt < rc.retries && rc.retryOnStatus.includes(res.status) && IDEMPOTENT.has(method)) {\n const ra = Number(res.headers.get(\"retry-after\"));\n await sleep(Number.isFinite(ra) && ra > 0 ? ra * 1000 : backoff(attempt));\n attempt++;\n continue;\n }\n break;\n }\n\n // Auto-refresh on 401\n if (res.status === 401 && options?.auth && refreshToken) {\n const refreshed = await refreshSession();\n if (refreshed) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n const retry = await fetchFn(url.toString(), {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n if (!retry.ok) throw await parseError(retry);\n return retry.status === 204 ? (undefined as T) : retry.json();\n }\n }\n\n if (!res.ok) throw await parseError(res);\n return res.status === 204 ? (undefined as T) : res.json();\n }\n\n async function parseError(res: Response): Promise<StorefrontError> {\n try {\n const body = await res.json();\n return new StorefrontError(\n res.status,\n body.code ?? body.error ?? \"UNKNOWN\",\n body.message ?? res.statusText,\n body,\n );\n } catch {\n return new StorefrontError(res.status, \"UNKNOWN\", res.statusText);\n }\n }\n\n async function refreshSession(): Promise<boolean> {\n if (!refreshToken) return false;\n try {\n const res = await fetchFn(`${apiUrl}/storefront/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Workspace-Id\": config.workspaceId,\n },\n body: JSON.stringify({ refreshToken }),\n });\n if (!res.ok) {\n accessToken = null;\n refreshToken = null;\n return false;\n }\n const data = await res.json();\n accessToken = data.accessToken;\n refreshToken = data.refreshToken;\n return true;\n } catch {\n return false;\n }\n }\n\n // ── Resource namespaces ──────────────────────────────────────────\n\n const store = {\n /** Resolve store config by workspace (returns theme, branding, currency) */\n async resolve(): Promise<StoreConfig> {\n return request(\"GET\", \"/storefront-api/resolve\");\n },\n };\n\n const products = {\n /** List published products with pagination and filters */\n async list(params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/products\", { params });\n },\n /** Get a single product by ID or slug */\n async get(idOrSlug: string): Promise<Product> {\n return request(\"GET\", `/storefront-api/products/${idOrSlug}`);\n },\n /** Search products (shorthand for list with search param) */\n async search(query: string, params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/search\", { params: { ...params, q: query } });\n },\n };\n\n const collections = {\n /** List published collections */\n async list(params?: ListParams): Promise<PaginatedResponse<Collection>> {\n return request(\"GET\", \"/storefront-api/collections\", { params });\n },\n /** Get a collection with its products */\n async get(idOrSlug: string): Promise<Collection & { products: Product[] }> {\n return request(\"GET\", `/storefront-api/collections/${idOrSlug}`);\n },\n };\n\n const discounts = {\n /** Preview a discount code against a cart before checkout. Never consumes usage. */\n async validate(code: string, input?: DiscountValidationInput): Promise<DiscountValidationResult> {\n return request(\"POST\", \"/storefront-api/discounts/validate\", { body: { code, ...(input || {}) } });\n },\n /** Active automatic promotions for display (codes are never exposed) */\n async automatic(): Promise<AutomaticPromotion[]> {\n return request(\"GET\", \"/storefront-api/discounts/automatic\");\n },\n };\n\n const checkout = {\n /** Create a checkout session from cart items */\n async create(items: CheckoutLineItem[], opts?: CreateCheckoutOptions): Promise<CheckoutSession> {\n const body: Record<string, unknown> = { lines: items };\n if (opts && opts.couponCode) body.couponCode = opts.couponCode;\n return request(\"POST\", \"/checkout\", { body });\n },\n /** Retrieve an existing checkout session */\n async get(checkoutId: string): Promise<CheckoutSession> {\n return request(\"GET\", `/checkout/${checkoutId}`);\n },\n /** Apply a coupon or discount code */\n async applyCoupon(checkoutId: string, couponCode: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/coupon`, { body: { code: couponCode } });\n },\n /** Apply a gift card to the checkout */\n async applyGiftCard(checkoutId: string, code: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/gift-card`, { body: { code } });\n },\n /** Complete checkout — process payment and create order */\n async complete(checkoutId: string, payment?: Record<string, unknown>): Promise<Order> {\n return request(\"POST\", `/checkout/${checkoutId}/complete`, { body: payment });\n },\n };\n\n const auth = {\n /** Register a new customer account */\n async register(data: {\n email: string;\n password: string;\n name: string;\n phone?: string;\n }): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/register\", { body: data });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with email + password */\n async login(email: string, password: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/login\", {\n body: { email, password },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with Google ID token */\n async loginWithGoogle(idToken: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/google\", {\n body: { idToken },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log out and clear local session */\n async logout(): Promise<void> {\n if (accessToken) {\n try {\n await request(\"POST\", \"/storefront/auth/logout\", { auth: true });\n } catch { /* ignore logout errors */ }\n }\n accessToken = null;\n refreshToken = null;\n },\n /** Refresh the access token */\n async refresh(): Promise<boolean> {\n return refreshSession();\n },\n /** Check if client has a valid session */\n isAuthenticated(): boolean {\n return accessToken !== null;\n },\n /** Manually set tokens (e.g., from SSR or cookie restoration) */\n setTokens(access: string, refresh: string): void {\n accessToken = access;\n refreshToken = refresh;\n },\n };\n\n const customer = {\n /** Get current customer profile */\n async me(): Promise<Customer> {\n return request(\"GET\", \"/storefront/auth/me\", { auth: true });\n },\n /** Get customer's order history */\n async orders(params?: ListParams): Promise<PaginatedResponse<Order>> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/orders`, { params, auth: true });\n },\n /** Get customer's saved addresses */\n async addresses(): Promise<Address[]> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/addresses`, { auth: true });\n },\n };\n\n const blog = {\n /** List published blog posts */\n async list(params?: ListParams & { tags?: string }): Promise<PaginatedResponse<BlogPost>> {\n return request(\"GET\", \"/storefront-api/blog/posts\", { params });\n },\n /** Get a blog post by slug */\n async get(slug: string): Promise<BlogPost> {\n return request(\"GET\", `/storefront-api/blog/posts/${slug}`);\n },\n };\n\n const bookings = {\n /** List bookable services */\n async services(): Promise<BookableService[]> {\n return request(\"GET\", \"/bookings-public/services\");\n },\n /** List bookable staff */\n async staff(): Promise<Array<{ id: string; name: string; avatar?: string }>> {\n return request(\"GET\", \"/bookings-public/staff\");\n },\n /** Check available time slots */\n async availability(params: {\n serviceId: string;\n date: string;\n staffId?: string;\n }): Promise<TimeSlot[]> {\n return request(\"GET\", \"/bookings-public/availability\", { params });\n },\n /** Create a booking */\n async book(data: {\n serviceId: string;\n date: string;\n startTime: string;\n staffId?: string;\n customer: { name: string; email: string; phone?: string };\n }): Promise<Booking> {\n return request(\"POST\", \"/bookings-public/book\", { body: data });\n },\n };\n\n const forms = {\n /** Get a published form by ID or slug */\n async get(idOrSlug: string): Promise<FormDefinition> {\n return request(\"GET\", `/public/forms/${idOrSlug}`);\n },\n /** Submit form response */\n async submit(formId: string, data: Record<string, unknown>): Promise<{ id: string }> {\n return request(\"POST\", `/public/forms/${formId}/submit`, { body: data });\n },\n /** Upload file for a form file field */\n async uploadFile(formId: string, file: File): Promise<{ url: string }> {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetchFn(`${apiUrl}/public/forms/${formId}/upload`, {\n method: \"POST\",\n headers: { \"X-Workspace-Id\": config.workspaceId },\n body: formData,\n });\n if (!res.ok) throw await parseError(res);\n return res.json();\n },\n };\n\n // ── Stateful cart (client-side, localStorage-persisted) ──\n\n const CART_KEY = \"managesales_cart_\" + config.workspaceId;\n const hasLS = () => {\n try {\n return config.persistCart !== false && typeof localStorage !== \"undefined\";\n } catch {\n return false;\n }\n };\n const loadCart = (): CartState | null => {\n if (!hasLS()) return null;\n try {\n const s = localStorage.getItem(CART_KEY);\n return s ? JSON.parse(s) : null;\n } catch {\n return null;\n }\n };\n const saveCart = (st: CartState): void => {\n if (!hasLS()) return;\n try {\n localStorage.setItem(CART_KEY, JSON.stringify(st));\n } catch {\n /* ignore persistence errors (quota, privacy mode, etc.) */\n }\n };\n let __lineSeq = 0;\n const genId = (p: string): string =>\n typeof crypto !== \"undefined\" && crypto.randomUUID ? p + crypto.randomUUID() : p + Date.now() + \"_\" + ++__lineSeq;\n const nowIso = (): string => new Date().toISOString();\n const freshCart = (): CartState => ({ id: genId(\"cart_\"), lines: [], createdAt: nowIso(), updatedAt: nowIso() });\n\n function makeCart(state: CartState): StorefrontCart {\n const persist = () => {\n state.updatedAt = nowIso();\n saveCart(state);\n };\n const cartObj: StorefrontCart = {\n get id() {\n return state.id;\n },\n get lines() {\n return state.lines;\n },\n get itemCount() {\n return state.lines.reduce((n, l) => n + l.quantity, 0);\n },\n get subtotal() {\n return state.lines.reduce((s, l) => s + l.unitPrice * l.quantity, 0);\n },\n // Supplying unitPrice alone does not skip the lookup — productName must also be\n // provided, otherwise this falls through to the products.get() network lookup below.\n async addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart> {\n let line: CartLine;\n if (input.unitPrice != null && input.productName) {\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n productName: input.productName,\n imageUrl: input.imageUrl,\n };\n } else {\n const p = await products.get(input.productId);\n const v = input.variantId && Array.isArray(p.variants) ? p.variants.find((x) => x.id === input.variantId) : undefined;\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: v && v.price != null ? v.price : p.price,\n productName: p.name,\n imageUrl: Array.isArray(p.images) && p.images.length > 0 ? p.images[0].url : undefined,\n };\n }\n const existing = state.lines.find((l) => l.productId === line.productId && l.variantId === line.variantId);\n if (existing) existing.quantity += line.quantity;\n else state.lines.push(line);\n persist();\n return cartObj;\n },\n updateLineItem(lineId: string, quantity: number): StorefrontCart {\n const l = state.lines.find((x) => x.id === lineId);\n if (l) {\n if (quantity <= 0) state.lines = state.lines.filter((x) => x.id !== lineId);\n else l.quantity = quantity;\n persist();\n }\n return cartObj;\n },\n removeLineItem(lineId: string): StorefrontCart {\n state.lines = state.lines.filter((x) => x.id !== lineId);\n persist();\n return cartObj;\n },\n clear(): StorefrontCart {\n state.lines = [];\n persist();\n return cartObj;\n },\n async checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession> {\n const session = await checkout.create(\n state.lines.map((l) => ({\n productId: l.productId,\n variantId: l.variantId,\n productName: l.productName,\n quantity: l.quantity,\n unitPrice: l.unitPrice,\n imageUrl: l.imageUrl,\n })),\n opts && opts.couponCode ? { couponCode: opts.couponCode } : undefined,\n );\n if (opts && opts.clearOnSuccess) cartObj.clear();\n return session;\n },\n };\n return cartObj;\n }\n\n const cart = {\n /** Create a new, empty cart (replaces any persisted cart) */\n create(): StorefrontCart {\n const st = freshCart();\n saveCart(st);\n return makeCart(st);\n },\n /** Get the current cart — loaded from storage if persisted, otherwise a fresh one */\n current(): StorefrontCart {\n return makeCart(loadCart() || freshCart());\n },\n /** Recover an abandoned cart by recovery token */\n async recover(token: string): Promise<CheckoutSession> {\n return request(\"GET\", `/abandoned-carts/recover/${token}`);\n },\n };\n\n // ── Alias namespaces (convenience wrappers over existing methods) ──\n\n /** Alias for `client.customer.orders` — order history for the logged-in customer */\n const orders = {\n /** Get customer's order history (delegates to `customer.orders`) */\n list: (params?: ListParams): Promise<PaginatedResponse<Order>> => customer.orders(params),\n };\n\n /** Convenience namespace bundling `auth` + `customer` under one name */\n const customers = {\n login: auth.login,\n register: auth.register,\n loginWithGoogle: auth.loginWithGoogle,\n logout: auth.logout,\n isAuthenticated: auth.isAuthenticated,\n setTokens: auth.setTokens,\n me: customer.me,\n orders: customer.orders,\n addresses: customer.addresses,\n };\n\n // ── Public API ───────────────────────────────────────────────────\n\n return {\n store,\n products,\n collections,\n discounts,\n checkout,\n auth,\n customer,\n blog,\n bookings,\n forms,\n cart,\n orders,\n customers,\n };\n}\n\n// ── Type export for TypeScript users ──\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>;\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAqXO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAKzC,WAAA,CAAY,MAAA,EAAgB,IAAA,EAAc,OAAA,EAAiB,OAAA,EAAmB;AAC5E,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF;AAIO,SAAS,uBAAuB,MAAA,EAA0B;AAC/D,EAAA,MAAM,UAAU,MAAA,CAAO,MAAA,IAAU,mCAAA,EAAqC,OAAA,CAAQ,OAAO,EAAE,CAAA;AACvF,EAAA,MAAM,UAAU,MAAA,CAAO,WAAA,IAAe,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AACtE,EAAA,IAAI,WAAA,GAA6B,IAAA;AACjC,EAAA,IAAI,YAAA,GAA8B,IAAA;AAIlC,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,OAAA,EAAS,CAAA;AAAA,IACT,WAAA,EAAa,GAAA;AAAA,IACb,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAG;AAAA,GACnD;AACA,EAAA,MAAM,KACJ,MAAA,CAAO,KAAA,KAAU,KAAA,GACb,EAAE,GAAG,cAAA,EAAgB,OAAA,EAAS,CAAA,EAAE,GAChC,EAAE,GAAG,cAAA,EAAgB,GAAI,MAAA,CAAO,KAAA,IAAS,EAAC,EAAG;AACnD,EAAA,MAAM,6BAAa,IAAI,GAAA,CAAI,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAAe,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACpF,EAAA,SAAS,QAAQ,OAAA,EAAyB;AACxC,IAAA,OAAO,KAAK,GAAA,CAAI,EAAA,CAAG,UAAA,EAAY,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA,CAAG,cAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAC,CAAC,CAAA;AAAA,EAClG;AAIA,EAAA,eAAe,OAAA,CACb,MAAA,EACA,IAAA,EACA,OAAA,EAKY;AACZ,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,CAAA;AACtC,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,EAAG;AACnD,QAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,EAAM,GAAA,CAAI,aAAa,GAAA,CAAI,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MACtE;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,kBAAkB,MAAA,CAAO;AAAA,KAC3B;AAEA,IAAA,IAAI,OAAA,EAAS,QAAQ,WAAA,EAAa;AAChC,MAAA,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA;AAAA,IAClD;AAEA,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAAA,IAC5B;AAEA,IAAA,MAAM,YAAA,GAA4B;AAAA,MAChC,MAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAM,OAAA,EAAS,IAAA,GAAO,KAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA,GAAI;AAAA,KACvD;AAEA,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,GAAA;AACJ,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,IAAI;AACF,QAAA,GAAA,GAAM,MAAM,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY,YAAY,CAAA;AAAA,MAClD,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,OAAA,GAAU,GAAG,OAAA,EAAS;AACxB,UAAA,MAAM,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAC,CAAA;AAC5B,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AACA,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,IAAI,OAAA,GAAU,EAAA,CAAG,OAAA,IAAW,EAAA,CAAG,aAAA,CAAc,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,IAAK,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,EAAG;AAC3F,QAAA,MAAM,KAAK,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAC,CAAA;AAChD,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAK,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,GAAA,GAAO,OAAA,CAAQ,OAAO,CAAC,CAAA;AACxE,QAAA,OAAA,EAAA;AACA,QAAA;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,OAAA,EAAS,QAAQ,YAAA,EAAc;AACvD,MAAA,MAAM,SAAA,GAAY,MAAM,cAAA,EAAe;AACvC,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA;AAChD,QAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,UAAS,EAAG;AAAA,UAC1C,MAAA;AAAA,UACA,OAAA;AAAA,UACA,MAAM,OAAA,EAAS,IAAA,GAAO,KAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA,GAAI;AAAA,SACtD,CAAA;AACD,QAAA,IAAI,CAAC,KAAA,CAAM,EAAA,EAAI,MAAM,MAAM,WAAW,KAAK,CAAA;AAC3C,QAAA,OAAO,KAAA,CAAM,MAAA,KAAW,GAAA,GAAO,MAAA,GAAkB,MAAM,IAAA,EAAK;AAAA,MAC9D;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,WAAW,GAAG,CAAA;AACvC,IAAA,OAAO,GAAA,CAAI,MAAA,KAAW,GAAA,GAAO,MAAA,GAAkB,IAAI,IAAA,EAAK;AAAA,EAC1D;AAEA,EAAA,eAAe,WAAW,GAAA,EAAyC;AACjE,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,IAAI,eAAA;AAAA,QACT,GAAA,CAAI,MAAA;AAAA,QACJ,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAA,IAAS,SAAA;AAAA,QAC3B,IAAA,CAAK,WAAW,GAAA,CAAI,UAAA;AAAA,QACpB;AAAA,OACF;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,CAAI,MAAA,EAAQ,SAAA,EAAW,IAAI,UAAU,CAAA;AAAA,IAClE;AAAA,EACF;AAEA,EAAA,eAAe,cAAA,GAAmC;AAChD,IAAA,IAAI,CAAC,cAAc,OAAO,KAAA;AAC1B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,CAAA,EAAG,MAAM,CAAA,wBAAA,CAAA,EAA4B;AAAA,QAC7D,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,kBAAkB,MAAA,CAAO;AAAA,SAC3B;AAAA,QACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,cAAc;AAAA,OACtC,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,WAAA,GAAc,IAAA;AACd,QAAA,YAAA,GAAe,IAAA;AACf,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,WAAA,GAAc,IAAA,CAAK,WAAA;AACnB,MAAA,YAAA,GAAe,IAAA,CAAK,YAAA;AACpB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAIA,EAAA,MAAM,KAAA,GAAQ;AAAA;AAAA,IAEZ,MAAM,OAAA,GAAgC;AACpC,MAAA,OAAO,OAAA,CAAQ,OAAO,yBAAyB,CAAA;AAAA,IACjD;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA;AAAA,IAEf,MAAM,KAAK,MAAA,EAA0D;AACnE,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,0BAAA,EAA4B,EAAE,QAAQ,CAAA;AAAA,IAC9D,CAAA;AAAA;AAAA,IAEA,MAAM,IAAI,QAAA,EAAoC;AAC5C,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,yBAAA,EAA4B,QAAQ,CAAA,CAAE,CAAA;AAAA,IAC9D,CAAA;AAAA;AAAA,IAEA,MAAM,MAAA,CAAO,KAAA,EAAe,MAAA,EAA0D;AACpF,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,wBAAA,EAA0B,EAAE,MAAA,EAAQ,EAAE,GAAG,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAM,EAAG,CAAA;AAAA,IACrF;AAAA,GACF;AAEA,EAAA,MAAM,WAAA,GAAc;AAAA;AAAA,IAElB,MAAM,KAAK,MAAA,EAA6D;AACtE,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,6BAAA,EAA+B,EAAE,QAAQ,CAAA;AAAA,IACjE,CAAA;AAAA;AAAA,IAEA,MAAM,IAAI,QAAA,EAAiE;AACzE,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,4BAAA,EAA+B,QAAQ,CAAA,CAAE,CAAA;AAAA,IACjE;AAAA,GACF;AAEA,EAAA,MAAM,SAAA,GAAY;AAAA;AAAA,IAEhB,MAAM,QAAA,CAAS,IAAA,EAAc,KAAA,EAAoE;AAC/F,MAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,oCAAA,EAAsC,EAAE,IAAA,EAAM,EAAE,IAAA,EAAM,GAAI,KAAA,IAAS,EAAC,EAAG,EAAG,CAAA;AAAA,IACnG,CAAA;AAAA;AAAA,IAEA,MAAM,SAAA,GAA2C;AAC/C,MAAA,OAAO,OAAA,CAAQ,OAAO,qCAAqC,CAAA;AAAA,IAC7D;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA;AAAA,IAEf,MAAM,MAAA,CAAO,KAAA,EAA2B,IAAA,EAAwD;AAC9F,MAAA,MAAM,IAAA,GAAgC,EAAE,KAAA,EAAO,KAAA,EAAM;AACrD,MAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACpD,MAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,WAAA,EAAa,EAAE,MAAM,CAAA;AAAA,IAC9C,CAAA;AAAA;AAAA,IAEA,MAAM,IAAI,UAAA,EAA8C;AACtD,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,UAAA,EAAa,UAAU,CAAA,CAAE,CAAA;AAAA,IACjD,CAAA;AAAA;AAAA,IAEA,MAAM,WAAA,CAAY,UAAA,EAAoB,UAAA,EAA8C;AAClF,MAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,UAAA,EAAa,UAAU,CAAA,OAAA,CAAA,EAAW,EAAE,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAW,EAAG,CAAA;AAAA,IACzF,CAAA;AAAA;AAAA,IAEA,MAAM,aAAA,CAAc,UAAA,EAAoB,IAAA,EAAwC;AAC9E,MAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,UAAA,EAAa,UAAU,CAAA,UAAA,CAAA,EAAc,EAAE,IAAA,EAAM,EAAE,IAAA,EAAK,EAAG,CAAA;AAAA,IAChF,CAAA;AAAA;AAAA,IAEA,MAAM,QAAA,CAAS,UAAA,EAAoB,OAAA,EAAmD;AACpF,MAAA,OAAO,OAAA,CAAQ,QAAQ,CAAA,UAAA,EAAa,UAAU,aAAa,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,IAC9E;AAAA,GACF;AAEA,EAAA,MAAM,IAAA,GAAO;AAAA;AAAA,IAEX,MAAM,SAAS,IAAA,EAKU;AACvB,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAqB,MAAA,EAAQ,6BAA6B,EAAE,IAAA,EAAM,MAAM,CAAA;AAC9F,MAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AACtB,MAAA,YAAA,GAAe,OAAA,CAAQ,YAAA;AACvB,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA;AAAA,IAEA,MAAM,KAAA,CAAM,KAAA,EAAe,QAAA,EAAwC;AACjE,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAqB,MAAA,EAAQ,wBAAA,EAA0B;AAAA,QAC3E,IAAA,EAAM,EAAE,KAAA,EAAO,QAAA;AAAS,OACzB,CAAA;AACD,MAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AACtB,MAAA,YAAA,GAAe,OAAA,CAAQ,YAAA;AACvB,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA;AAAA,IAEA,MAAM,gBAAgB,OAAA,EAAuC;AAC3D,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAqB,MAAA,EAAQ,yBAAA,EAA2B;AAAA,QAC5E,IAAA,EAAM,EAAE,OAAA;AAAQ,OACjB,CAAA;AACD,MAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AACtB,MAAA,YAAA,GAAe,OAAA,CAAQ,YAAA;AACvB,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA;AAAA,IAEA,MAAM,MAAA,GAAwB;AAC5B,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,MAAA,EAAQ,yBAAA,EAA2B,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,QACjE,CAAA,CAAA,MAAQ;AAAA,QAA6B;AAAA,MACvC;AACA,MAAA,WAAA,GAAc,IAAA;AACd,MAAA,YAAA,GAAe,IAAA;AAAA,IACjB,CAAA;AAAA;AAAA,IAEA,MAAM,OAAA,GAA4B;AAChC,MAAA,OAAO,cAAA,EAAe;AAAA,IACxB,CAAA;AAAA;AAAA,IAEA,eAAA,GAA2B;AACzB,MAAA,OAAO,WAAA,KAAgB,IAAA;AAAA,IACzB,CAAA;AAAA;AAAA,IAEA,SAAA,CAAU,QAAgB,OAAA,EAAuB;AAC/C,MAAA,WAAA,GAAc,MAAA;AACd,MAAA,YAAA,GAAe,OAAA;AAAA,IACjB;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA;AAAA,IAEf,MAAM,EAAA,GAAwB;AAC5B,MAAA,OAAO,QAAQ,KAAA,EAAO,qBAAA,EAAuB,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IAC7D,CAAA;AAAA;AAAA,IAEA,MAAM,OAAO,MAAA,EAAwD;AACnE,MAAA,MAAM,EAAA,GAAK,MAAM,OAAA,CAAkB,KAAA,EAAO,uBAAuB,EAAE,IAAA,EAAM,MAAM,CAAA;AAC/E,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,yBAAA,EAA4B,EAAA,CAAG,EAAE,WAAW,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IAC1F,CAAA;AAAA;AAAA,IAEA,MAAM,SAAA,GAAgC;AACpC,MAAA,MAAM,EAAA,GAAK,MAAM,OAAA,CAAkB,KAAA,EAAO,uBAAuB,EAAE,IAAA,EAAM,MAAM,CAAA;AAC/E,MAAA,OAAO,OAAA,CAAQ,OAAO,CAAA,yBAAA,EAA4B,EAAA,CAAG,EAAE,CAAA,UAAA,CAAA,EAAc,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IACrF;AAAA,GACF;AAEA,EAAA,MAAM,IAAA,GAAO;AAAA;AAAA,IAEX,MAAM,KAAK,MAAA,EAA+E;AACxF,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,4BAAA,EAA8B,EAAE,QAAQ,CAAA;AAAA,IAChE,CAAA;AAAA;AAAA,IAEA,MAAM,IAAI,IAAA,EAAiC;AACzC,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,2BAAA,EAA8B,IAAI,CAAA,CAAE,CAAA;AAAA,IAC5D;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA;AAAA,IAEf,MAAM,QAAA,GAAuC;AAC3C,MAAA,OAAO,OAAA,CAAQ,OAAO,2BAA2B,CAAA;AAAA,IACnD,CAAA;AAAA;AAAA,IAEA,MAAM,KAAA,GAAuE;AAC3E,MAAA,OAAO,OAAA,CAAQ,OAAO,wBAAwB,CAAA;AAAA,IAChD,CAAA;AAAA;AAAA,IAEA,MAAM,aAAa,MAAA,EAIK;AACtB,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,+BAAA,EAAiC,EAAE,QAAQ,CAAA;AAAA,IACnE,CAAA;AAAA;AAAA,IAEA,MAAM,KAAK,IAAA,EAMU;AACnB,MAAA,OAAO,QAAQ,MAAA,EAAQ,uBAAA,EAAyB,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IAChE;AAAA,GACF;AAEA,EAAA,MAAM,KAAA,GAAQ;AAAA;AAAA,IAEZ,MAAM,IAAI,QAAA,EAA2C;AACnD,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,cAAA,EAAiB,QAAQ,CAAA,CAAE,CAAA;AAAA,IACnD,CAAA;AAAA;AAAA,IAEA,MAAM,MAAA,CAAO,MAAA,EAAgB,IAAA,EAAwD;AACnF,MAAA,OAAO,OAAA,CAAQ,QAAQ,CAAA,cAAA,EAAiB,MAAM,WAAW,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACzE,CAAA;AAAA;AAAA,IAEA,MAAM,UAAA,CAAW,MAAA,EAAgB,IAAA,EAAsC;AACrE,MAAA,MAAM,QAAA,GAAW,IAAI,QAAA,EAAS;AAC9B,MAAA,QAAA,CAAS,MAAA,CAAO,QAAQ,IAAI,CAAA;AAC5B,MAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,GAAG,MAAM,CAAA,cAAA,EAAiB,MAAM,CAAA,OAAA,CAAA,EAAW;AAAA,QACnE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,gBAAA,EAAkB,MAAA,CAAO,WAAA,EAAY;AAAA,QAChD,IAAA,EAAM;AAAA,OACP,CAAA;AACD,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,WAAW,GAAG,CAAA;AACvC,MAAA,OAAO,IAAI,IAAA,EAAK;AAAA,IAClB;AAAA,GACF;AAIA,EAAA,MAAM,QAAA,GAAW,sBAAsB,MAAA,CAAO,WAAA;AAC9C,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,IAAI;AACF,MAAA,OAAO,MAAA,CAAO,WAAA,KAAgB,KAAA,IAAS,OAAO,YAAA,KAAiB,WAAA;AAAA,IACjE,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAA;AACA,EAAA,MAAM,WAAW,MAAwB;AACvC,IAAA,IAAI,CAAC,KAAA,EAAM,EAAG,OAAO,IAAA;AACrB,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,YAAA,CAAa,OAAA,CAAQ,QAAQ,CAAA;AACvC,MAAA,OAAO,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA;AACA,EAAA,MAAM,QAAA,GAAW,CAAC,EAAA,KAAwB;AACxC,IAAA,IAAI,CAAC,OAAM,EAAG;AACd,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,EAAE,CAAC,CAAA;AAAA,IACnD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AACA,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,MAAM,QAAQ,CAAC,CAAA,KACb,OAAO,MAAA,KAAW,eAAe,MAAA,CAAO,UAAA,GAAa,CAAA,GAAI,MAAA,CAAO,YAAW,GAAI,CAAA,GAAI,KAAK,GAAA,EAAI,GAAI,MAAM,EAAE,SAAA;AAC1G,EAAA,MAAM,MAAA,GAAS,MAAA,iBAAc,IAAI,IAAA,IAAO,WAAA,EAAY;AACpD,EAAA,MAAM,SAAA,GAAY,OAAkB,EAAE,EAAA,EAAI,MAAM,OAAO,CAAA,EAAG,KAAA,EAAO,IAAI,SAAA,EAAW,MAAA,EAAO,EAAG,SAAA,EAAW,QAAO,EAAE,CAAA;AAE9G,EAAA,SAAS,SAAS,KAAA,EAAkC;AAClD,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,KAAA,CAAM,YAAY,MAAA,EAAO;AACzB,MAAA,QAAA,CAAS,KAAK,CAAA;AAAA,IAChB,CAAA;AACA,IAAA,MAAM,OAAA,GAA0B;AAAA,MAC9B,IAAI,EAAA,GAAK;AACP,QAAA,OAAO,KAAA,CAAM,EAAA;AAAA,MACf,CAAA;AAAA,MACA,IAAI,KAAA,GAAQ;AACV,QAAA,OAAO,KAAA,CAAM,KAAA;AAAA,MACf,CAAA;AAAA,MACA,IAAI,SAAA,GAAY;AACd,QAAA,OAAO,KAAA,CAAM,MAAM,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,QAAA,EAAU,CAAC,CAAA;AAAA,MACvD,CAAA;AAAA,MACA,IAAI,QAAA,GAAW;AACb,QAAA,OAAO,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,QAAA,EAAU,CAAC,CAAA;AAAA,MACrE,CAAA;AAAA;AAAA;AAAA,MAGA,MAAM,YAAY,KAAA,EAAsD;AACtE,QAAA,IAAI,IAAA;AACJ,QAAA,IAAI,KAAA,CAAM,SAAA,IAAa,IAAA,IAAQ,KAAA,CAAM,WAAA,EAAa;AAChD,UAAA,IAAA,GAAO;AAAA,YACL,EAAA,EAAI,MAAM,OAAO,CAAA;AAAA,YACjB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,aAAa,KAAA,CAAM,WAAA;AAAA,YACnB,UAAU,KAAA,CAAM;AAAA,WAClB;AAAA,QACF,CAAA,MAAO;AACL,UAAA,MAAM,CAAA,GAAI,MAAM,QAAA,CAAS,GAAA,CAAI,MAAM,SAAS,CAAA;AAC5C,UAAA,MAAM,IAAI,KAAA,CAAM,SAAA,IAAa,KAAA,CAAM,OAAA,CAAQ,EAAE,QAAQ,CAAA,GAAI,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,KAAA,CAAM,SAAS,CAAA,GAAI,MAAA;AAC5G,UAAA,IAAA,GAAO;AAAA,YACL,EAAA,EAAI,MAAM,OAAO,CAAA;AAAA,YACjB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,WAAW,CAAA,IAAK,CAAA,CAAE,SAAS,IAAA,GAAO,CAAA,CAAE,QAAQ,CAAA,CAAE,KAAA;AAAA,YAC9C,aAAa,CAAA,CAAE,IAAA;AAAA,YACf,QAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,MAAM,CAAA,IAAK,CAAA,CAAE,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,CAAA,CAAE,MAAA,CAAO,CAAC,EAAE,GAAA,GAAM;AAAA,WAC/E;AAAA,QACF;AACA,QAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA,KAAc,IAAA,CAAK,SAAA,IAAa,CAAA,CAAE,SAAA,KAAc,KAAK,SAAS,CAAA;AACzG,QAAA,IAAI,QAAA,EAAU,QAAA,CAAS,QAAA,IAAY,IAAA,CAAK,QAAA;AAAA,aACnC,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAC1B,QAAA,OAAA,EAAQ;AACR,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AAAA,MACA,cAAA,CAAe,QAAgB,QAAA,EAAkC;AAC/D,QAAA,MAAM,CAAA,GAAI,MAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AACjD,QAAA,IAAI,CAAA,EAAG;AACL,UAAA,IAAI,QAAA,IAAY,CAAA,EAAG,KAAA,CAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,MAAM,CAAA;AAAA,iBACnE,QAAA,GAAW,QAAA;AAClB,UAAA,OAAA,EAAQ;AAAA,QACV;AACA,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AAAA,MACA,eAAe,MAAA,EAAgC;AAC7C,QAAA,KAAA,CAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AACvD,QAAA,OAAA,EAAQ;AACR,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AAAA,MACA,KAAA,GAAwB;AACtB,QAAA,KAAA,CAAM,QAAQ,EAAC;AACf,QAAA,OAAA,EAAQ;AACR,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AAAA,MACA,MAAM,SAAS,IAAA,EAAoF;AACjG,QAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,MAAA;AAAA,UAC7B,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,YACtB,WAAW,CAAA,CAAE,SAAA;AAAA,YACb,WAAW,CAAA,CAAE,SAAA;AAAA,YACb,aAAa,CAAA,CAAE,WAAA;AAAA,YACf,UAAU,CAAA,CAAE,QAAA;AAAA,YACZ,WAAW,CAAA,CAAE,SAAA;AAAA,YACb,UAAU,CAAA,CAAE;AAAA,WACd,CAAE,CAAA;AAAA,UACF,QAAQ,IAAA,CAAK,UAAA,GAAa,EAAE,UAAA,EAAY,IAAA,CAAK,YAAW,GAAI;AAAA,SAC9D;AACA,QAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,cAAA,EAAgB,OAAA,CAAQ,KAAA,EAAM;AAC/C,QAAA,OAAO,OAAA;AAAA,MACT;AAAA,KACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO;AAAA;AAAA,IAEX,MAAA,GAAyB;AACvB,MAAA,MAAM,KAAK,SAAA,EAAU;AACrB,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,OAAO,SAAS,EAAE,CAAA;AAAA,IACpB,CAAA;AAAA;AAAA,IAEA,OAAA,GAA0B;AACxB,MAAA,OAAO,QAAA,CAAS,QAAA,EAAS,IAAK,SAAA,EAAW,CAAA;AAAA,IAC3C,CAAA;AAAA;AAAA,IAEA,MAAM,QAAQ,KAAA,EAAyC;AACrD,MAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,yBAAA,EAA4B,KAAK,CAAA,CAAE,CAAA;AAAA,IAC3D;AAAA,GACF;AAKA,EAAA,MAAM,MAAA,GAAS;AAAA;AAAA,IAEb,IAAA,EAAM,CAAC,MAAA,KAA2D,QAAA,CAAS,OAAO,MAAM;AAAA,GAC1F;AAGA,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,iBAAiB,IAAA,CAAK,eAAA;AAAA,IACtB,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,iBAAiB,IAAA,CAAK,eAAA;AAAA,IACtB,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,IAAI,QAAA,CAAS,EAAA;AAAA,IACb,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,WAAW,QAAA,CAAS;AAAA,GACtB;AAIA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF","file":"index.cjs","sourcesContent":["/**\n * ManageSales Storefront SDK\n * --------------------------\n * Resource-based client for building online storefronts.\n * Works with any framework: Next.js, Remix, Nuxt, Astro, plain HTML.\n *\n * Usage:\n * import { createStorefrontClient } from \"./managesales-storefront\";\n * const client = createStorefrontClient({ workspaceId: \"<workspace_id>\" });\n * const products = await client.products.list();\n */\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface RetryConfig {\n /** Max retry attempts for a failed request (default: 2) */\n retries?: number;\n /** Base delay in ms used for exponential backoff (default: 300) */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay, in ms (default: 4000) */\n maxDelayMs?: number;\n /** HTTP status codes that are retried, GET/HEAD only (default: [408,425,429,500,502,503,504]) */\n retryOnStatus?: number[];\n}\n\nexport interface StorefrontConfig {\n /** Your workspace ID (required) */\n workspaceId: string;\n /** API base URL — defaults to production */\n apiUrl?: string;\n /** Custom fetch implementation (for SSR / edge) */\n customFetch?: typeof fetch;\n /** Default locale for content */\n locale?: string;\n /**\n * Retry behavior for transient failures (network errors, and 5xx/408/425/429\n * responses on idempotent GET/HEAD requests). Pass `false` to disable retries\n * entirely. Defaults to 2 retries with exponential backoff.\n */\n retry?: RetryConfig | false;\n /**\n * Persist the stateful cart (`client.cart`) to `localStorage` so it survives\n * page reloads. Defaults to `true`. Has no effect in environments without\n * `localStorage` (e.g. Node/SSR) — the cart simply stays in-memory.\n */\n persistCart?: boolean;\n}\n\nexport interface ListParams {\n page?: number;\n limit?: number;\n search?: string;\n sort?: string;\n order?: \"asc\" | \"desc\";\n [key: string]: unknown;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n// ── Product types ──\n\nexport interface Product {\n id: string;\n name: string;\n slug: string;\n description: string;\n status: string;\n price: number;\n compareAtPrice?: number;\n currency: string;\n images: ProductImage[];\n variants: ProductVariant[];\n category?: { id: string; name: string };\n brand?: { id: string; name: string };\n tags: string[];\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProductImage {\n id: string;\n url: string;\n alt: string;\n position: number;\n}\n\nexport interface ProductVariant {\n id: string;\n name: string;\n sku: string;\n price: number;\n compareAtPrice?: number;\n inventory: number;\n options: Record<string, string>;\n}\n\n// ── Collection types ──\n\nexport interface Collection {\n id: string;\n name: string;\n slug: string;\n description: string;\n image?: string;\n productCount: number;\n}\n\n// ── Cart & Checkout types ──\n\nexport interface CheckoutLineItem {\n productId: string;\n variantId?: string;\n productName: string;\n quantity: number;\n unitPrice: number;\n imageUrl?: string;\n}\n\nexport interface CheckoutSessionLine {\n productId?: string;\n variantId?: string;\n productName: string;\n sku?: string;\n imageUrl?: string;\n quantity: number;\n unitPrice: number;\n}\n\nexport interface ShippingMethod {\n id: string;\n name: string;\n price: number;\n estimatedDays?: string;\n}\n\nexport interface CheckoutShippingAddress {\n name?: string;\n phone?: string;\n address?: string;\n city?: string;\n region?: string;\n country?: string;\n postalCode?: string;\n}\n\nexport interface CheckoutSession {\n id: string;\n status: \"open\" | \"completed\" | \"expired\";\n lines: CheckoutSessionLine[];\n subtotal: number;\n discountAmount: number;\n discountCode?: string;\n discountLabel?: string;\n taxAmount: number;\n taxLabel?: string;\n shippingAmount: number;\n shippingMethodId?: string;\n shippingMethodName?: string;\n shipping?: CheckoutShippingAddress;\n giftCardAmount?: number;\n giftCardCode?: string;\n availableShippingMethods?: ShippingMethod[];\n total: number;\n currency: string;\n createdAt?: string;\n /** @deprecated Never populated by the API — use `lines` */\n items?: CheckoutLineItem[];\n /** @deprecated Never populated by the API — use `taxAmount` */\n tax?: number;\n /** @deprecated Never populated by the API — use `discountAmount` */\n discount?: number;\n /** @deprecated Never populated by the API — use `discountCode` */\n couponCode?: string;\n}\n\nexport interface CartLine {\n id: string;\n productId: string;\n variantId?: string;\n quantity: number;\n unitPrice: number;\n productName: string;\n imageUrl?: string;\n}\n\nexport interface CartState {\n id: string;\n lines: CartLine[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AddCartLineItemInput {\n productId: string;\n variantId?: string;\n quantity: number;\n /** Skip the `products.get` price lookup by supplying these directly */\n unitPrice?: number;\n productName?: string;\n imageUrl?: string;\n}\n\nexport interface StorefrontCart {\n readonly id: string;\n readonly lines: CartLine[];\n readonly itemCount: number;\n readonly subtotal: number;\n /** Adds a line item. Supplying `unitPrice` also requires `productName`, otherwise this falls through to a `products.get` network lookup. */\n addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart>;\n updateLineItem(lineId: string, quantity: number): StorefrontCart;\n removeLineItem(lineId: string): StorefrontCart;\n clear(): StorefrontCart;\n checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession>;\n}\n\nexport interface Order {\n id: string;\n orderNumber: string;\n status: string;\n total: number;\n currency: string;\n items: OrderItem[];\n createdAt: string;\n}\n\nexport interface OrderItem {\n productId: string;\n name: string;\n quantity: number;\n price: number;\n}\n\n// ── Discount types ──\n\nexport interface DiscountValidationInput {\n /** Cart subtotal; omit when supplying `items` */\n subtotal?: number;\n items?: Array<{ productId?: string; variantId?: string; quantity: number; unitPrice: number }>;\n /** Known customer id — enables per-customer limit checks */\n customerId?: string;\n}\n\nexport interface DiscountValidationResult {\n valid: boolean;\n discountId?: string;\n code?: string;\n label?: string;\n amount?: number;\n freeShipping?: boolean;\n /** Present when `valid` is false — customer-safe explanation */\n reason?: string;\n}\n\nexport interface AutomaticPromotion {\n id: string;\n title: string;\n type: \"percentage\" | \"fixed_amount\" | \"buy_x_get_y\" | \"free_shipping\";\n value: number;\n minOrderAmount?: number | null;\n minQuantity?: number | null;\n endsAt?: string | null;\n}\n\nexport interface CreateCheckoutOptions {\n /** Coupon code applied server-side at session creation */\n couponCode?: string;\n}\n\n// ── Customer types ──\n\nexport interface Customer {\n id: string;\n email: string;\n name: string;\n phone?: string;\n createdAt: string;\n}\n\nexport interface AuthSession {\n customer: Customer;\n accessToken: string;\n refreshToken: string;\n}\n\nexport interface Address {\n id: string;\n label?: string;\n line1: string;\n line2?: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n isDefault: boolean;\n}\n\n// ── Blog types ──\n\nexport interface BlogPost {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage?: string;\n tags: string[];\n publishedAt: string;\n}\n\n// ── Booking types ──\n\nexport interface BookableService {\n id: string;\n name: string;\n duration: number;\n price: number;\n description: string;\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n id: string;\n serviceId: string;\n date: string;\n startTime: string;\n endTime: string;\n status: string;\n customer: { name: string; email: string };\n}\n\n// ── Form types ──\n\nexport interface FormDefinition {\n id: string;\n title: string;\n description: string;\n fields: FormField[];\n}\n\nexport interface FormField {\n id: string;\n type: string;\n label: string;\n required: boolean;\n options?: string[];\n placeholder?: string;\n}\n\n// ── Store config ──\n\nexport interface StoreConfig {\n name: string;\n slug: string;\n logo?: string;\n theme: Record<string, unknown>;\n currency: string;\n locale: string;\n}\n\n// ── SDK Error ──\n\nexport class StorefrontError extends Error {\n status: number;\n code: string;\n details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"StorefrontError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n// ── Core client ────────────────────────────────────────────────────\n\nexport function createStorefrontClient(config: StorefrontConfig) {\n const apiUrl = (config.apiUrl ?? \"https://api.managesales.io/api/v1\").replace(/\\/$/, \"\");\n const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);\n let accessToken: string | null = null;\n let refreshToken: string | null = null;\n\n // ── Retry configuration ──\n\n const RETRY_DEFAULTS = {\n retries: 2,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n retryOnStatus: [408, 425, 429, 500, 502, 503, 504],\n };\n const rc =\n config.retry === false\n ? { ...RETRY_DEFAULTS, retries: 0 }\n : { ...RETRY_DEFAULTS, ...(config.retry || {}) };\n const IDEMPOTENT = new Set([\"GET\", \"HEAD\"]);\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n function backoff(attempt: number): number {\n return Math.min(rc.maxDelayMs, Math.round(Math.random() * rc.baseDelayMs * Math.pow(2, attempt)));\n }\n\n // ── Internal helpers ──\n\n async function request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n params?: Record<string, unknown>;\n auth?: boolean;\n },\n ): Promise<T> {\n const url = new URL(`${apiUrl}${path}`);\n if (options?.params) {\n for (const [k, v] of Object.entries(options.params)) {\n if (v !== undefined && v !== null) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n \"X-Workspace-Id\": config.workspaceId,\n };\n\n if (options?.auth && accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n }\n\n if (options?.body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n };\n\n let attempt = 0;\n let res: Response;\n while (true) {\n try {\n res = await fetchFn(url.toString(), fetchOptions);\n } catch (err) {\n if (attempt < rc.retries) {\n await sleep(backoff(attempt));\n attempt++;\n continue;\n }\n throw err;\n }\n if (attempt < rc.retries && rc.retryOnStatus.includes(res.status) && IDEMPOTENT.has(method)) {\n const ra = Number(res.headers.get(\"retry-after\"));\n await sleep(Number.isFinite(ra) && ra > 0 ? ra * 1000 : backoff(attempt));\n attempt++;\n continue;\n }\n break;\n }\n\n // Auto-refresh on 401\n if (res.status === 401 && options?.auth && refreshToken) {\n const refreshed = await refreshSession();\n if (refreshed) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n const retry = await fetchFn(url.toString(), {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n if (!retry.ok) throw await parseError(retry);\n return retry.status === 204 ? (undefined as T) : retry.json();\n }\n }\n\n if (!res.ok) throw await parseError(res);\n return res.status === 204 ? (undefined as T) : res.json();\n }\n\n async function parseError(res: Response): Promise<StorefrontError> {\n try {\n const body = await res.json();\n return new StorefrontError(\n res.status,\n body.code ?? body.error ?? \"UNKNOWN\",\n body.message ?? res.statusText,\n body,\n );\n } catch {\n return new StorefrontError(res.status, \"UNKNOWN\", res.statusText);\n }\n }\n\n async function refreshSession(): Promise<boolean> {\n if (!refreshToken) return false;\n try {\n const res = await fetchFn(`${apiUrl}/storefront/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Workspace-Id\": config.workspaceId,\n },\n body: JSON.stringify({ refreshToken }),\n });\n if (!res.ok) {\n accessToken = null;\n refreshToken = null;\n return false;\n }\n const data = await res.json();\n accessToken = data.accessToken;\n refreshToken = data.refreshToken;\n return true;\n } catch {\n return false;\n }\n }\n\n // ── Resource namespaces ──────────────────────────────────────────\n\n const store = {\n /** Resolve store config by workspace (returns theme, branding, currency) */\n async resolve(): Promise<StoreConfig> {\n return request(\"GET\", \"/storefront-api/resolve\");\n },\n };\n\n const products = {\n /** List published products with pagination and filters */\n async list(params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/products\", { params });\n },\n /** Get a single product by ID or slug */\n async get(idOrSlug: string): Promise<Product> {\n return request(\"GET\", `/storefront-api/products/${idOrSlug}`);\n },\n /** Search products (shorthand for list with search param) */\n async search(query: string, params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/search\", { params: { ...params, q: query } });\n },\n };\n\n const collections = {\n /** List published collections */\n async list(params?: ListParams): Promise<PaginatedResponse<Collection>> {\n return request(\"GET\", \"/storefront-api/collections\", { params });\n },\n /** Get a collection with its products */\n async get(idOrSlug: string): Promise<Collection & { products: Product[] }> {\n return request(\"GET\", `/storefront-api/collections/${idOrSlug}`);\n },\n };\n\n const discounts = {\n /** Preview a discount code against a cart before checkout. Never consumes usage. */\n async validate(code: string, input?: DiscountValidationInput): Promise<DiscountValidationResult> {\n return request(\"POST\", \"/storefront-api/discounts/validate\", { body: { code, ...(input || {}) } });\n },\n /** Active automatic promotions for display (codes are never exposed) */\n async automatic(): Promise<AutomaticPromotion[]> {\n return request(\"GET\", \"/storefront-api/discounts/automatic\");\n },\n };\n\n const checkout = {\n /** Create a checkout session from cart items */\n async create(items: CheckoutLineItem[], opts?: CreateCheckoutOptions): Promise<CheckoutSession> {\n const body: Record<string, unknown> = { lines: items };\n if (opts && opts.couponCode) body.couponCode = opts.couponCode;\n return request(\"POST\", \"/checkout\", { body });\n },\n /** Retrieve an existing checkout session */\n async get(checkoutId: string): Promise<CheckoutSession> {\n return request(\"GET\", `/checkout/${checkoutId}`);\n },\n /** Apply a coupon or discount code */\n async applyCoupon(checkoutId: string, couponCode: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/coupon`, { body: { code: couponCode } });\n },\n /** Apply a gift card to the checkout */\n async applyGiftCard(checkoutId: string, code: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/gift-card`, { body: { code } });\n },\n /** Complete checkout — process payment and create order */\n async complete(checkoutId: string, payment?: Record<string, unknown>): Promise<Order> {\n return request(\"POST\", `/checkout/${checkoutId}/complete`, { body: payment });\n },\n };\n\n const auth = {\n /** Register a new customer account */\n async register(data: {\n email: string;\n password: string;\n name: string;\n phone?: string;\n }): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/register\", { body: data });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with email + password */\n async login(email: string, password: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/login\", {\n body: { email, password },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with Google ID token */\n async loginWithGoogle(idToken: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/google\", {\n body: { idToken },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log out and clear local session */\n async logout(): Promise<void> {\n if (accessToken) {\n try {\n await request(\"POST\", \"/storefront/auth/logout\", { auth: true });\n } catch { /* ignore logout errors */ }\n }\n accessToken = null;\n refreshToken = null;\n },\n /** Refresh the access token */\n async refresh(): Promise<boolean> {\n return refreshSession();\n },\n /** Check if client has a valid session */\n isAuthenticated(): boolean {\n return accessToken !== null;\n },\n /** Manually set tokens (e.g., from SSR or cookie restoration) */\n setTokens(access: string, refresh: string): void {\n accessToken = access;\n refreshToken = refresh;\n },\n };\n\n const customer = {\n /** Get current customer profile */\n async me(): Promise<Customer> {\n return request(\"GET\", \"/storefront/auth/me\", { auth: true });\n },\n /** Get customer's order history */\n async orders(params?: ListParams): Promise<PaginatedResponse<Order>> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/orders`, { params, auth: true });\n },\n /** Get customer's saved addresses */\n async addresses(): Promise<Address[]> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/addresses`, { auth: true });\n },\n };\n\n const blog = {\n /** List published blog posts */\n async list(params?: ListParams & { tags?: string }): Promise<PaginatedResponse<BlogPost>> {\n return request(\"GET\", \"/storefront-api/blog/posts\", { params });\n },\n /** Get a blog post by slug */\n async get(slug: string): Promise<BlogPost> {\n return request(\"GET\", `/storefront-api/blog/posts/${slug}`);\n },\n };\n\n const bookings = {\n /** List bookable services */\n async services(): Promise<BookableService[]> {\n return request(\"GET\", \"/bookings-public/services\");\n },\n /** List bookable staff */\n async staff(): Promise<Array<{ id: string; name: string; avatar?: string }>> {\n return request(\"GET\", \"/bookings-public/staff\");\n },\n /** Check available time slots */\n async availability(params: {\n serviceId: string;\n date: string;\n staffId?: string;\n }): Promise<TimeSlot[]> {\n return request(\"GET\", \"/bookings-public/availability\", { params });\n },\n /** Create a booking */\n async book(data: {\n serviceId: string;\n date: string;\n startTime: string;\n staffId?: string;\n customer: { name: string; email: string; phone?: string };\n }): Promise<Booking> {\n return request(\"POST\", \"/bookings-public/book\", { body: data });\n },\n };\n\n const forms = {\n /** Get a published form by ID or slug */\n async get(idOrSlug: string): Promise<FormDefinition> {\n return request(\"GET\", `/public/forms/${idOrSlug}`);\n },\n /** Submit form response */\n async submit(formId: string, data: Record<string, unknown>): Promise<{ id: string }> {\n return request(\"POST\", `/public/forms/${formId}/submit`, { body: data });\n },\n /** Upload file for a form file field */\n async uploadFile(formId: string, file: File): Promise<{ url: string }> {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetchFn(`${apiUrl}/public/forms/${formId}/upload`, {\n method: \"POST\",\n headers: { \"X-Workspace-Id\": config.workspaceId },\n body: formData,\n });\n if (!res.ok) throw await parseError(res);\n return res.json();\n },\n };\n\n // ── Stateful cart (client-side, localStorage-persisted) ──\n\n const CART_KEY = \"managesales_cart_\" + config.workspaceId;\n const hasLS = () => {\n try {\n return config.persistCart !== false && typeof localStorage !== \"undefined\";\n } catch {\n return false;\n }\n };\n const loadCart = (): CartState | null => {\n if (!hasLS()) return null;\n try {\n const s = localStorage.getItem(CART_KEY);\n return s ? JSON.parse(s) : null;\n } catch {\n return null;\n }\n };\n const saveCart = (st: CartState): void => {\n if (!hasLS()) return;\n try {\n localStorage.setItem(CART_KEY, JSON.stringify(st));\n } catch {\n /* ignore persistence errors (quota, privacy mode, etc.) */\n }\n };\n let __lineSeq = 0;\n const genId = (p: string): string =>\n typeof crypto !== \"undefined\" && crypto.randomUUID ? p + crypto.randomUUID() : p + Date.now() + \"_\" + ++__lineSeq;\n const nowIso = (): string => new Date().toISOString();\n const freshCart = (): CartState => ({ id: genId(\"cart_\"), lines: [], createdAt: nowIso(), updatedAt: nowIso() });\n\n function makeCart(state: CartState): StorefrontCart {\n const persist = () => {\n state.updatedAt = nowIso();\n saveCart(state);\n };\n const cartObj: StorefrontCart = {\n get id() {\n return state.id;\n },\n get lines() {\n return state.lines;\n },\n get itemCount() {\n return state.lines.reduce((n, l) => n + l.quantity, 0);\n },\n get subtotal() {\n return state.lines.reduce((s, l) => s + l.unitPrice * l.quantity, 0);\n },\n // Supplying unitPrice alone does not skip the lookup — productName must also be\n // provided, otherwise this falls through to the products.get() network lookup below.\n async addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart> {\n let line: CartLine;\n if (input.unitPrice != null && input.productName) {\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n productName: input.productName,\n imageUrl: input.imageUrl,\n };\n } else {\n const p = await products.get(input.productId);\n const v = input.variantId && Array.isArray(p.variants) ? p.variants.find((x) => x.id === input.variantId) : undefined;\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: v && v.price != null ? v.price : p.price,\n productName: p.name,\n imageUrl: Array.isArray(p.images) && p.images.length > 0 ? p.images[0].url : undefined,\n };\n }\n const existing = state.lines.find((l) => l.productId === line.productId && l.variantId === line.variantId);\n if (existing) existing.quantity += line.quantity;\n else state.lines.push(line);\n persist();\n return cartObj;\n },\n updateLineItem(lineId: string, quantity: number): StorefrontCart {\n const l = state.lines.find((x) => x.id === lineId);\n if (l) {\n if (quantity <= 0) state.lines = state.lines.filter((x) => x.id !== lineId);\n else l.quantity = quantity;\n persist();\n }\n return cartObj;\n },\n removeLineItem(lineId: string): StorefrontCart {\n state.lines = state.lines.filter((x) => x.id !== lineId);\n persist();\n return cartObj;\n },\n clear(): StorefrontCart {\n state.lines = [];\n persist();\n return cartObj;\n },\n async checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession> {\n const session = await checkout.create(\n state.lines.map((l) => ({\n productId: l.productId,\n variantId: l.variantId,\n productName: l.productName,\n quantity: l.quantity,\n unitPrice: l.unitPrice,\n imageUrl: l.imageUrl,\n })),\n opts && opts.couponCode ? { couponCode: opts.couponCode } : undefined,\n );\n if (opts && opts.clearOnSuccess) cartObj.clear();\n return session;\n },\n };\n return cartObj;\n }\n\n const cart = {\n /** Create a new, empty cart (replaces any persisted cart) */\n create(): StorefrontCart {\n const st = freshCart();\n saveCart(st);\n return makeCart(st);\n },\n /** Get the current cart — loaded from storage if persisted, otherwise a fresh one */\n current(): StorefrontCart {\n return makeCart(loadCart() || freshCart());\n },\n /** Recover an abandoned cart by recovery token */\n async recover(token: string): Promise<CheckoutSession> {\n return request(\"GET\", `/abandoned-carts/recover/${token}`);\n },\n };\n\n // ── Alias namespaces (convenience wrappers over existing methods) ──\n\n /** Alias for `client.customer.orders` — order history for the logged-in customer */\n const orders = {\n /** Get customer's order history (delegates to `customer.orders`) */\n list: (params?: ListParams): Promise<PaginatedResponse<Order>> => customer.orders(params),\n };\n\n /** Convenience namespace bundling `auth` + `customer` under one name */\n const customers = {\n login: auth.login,\n register: auth.register,\n loginWithGoogle: auth.loginWithGoogle,\n logout: auth.logout,\n isAuthenticated: auth.isAuthenticated,\n setTokens: auth.setTokens,\n me: customer.me,\n orders: customer.orders,\n addresses: customer.addresses,\n };\n\n // ── Public API ───────────────────────────────────────────────────\n\n return {\n store,\n products,\n collections,\n discounts,\n checkout,\n auth,\n customer,\n blog,\n bookings,\n forms,\n cart,\n orders,\n customers,\n };\n}\n\n// ── Type export for TypeScript users ──\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>;\n"]}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var StorefrontError = class extends Error {
9
9
  }
10
10
  };
11
11
  function createStorefrontClient(config) {
12
- const apiUrl = (config.apiUrl ?? "https://managesales-backend-phase1test.up.railway.app/api/v1").replace(/\/$/, "");
12
+ const apiUrl = (config.apiUrl ?? "https://api.managesales.io/api/v1").replace(/\/$/, "");
13
13
  const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);
14
14
  let accessToken = null;
15
15
  let refreshToken = null;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ManageSales Storefront SDK\n * --------------------------\n * Resource-based client for building online storefronts.\n * Works with any framework: Next.js, Remix, Nuxt, Astro, plain HTML.\n *\n * Usage:\n * import { createStorefrontClient } from \"./managesales-storefront\";\n * const client = createStorefrontClient({ workspaceId: \"<workspace_id>\" });\n * const products = await client.products.list();\n */\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface RetryConfig {\n /** Max retry attempts for a failed request (default: 2) */\n retries?: number;\n /** Base delay in ms used for exponential backoff (default: 300) */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay, in ms (default: 4000) */\n maxDelayMs?: number;\n /** HTTP status codes that are retried, GET/HEAD only (default: [408,425,429,500,502,503,504]) */\n retryOnStatus?: number[];\n}\n\nexport interface StorefrontConfig {\n /** Your workspace ID (required) */\n workspaceId: string;\n /** API base URL — defaults to production */\n apiUrl?: string;\n /** Custom fetch implementation (for SSR / edge) */\n customFetch?: typeof fetch;\n /** Default locale for content */\n locale?: string;\n /**\n * Retry behavior for transient failures (network errors, and 5xx/408/425/429\n * responses on idempotent GET/HEAD requests). Pass `false` to disable retries\n * entirely. Defaults to 2 retries with exponential backoff.\n */\n retry?: RetryConfig | false;\n /**\n * Persist the stateful cart (`client.cart`) to `localStorage` so it survives\n * page reloads. Defaults to `true`. Has no effect in environments without\n * `localStorage` (e.g. Node/SSR) — the cart simply stays in-memory.\n */\n persistCart?: boolean;\n}\n\nexport interface ListParams {\n page?: number;\n limit?: number;\n search?: string;\n sort?: string;\n order?: \"asc\" | \"desc\";\n [key: string]: unknown;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n// ── Product types ──\n\nexport interface Product {\n id: string;\n name: string;\n slug: string;\n description: string;\n status: string;\n price: number;\n compareAtPrice?: number;\n currency: string;\n images: ProductImage[];\n variants: ProductVariant[];\n category?: { id: string; name: string };\n brand?: { id: string; name: string };\n tags: string[];\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProductImage {\n id: string;\n url: string;\n alt: string;\n position: number;\n}\n\nexport interface ProductVariant {\n id: string;\n name: string;\n sku: string;\n price: number;\n compareAtPrice?: number;\n inventory: number;\n options: Record<string, string>;\n}\n\n// ── Collection types ──\n\nexport interface Collection {\n id: string;\n name: string;\n slug: string;\n description: string;\n image?: string;\n productCount: number;\n}\n\n// ── Cart & Checkout types ──\n\nexport interface CheckoutLineItem {\n productId: string;\n variantId?: string;\n productName: string;\n quantity: number;\n unitPrice: number;\n imageUrl?: string;\n}\n\nexport interface CheckoutSessionLine {\n productId?: string;\n variantId?: string;\n productName: string;\n sku?: string;\n imageUrl?: string;\n quantity: number;\n unitPrice: number;\n}\n\nexport interface ShippingMethod {\n id: string;\n name: string;\n price: number;\n estimatedDays?: string;\n}\n\nexport interface CheckoutShippingAddress {\n name?: string;\n phone?: string;\n address?: string;\n city?: string;\n region?: string;\n country?: string;\n postalCode?: string;\n}\n\nexport interface CheckoutSession {\n id: string;\n status: \"open\" | \"completed\" | \"expired\";\n lines: CheckoutSessionLine[];\n subtotal: number;\n discountAmount: number;\n discountCode?: string;\n discountLabel?: string;\n taxAmount: number;\n taxLabel?: string;\n shippingAmount: number;\n shippingMethodId?: string;\n shippingMethodName?: string;\n shipping?: CheckoutShippingAddress;\n giftCardAmount?: number;\n giftCardCode?: string;\n availableShippingMethods?: ShippingMethod[];\n total: number;\n currency: string;\n createdAt?: string;\n /** @deprecated Never populated by the API — use `lines` */\n items?: CheckoutLineItem[];\n /** @deprecated Never populated by the API — use `taxAmount` */\n tax?: number;\n /** @deprecated Never populated by the API — use `discountAmount` */\n discount?: number;\n /** @deprecated Never populated by the API — use `discountCode` */\n couponCode?: string;\n}\n\nexport interface CartLine {\n id: string;\n productId: string;\n variantId?: string;\n quantity: number;\n unitPrice: number;\n productName: string;\n imageUrl?: string;\n}\n\nexport interface CartState {\n id: string;\n lines: CartLine[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AddCartLineItemInput {\n productId: string;\n variantId?: string;\n quantity: number;\n /** Skip the `products.get` price lookup by supplying these directly */\n unitPrice?: number;\n productName?: string;\n imageUrl?: string;\n}\n\nexport interface StorefrontCart {\n readonly id: string;\n readonly lines: CartLine[];\n readonly itemCount: number;\n readonly subtotal: number;\n /** Adds a line item. Supplying `unitPrice` also requires `productName`, otherwise this falls through to a `products.get` network lookup. */\n addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart>;\n updateLineItem(lineId: string, quantity: number): StorefrontCart;\n removeLineItem(lineId: string): StorefrontCart;\n clear(): StorefrontCart;\n checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession>;\n}\n\nexport interface Order {\n id: string;\n orderNumber: string;\n status: string;\n total: number;\n currency: string;\n items: OrderItem[];\n createdAt: string;\n}\n\nexport interface OrderItem {\n productId: string;\n name: string;\n quantity: number;\n price: number;\n}\n\n// ── Discount types ──\n\nexport interface DiscountValidationInput {\n /** Cart subtotal; omit when supplying `items` */\n subtotal?: number;\n items?: Array<{ productId?: string; variantId?: string; quantity: number; unitPrice: number }>;\n /** Known customer id — enables per-customer limit checks */\n customerId?: string;\n}\n\nexport interface DiscountValidationResult {\n valid: boolean;\n discountId?: string;\n code?: string;\n label?: string;\n amount?: number;\n freeShipping?: boolean;\n /** Present when `valid` is false — customer-safe explanation */\n reason?: string;\n}\n\nexport interface AutomaticPromotion {\n id: string;\n title: string;\n type: \"percentage\" | \"fixed_amount\" | \"buy_x_get_y\" | \"free_shipping\";\n value: number;\n minOrderAmount?: number | null;\n minQuantity?: number | null;\n endsAt?: string | null;\n}\n\nexport interface CreateCheckoutOptions {\n /** Coupon code applied server-side at session creation */\n couponCode?: string;\n}\n\n// ── Customer types ──\n\nexport interface Customer {\n id: string;\n email: string;\n name: string;\n phone?: string;\n createdAt: string;\n}\n\nexport interface AuthSession {\n customer: Customer;\n accessToken: string;\n refreshToken: string;\n}\n\nexport interface Address {\n id: string;\n label?: string;\n line1: string;\n line2?: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n isDefault: boolean;\n}\n\n// ── Blog types ──\n\nexport interface BlogPost {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage?: string;\n tags: string[];\n publishedAt: string;\n}\n\n// ── Booking types ──\n\nexport interface BookableService {\n id: string;\n name: string;\n duration: number;\n price: number;\n description: string;\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n id: string;\n serviceId: string;\n date: string;\n startTime: string;\n endTime: string;\n status: string;\n customer: { name: string; email: string };\n}\n\n// ── Form types ──\n\nexport interface FormDefinition {\n id: string;\n title: string;\n description: string;\n fields: FormField[];\n}\n\nexport interface FormField {\n id: string;\n type: string;\n label: string;\n required: boolean;\n options?: string[];\n placeholder?: string;\n}\n\n// ── Store config ──\n\nexport interface StoreConfig {\n name: string;\n slug: string;\n logo?: string;\n theme: Record<string, unknown>;\n currency: string;\n locale: string;\n}\n\n// ── SDK Error ──\n\nexport class StorefrontError extends Error {\n status: number;\n code: string;\n details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"StorefrontError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n// ── Core client ────────────────────────────────────────────────────\n\nexport function createStorefrontClient(config: StorefrontConfig) {\n const apiUrl = (config.apiUrl ?? \"https://managesales-backend-phase1test.up.railway.app/api/v1\").replace(/\\/$/, \"\");\n const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);\n let accessToken: string | null = null;\n let refreshToken: string | null = null;\n\n // ── Retry configuration ──\n\n const RETRY_DEFAULTS = {\n retries: 2,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n retryOnStatus: [408, 425, 429, 500, 502, 503, 504],\n };\n const rc =\n config.retry === false\n ? { ...RETRY_DEFAULTS, retries: 0 }\n : { ...RETRY_DEFAULTS, ...(config.retry || {}) };\n const IDEMPOTENT = new Set([\"GET\", \"HEAD\"]);\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n function backoff(attempt: number): number {\n return Math.min(rc.maxDelayMs, Math.round(Math.random() * rc.baseDelayMs * Math.pow(2, attempt)));\n }\n\n // ── Internal helpers ──\n\n async function request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n params?: Record<string, unknown>;\n auth?: boolean;\n },\n ): Promise<T> {\n const url = new URL(`${apiUrl}${path}`);\n if (options?.params) {\n for (const [k, v] of Object.entries(options.params)) {\n if (v !== undefined && v !== null) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n \"X-Workspace-Id\": config.workspaceId,\n };\n\n if (options?.auth && accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n }\n\n if (options?.body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n };\n\n let attempt = 0;\n let res: Response;\n while (true) {\n try {\n res = await fetchFn(url.toString(), fetchOptions);\n } catch (err) {\n if (attempt < rc.retries) {\n await sleep(backoff(attempt));\n attempt++;\n continue;\n }\n throw err;\n }\n if (attempt < rc.retries && rc.retryOnStatus.includes(res.status) && IDEMPOTENT.has(method)) {\n const ra = Number(res.headers.get(\"retry-after\"));\n await sleep(Number.isFinite(ra) && ra > 0 ? ra * 1000 : backoff(attempt));\n attempt++;\n continue;\n }\n break;\n }\n\n // Auto-refresh on 401\n if (res.status === 401 && options?.auth && refreshToken) {\n const refreshed = await refreshSession();\n if (refreshed) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n const retry = await fetchFn(url.toString(), {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n if (!retry.ok) throw await parseError(retry);\n return retry.status === 204 ? (undefined as T) : retry.json();\n }\n }\n\n if (!res.ok) throw await parseError(res);\n return res.status === 204 ? (undefined as T) : res.json();\n }\n\n async function parseError(res: Response): Promise<StorefrontError> {\n try {\n const body = await res.json();\n return new StorefrontError(\n res.status,\n body.code ?? body.error ?? \"UNKNOWN\",\n body.message ?? res.statusText,\n body,\n );\n } catch {\n return new StorefrontError(res.status, \"UNKNOWN\", res.statusText);\n }\n }\n\n async function refreshSession(): Promise<boolean> {\n if (!refreshToken) return false;\n try {\n const res = await fetchFn(`${apiUrl}/storefront/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Workspace-Id\": config.workspaceId,\n },\n body: JSON.stringify({ refreshToken }),\n });\n if (!res.ok) {\n accessToken = null;\n refreshToken = null;\n return false;\n }\n const data = await res.json();\n accessToken = data.accessToken;\n refreshToken = data.refreshToken;\n return true;\n } catch {\n return false;\n }\n }\n\n // ── Resource namespaces ──────────────────────────────────────────\n\n const store = {\n /** Resolve store config by workspace (returns theme, branding, currency) */\n async resolve(): Promise<StoreConfig> {\n return request(\"GET\", \"/storefront-api/resolve\");\n },\n };\n\n const products = {\n /** List published products with pagination and filters */\n async list(params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/products\", { params });\n },\n /** Get a single product by ID or slug */\n async get(idOrSlug: string): Promise<Product> {\n return request(\"GET\", `/storefront-api/products/${idOrSlug}`);\n },\n /** Search products (shorthand for list with search param) */\n async search(query: string, params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/search\", { params: { ...params, q: query } });\n },\n };\n\n const collections = {\n /** List published collections */\n async list(params?: ListParams): Promise<PaginatedResponse<Collection>> {\n return request(\"GET\", \"/storefront-api/collections\", { params });\n },\n /** Get a collection with its products */\n async get(idOrSlug: string): Promise<Collection & { products: Product[] }> {\n return request(\"GET\", `/storefront-api/collections/${idOrSlug}`);\n },\n };\n\n const discounts = {\n /** Preview a discount code against a cart before checkout. Never consumes usage. */\n async validate(code: string, input?: DiscountValidationInput): Promise<DiscountValidationResult> {\n return request(\"POST\", \"/storefront-api/discounts/validate\", { body: { code, ...(input || {}) } });\n },\n /** Active automatic promotions for display (codes are never exposed) */\n async automatic(): Promise<AutomaticPromotion[]> {\n return request(\"GET\", \"/storefront-api/discounts/automatic\");\n },\n };\n\n const checkout = {\n /** Create a checkout session from cart items */\n async create(items: CheckoutLineItem[], opts?: CreateCheckoutOptions): Promise<CheckoutSession> {\n const body: Record<string, unknown> = { lines: items };\n if (opts && opts.couponCode) body.couponCode = opts.couponCode;\n return request(\"POST\", \"/checkout\", { body });\n },\n /** Retrieve an existing checkout session */\n async get(checkoutId: string): Promise<CheckoutSession> {\n return request(\"GET\", `/checkout/${checkoutId}`);\n },\n /** Apply a coupon or discount code */\n async applyCoupon(checkoutId: string, couponCode: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/coupon`, { body: { code: couponCode } });\n },\n /** Apply a gift card to the checkout */\n async applyGiftCard(checkoutId: string, code: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/gift-card`, { body: { code } });\n },\n /** Complete checkout — process payment and create order */\n async complete(checkoutId: string, payment?: Record<string, unknown>): Promise<Order> {\n return request(\"POST\", `/checkout/${checkoutId}/complete`, { body: payment });\n },\n };\n\n const auth = {\n /** Register a new customer account */\n async register(data: {\n email: string;\n password: string;\n name: string;\n phone?: string;\n }): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/register\", { body: data });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with email + password */\n async login(email: string, password: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/login\", {\n body: { email, password },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with Google ID token */\n async loginWithGoogle(idToken: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/google\", {\n body: { idToken },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log out and clear local session */\n async logout(): Promise<void> {\n if (accessToken) {\n try {\n await request(\"POST\", \"/storefront/auth/logout\", { auth: true });\n } catch { /* ignore logout errors */ }\n }\n accessToken = null;\n refreshToken = null;\n },\n /** Refresh the access token */\n async refresh(): Promise<boolean> {\n return refreshSession();\n },\n /** Check if client has a valid session */\n isAuthenticated(): boolean {\n return accessToken !== null;\n },\n /** Manually set tokens (e.g., from SSR or cookie restoration) */\n setTokens(access: string, refresh: string): void {\n accessToken = access;\n refreshToken = refresh;\n },\n };\n\n const customer = {\n /** Get current customer profile */\n async me(): Promise<Customer> {\n return request(\"GET\", \"/storefront/auth/me\", { auth: true });\n },\n /** Get customer's order history */\n async orders(params?: ListParams): Promise<PaginatedResponse<Order>> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/orders`, { params, auth: true });\n },\n /** Get customer's saved addresses */\n async addresses(): Promise<Address[]> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/addresses`, { auth: true });\n },\n };\n\n const blog = {\n /** List published blog posts */\n async list(params?: ListParams & { tags?: string }): Promise<PaginatedResponse<BlogPost>> {\n return request(\"GET\", \"/storefront-api/blog/posts\", { params });\n },\n /** Get a blog post by slug */\n async get(slug: string): Promise<BlogPost> {\n return request(\"GET\", `/storefront-api/blog/posts/${slug}`);\n },\n };\n\n const bookings = {\n /** List bookable services */\n async services(): Promise<BookableService[]> {\n return request(\"GET\", \"/bookings-public/services\");\n },\n /** List bookable staff */\n async staff(): Promise<Array<{ id: string; name: string; avatar?: string }>> {\n return request(\"GET\", \"/bookings-public/staff\");\n },\n /** Check available time slots */\n async availability(params: {\n serviceId: string;\n date: string;\n staffId?: string;\n }): Promise<TimeSlot[]> {\n return request(\"GET\", \"/bookings-public/availability\", { params });\n },\n /** Create a booking */\n async book(data: {\n serviceId: string;\n date: string;\n startTime: string;\n staffId?: string;\n customer: { name: string; email: string; phone?: string };\n }): Promise<Booking> {\n return request(\"POST\", \"/bookings-public/book\", { body: data });\n },\n };\n\n const forms = {\n /** Get a published form by ID or slug */\n async get(idOrSlug: string): Promise<FormDefinition> {\n return request(\"GET\", `/public/forms/${idOrSlug}`);\n },\n /** Submit form response */\n async submit(formId: string, data: Record<string, unknown>): Promise<{ id: string }> {\n return request(\"POST\", `/public/forms/${formId}/submit`, { body: data });\n },\n /** Upload file for a form file field */\n async uploadFile(formId: string, file: File): Promise<{ url: string }> {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetchFn(`${apiUrl}/public/forms/${formId}/upload`, {\n method: \"POST\",\n headers: { \"X-Workspace-Id\": config.workspaceId },\n body: formData,\n });\n if (!res.ok) throw await parseError(res);\n return res.json();\n },\n };\n\n // ── Stateful cart (client-side, localStorage-persisted) ──\n\n const CART_KEY = \"managesales_cart_\" + config.workspaceId;\n const hasLS = () => {\n try {\n return config.persistCart !== false && typeof localStorage !== \"undefined\";\n } catch {\n return false;\n }\n };\n const loadCart = (): CartState | null => {\n if (!hasLS()) return null;\n try {\n const s = localStorage.getItem(CART_KEY);\n return s ? JSON.parse(s) : null;\n } catch {\n return null;\n }\n };\n const saveCart = (st: CartState): void => {\n if (!hasLS()) return;\n try {\n localStorage.setItem(CART_KEY, JSON.stringify(st));\n } catch {\n /* ignore persistence errors (quota, privacy mode, etc.) */\n }\n };\n let __lineSeq = 0;\n const genId = (p: string): string =>\n typeof crypto !== \"undefined\" && crypto.randomUUID ? p + crypto.randomUUID() : p + Date.now() + \"_\" + ++__lineSeq;\n const nowIso = (): string => new Date().toISOString();\n const freshCart = (): CartState => ({ id: genId(\"cart_\"), lines: [], createdAt: nowIso(), updatedAt: nowIso() });\n\n function makeCart(state: CartState): StorefrontCart {\n const persist = () => {\n state.updatedAt = nowIso();\n saveCart(state);\n };\n const cartObj: StorefrontCart = {\n get id() {\n return state.id;\n },\n get lines() {\n return state.lines;\n },\n get itemCount() {\n return state.lines.reduce((n, l) => n + l.quantity, 0);\n },\n get subtotal() {\n return state.lines.reduce((s, l) => s + l.unitPrice * l.quantity, 0);\n },\n // Supplying unitPrice alone does not skip the lookup — productName must also be\n // provided, otherwise this falls through to the products.get() network lookup below.\n async addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart> {\n let line: CartLine;\n if (input.unitPrice != null && input.productName) {\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n productName: input.productName,\n imageUrl: input.imageUrl,\n };\n } else {\n const p = await products.get(input.productId);\n const v = input.variantId && Array.isArray(p.variants) ? p.variants.find((x) => x.id === input.variantId) : undefined;\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: v && v.price != null ? v.price : p.price,\n productName: p.name,\n imageUrl: Array.isArray(p.images) && p.images.length > 0 ? p.images[0].url : undefined,\n };\n }\n const existing = state.lines.find((l) => l.productId === line.productId && l.variantId === line.variantId);\n if (existing) existing.quantity += line.quantity;\n else state.lines.push(line);\n persist();\n return cartObj;\n },\n updateLineItem(lineId: string, quantity: number): StorefrontCart {\n const l = state.lines.find((x) => x.id === lineId);\n if (l) {\n if (quantity <= 0) state.lines = state.lines.filter((x) => x.id !== lineId);\n else l.quantity = quantity;\n persist();\n }\n return cartObj;\n },\n removeLineItem(lineId: string): StorefrontCart {\n state.lines = state.lines.filter((x) => x.id !== lineId);\n persist();\n return cartObj;\n },\n clear(): StorefrontCart {\n state.lines = [];\n persist();\n return cartObj;\n },\n async checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession> {\n const session = await checkout.create(\n state.lines.map((l) => ({\n productId: l.productId,\n variantId: l.variantId,\n productName: l.productName,\n quantity: l.quantity,\n unitPrice: l.unitPrice,\n imageUrl: l.imageUrl,\n })),\n opts && opts.couponCode ? { couponCode: opts.couponCode } : undefined,\n );\n if (opts && opts.clearOnSuccess) cartObj.clear();\n return session;\n },\n };\n return cartObj;\n }\n\n const cart = {\n /** Create a new, empty cart (replaces any persisted cart) */\n create(): StorefrontCart {\n const st = freshCart();\n saveCart(st);\n return makeCart(st);\n },\n /** Get the current cart — loaded from storage if persisted, otherwise a fresh one */\n current(): StorefrontCart {\n return makeCart(loadCart() || freshCart());\n },\n /** Recover an abandoned cart by recovery token */\n async recover(token: string): Promise<CheckoutSession> {\n return request(\"GET\", `/abandoned-carts/recover/${token}`);\n },\n };\n\n // ── Alias namespaces (convenience wrappers over existing methods) ──\n\n /** Alias for `client.customer.orders` — order history for the logged-in customer */\n const orders = {\n /** Get customer's order history (delegates to `customer.orders`) */\n list: (params?: ListParams): Promise<PaginatedResponse<Order>> => customer.orders(params),\n };\n\n /** Convenience namespace bundling `auth` + `customer` under one name */\n const customers = {\n login: auth.login,\n register: auth.register,\n loginWithGoogle: auth.loginWithGoogle,\n logout: auth.logout,\n isAuthenticated: auth.isAuthenticated,\n setTokens: auth.setTokens,\n me: customer.me,\n orders: customer.orders,\n addresses: customer.addresses,\n };\n\n // ── Public API ───────────────────────────────────────────────────\n\n return {\n store,\n products,\n collections,\n discounts,\n checkout,\n auth,\n customer,\n blog,\n bookings,\n forms,\n cart,\n orders,\n customers,\n };\n}\n\n// ── Type export for TypeScript users ──\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>;\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ManageSales Storefront SDK\n * --------------------------\n * Resource-based client for building online storefronts.\n * Works with any framework: Next.js, Remix, Nuxt, Astro, plain HTML.\n *\n * Usage:\n * import { createStorefrontClient } from \"./managesales-storefront\";\n * const client = createStorefrontClient({ workspaceId: \"<workspace_id>\" });\n * const products = await client.products.list();\n */\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface RetryConfig {\n /** Max retry attempts for a failed request (default: 2) */\n retries?: number;\n /** Base delay in ms used for exponential backoff (default: 300) */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay, in ms (default: 4000) */\n maxDelayMs?: number;\n /** HTTP status codes that are retried, GET/HEAD only (default: [408,425,429,500,502,503,504]) */\n retryOnStatus?: number[];\n}\n\nexport interface StorefrontConfig {\n /** Your workspace ID (required) */\n workspaceId: string;\n /** API base URL — defaults to production */\n apiUrl?: string;\n /** Custom fetch implementation (for SSR / edge) */\n customFetch?: typeof fetch;\n /** Default locale for content */\n locale?: string;\n /**\n * Retry behavior for transient failures (network errors, and 5xx/408/425/429\n * responses on idempotent GET/HEAD requests). Pass `false` to disable retries\n * entirely. Defaults to 2 retries with exponential backoff.\n */\n retry?: RetryConfig | false;\n /**\n * Persist the stateful cart (`client.cart`) to `localStorage` so it survives\n * page reloads. Defaults to `true`. Has no effect in environments without\n * `localStorage` (e.g. Node/SSR) — the cart simply stays in-memory.\n */\n persistCart?: boolean;\n}\n\nexport interface ListParams {\n page?: number;\n limit?: number;\n search?: string;\n sort?: string;\n order?: \"asc\" | \"desc\";\n [key: string]: unknown;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n// ── Product types ──\n\nexport interface Product {\n id: string;\n name: string;\n slug: string;\n description: string;\n status: string;\n price: number;\n compareAtPrice?: number;\n currency: string;\n images: ProductImage[];\n variants: ProductVariant[];\n category?: { id: string; name: string };\n brand?: { id: string; name: string };\n tags: string[];\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProductImage {\n id: string;\n url: string;\n alt: string;\n position: number;\n}\n\nexport interface ProductVariant {\n id: string;\n name: string;\n sku: string;\n price: number;\n compareAtPrice?: number;\n inventory: number;\n options: Record<string, string>;\n}\n\n// ── Collection types ──\n\nexport interface Collection {\n id: string;\n name: string;\n slug: string;\n description: string;\n image?: string;\n productCount: number;\n}\n\n// ── Cart & Checkout types ──\n\nexport interface CheckoutLineItem {\n productId: string;\n variantId?: string;\n productName: string;\n quantity: number;\n unitPrice: number;\n imageUrl?: string;\n}\n\nexport interface CheckoutSessionLine {\n productId?: string;\n variantId?: string;\n productName: string;\n sku?: string;\n imageUrl?: string;\n quantity: number;\n unitPrice: number;\n}\n\nexport interface ShippingMethod {\n id: string;\n name: string;\n price: number;\n estimatedDays?: string;\n}\n\nexport interface CheckoutShippingAddress {\n name?: string;\n phone?: string;\n address?: string;\n city?: string;\n region?: string;\n country?: string;\n postalCode?: string;\n}\n\nexport interface CheckoutSession {\n id: string;\n status: \"open\" | \"completed\" | \"expired\";\n lines: CheckoutSessionLine[];\n subtotal: number;\n discountAmount: number;\n discountCode?: string;\n discountLabel?: string;\n taxAmount: number;\n taxLabel?: string;\n shippingAmount: number;\n shippingMethodId?: string;\n shippingMethodName?: string;\n shipping?: CheckoutShippingAddress;\n giftCardAmount?: number;\n giftCardCode?: string;\n availableShippingMethods?: ShippingMethod[];\n total: number;\n currency: string;\n createdAt?: string;\n /** @deprecated Never populated by the API — use `lines` */\n items?: CheckoutLineItem[];\n /** @deprecated Never populated by the API — use `taxAmount` */\n tax?: number;\n /** @deprecated Never populated by the API — use `discountAmount` */\n discount?: number;\n /** @deprecated Never populated by the API — use `discountCode` */\n couponCode?: string;\n}\n\nexport interface CartLine {\n id: string;\n productId: string;\n variantId?: string;\n quantity: number;\n unitPrice: number;\n productName: string;\n imageUrl?: string;\n}\n\nexport interface CartState {\n id: string;\n lines: CartLine[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AddCartLineItemInput {\n productId: string;\n variantId?: string;\n quantity: number;\n /** Skip the `products.get` price lookup by supplying these directly */\n unitPrice?: number;\n productName?: string;\n imageUrl?: string;\n}\n\nexport interface StorefrontCart {\n readonly id: string;\n readonly lines: CartLine[];\n readonly itemCount: number;\n readonly subtotal: number;\n /** Adds a line item. Supplying `unitPrice` also requires `productName`, otherwise this falls through to a `products.get` network lookup. */\n addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart>;\n updateLineItem(lineId: string, quantity: number): StorefrontCart;\n removeLineItem(lineId: string): StorefrontCart;\n clear(): StorefrontCart;\n checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession>;\n}\n\nexport interface Order {\n id: string;\n orderNumber: string;\n status: string;\n total: number;\n currency: string;\n items: OrderItem[];\n createdAt: string;\n}\n\nexport interface OrderItem {\n productId: string;\n name: string;\n quantity: number;\n price: number;\n}\n\n// ── Discount types ──\n\nexport interface DiscountValidationInput {\n /** Cart subtotal; omit when supplying `items` */\n subtotal?: number;\n items?: Array<{ productId?: string; variantId?: string; quantity: number; unitPrice: number }>;\n /** Known customer id — enables per-customer limit checks */\n customerId?: string;\n}\n\nexport interface DiscountValidationResult {\n valid: boolean;\n discountId?: string;\n code?: string;\n label?: string;\n amount?: number;\n freeShipping?: boolean;\n /** Present when `valid` is false — customer-safe explanation */\n reason?: string;\n}\n\nexport interface AutomaticPromotion {\n id: string;\n title: string;\n type: \"percentage\" | \"fixed_amount\" | \"buy_x_get_y\" | \"free_shipping\";\n value: number;\n minOrderAmount?: number | null;\n minQuantity?: number | null;\n endsAt?: string | null;\n}\n\nexport interface CreateCheckoutOptions {\n /** Coupon code applied server-side at session creation */\n couponCode?: string;\n}\n\n// ── Customer types ──\n\nexport interface Customer {\n id: string;\n email: string;\n name: string;\n phone?: string;\n createdAt: string;\n}\n\nexport interface AuthSession {\n customer: Customer;\n accessToken: string;\n refreshToken: string;\n}\n\nexport interface Address {\n id: string;\n label?: string;\n line1: string;\n line2?: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n isDefault: boolean;\n}\n\n// ── Blog types ──\n\nexport interface BlogPost {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage?: string;\n tags: string[];\n publishedAt: string;\n}\n\n// ── Booking types ──\n\nexport interface BookableService {\n id: string;\n name: string;\n duration: number;\n price: number;\n description: string;\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n id: string;\n serviceId: string;\n date: string;\n startTime: string;\n endTime: string;\n status: string;\n customer: { name: string; email: string };\n}\n\n// ── Form types ──\n\nexport interface FormDefinition {\n id: string;\n title: string;\n description: string;\n fields: FormField[];\n}\n\nexport interface FormField {\n id: string;\n type: string;\n label: string;\n required: boolean;\n options?: string[];\n placeholder?: string;\n}\n\n// ── Store config ──\n\nexport interface StoreConfig {\n name: string;\n slug: string;\n logo?: string;\n theme: Record<string, unknown>;\n currency: string;\n locale: string;\n}\n\n// ── SDK Error ──\n\nexport class StorefrontError extends Error {\n status: number;\n code: string;\n details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"StorefrontError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n// ── Core client ────────────────────────────────────────────────────\n\nexport function createStorefrontClient(config: StorefrontConfig) {\n const apiUrl = (config.apiUrl ?? \"https://api.managesales.io/api/v1\").replace(/\\/$/, \"\");\n const fetchFn = config.customFetch ?? globalThis.fetch.bind(globalThis);\n let accessToken: string | null = null;\n let refreshToken: string | null = null;\n\n // ── Retry configuration ──\n\n const RETRY_DEFAULTS = {\n retries: 2,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n retryOnStatus: [408, 425, 429, 500, 502, 503, 504],\n };\n const rc =\n config.retry === false\n ? { ...RETRY_DEFAULTS, retries: 0 }\n : { ...RETRY_DEFAULTS, ...(config.retry || {}) };\n const IDEMPOTENT = new Set([\"GET\", \"HEAD\"]);\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n function backoff(attempt: number): number {\n return Math.min(rc.maxDelayMs, Math.round(Math.random() * rc.baseDelayMs * Math.pow(2, attempt)));\n }\n\n // ── Internal helpers ──\n\n async function request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n params?: Record<string, unknown>;\n auth?: boolean;\n },\n ): Promise<T> {\n const url = new URL(`${apiUrl}${path}`);\n if (options?.params) {\n for (const [k, v] of Object.entries(options.params)) {\n if (v !== undefined && v !== null) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n \"X-Workspace-Id\": config.workspaceId,\n };\n\n if (options?.auth && accessToken) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n }\n\n if (options?.body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n };\n\n let attempt = 0;\n let res: Response;\n while (true) {\n try {\n res = await fetchFn(url.toString(), fetchOptions);\n } catch (err) {\n if (attempt < rc.retries) {\n await sleep(backoff(attempt));\n attempt++;\n continue;\n }\n throw err;\n }\n if (attempt < rc.retries && rc.retryOnStatus.includes(res.status) && IDEMPOTENT.has(method)) {\n const ra = Number(res.headers.get(\"retry-after\"));\n await sleep(Number.isFinite(ra) && ra > 0 ? ra * 1000 : backoff(attempt));\n attempt++;\n continue;\n }\n break;\n }\n\n // Auto-refresh on 401\n if (res.status === 401 && options?.auth && refreshToken) {\n const refreshed = await refreshSession();\n if (refreshed) {\n headers[\"Authorization\"] = `Bearer ${accessToken}`;\n const retry = await fetchFn(url.toString(), {\n method,\n headers,\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n if (!retry.ok) throw await parseError(retry);\n return retry.status === 204 ? (undefined as T) : retry.json();\n }\n }\n\n if (!res.ok) throw await parseError(res);\n return res.status === 204 ? (undefined as T) : res.json();\n }\n\n async function parseError(res: Response): Promise<StorefrontError> {\n try {\n const body = await res.json();\n return new StorefrontError(\n res.status,\n body.code ?? body.error ?? \"UNKNOWN\",\n body.message ?? res.statusText,\n body,\n );\n } catch {\n return new StorefrontError(res.status, \"UNKNOWN\", res.statusText);\n }\n }\n\n async function refreshSession(): Promise<boolean> {\n if (!refreshToken) return false;\n try {\n const res = await fetchFn(`${apiUrl}/storefront/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Workspace-Id\": config.workspaceId,\n },\n body: JSON.stringify({ refreshToken }),\n });\n if (!res.ok) {\n accessToken = null;\n refreshToken = null;\n return false;\n }\n const data = await res.json();\n accessToken = data.accessToken;\n refreshToken = data.refreshToken;\n return true;\n } catch {\n return false;\n }\n }\n\n // ── Resource namespaces ──────────────────────────────────────────\n\n const store = {\n /** Resolve store config by workspace (returns theme, branding, currency) */\n async resolve(): Promise<StoreConfig> {\n return request(\"GET\", \"/storefront-api/resolve\");\n },\n };\n\n const products = {\n /** List published products with pagination and filters */\n async list(params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/products\", { params });\n },\n /** Get a single product by ID or slug */\n async get(idOrSlug: string): Promise<Product> {\n return request(\"GET\", `/storefront-api/products/${idOrSlug}`);\n },\n /** Search products (shorthand for list with search param) */\n async search(query: string, params?: ListParams): Promise<PaginatedResponse<Product>> {\n return request(\"GET\", \"/storefront-api/search\", { params: { ...params, q: query } });\n },\n };\n\n const collections = {\n /** List published collections */\n async list(params?: ListParams): Promise<PaginatedResponse<Collection>> {\n return request(\"GET\", \"/storefront-api/collections\", { params });\n },\n /** Get a collection with its products */\n async get(idOrSlug: string): Promise<Collection & { products: Product[] }> {\n return request(\"GET\", `/storefront-api/collections/${idOrSlug}`);\n },\n };\n\n const discounts = {\n /** Preview a discount code against a cart before checkout. Never consumes usage. */\n async validate(code: string, input?: DiscountValidationInput): Promise<DiscountValidationResult> {\n return request(\"POST\", \"/storefront-api/discounts/validate\", { body: { code, ...(input || {}) } });\n },\n /** Active automatic promotions for display (codes are never exposed) */\n async automatic(): Promise<AutomaticPromotion[]> {\n return request(\"GET\", \"/storefront-api/discounts/automatic\");\n },\n };\n\n const checkout = {\n /** Create a checkout session from cart items */\n async create(items: CheckoutLineItem[], opts?: CreateCheckoutOptions): Promise<CheckoutSession> {\n const body: Record<string, unknown> = { lines: items };\n if (opts && opts.couponCode) body.couponCode = opts.couponCode;\n return request(\"POST\", \"/checkout\", { body });\n },\n /** Retrieve an existing checkout session */\n async get(checkoutId: string): Promise<CheckoutSession> {\n return request(\"GET\", `/checkout/${checkoutId}`);\n },\n /** Apply a coupon or discount code */\n async applyCoupon(checkoutId: string, couponCode: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/coupon`, { body: { code: couponCode } });\n },\n /** Apply a gift card to the checkout */\n async applyGiftCard(checkoutId: string, code: string): Promise<CheckoutSession> {\n return request(\"POST\", `/checkout/${checkoutId}/gift-card`, { body: { code } });\n },\n /** Complete checkout — process payment and create order */\n async complete(checkoutId: string, payment?: Record<string, unknown>): Promise<Order> {\n return request(\"POST\", `/checkout/${checkoutId}/complete`, { body: payment });\n },\n };\n\n const auth = {\n /** Register a new customer account */\n async register(data: {\n email: string;\n password: string;\n name: string;\n phone?: string;\n }): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/register\", { body: data });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with email + password */\n async login(email: string, password: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/login\", {\n body: { email, password },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log in with Google ID token */\n async loginWithGoogle(idToken: string): Promise<AuthSession> {\n const session = await request<AuthSession>(\"POST\", \"/storefront/auth/google\", {\n body: { idToken },\n });\n accessToken = session.accessToken;\n refreshToken = session.refreshToken;\n return session;\n },\n /** Log out and clear local session */\n async logout(): Promise<void> {\n if (accessToken) {\n try {\n await request(\"POST\", \"/storefront/auth/logout\", { auth: true });\n } catch { /* ignore logout errors */ }\n }\n accessToken = null;\n refreshToken = null;\n },\n /** Refresh the access token */\n async refresh(): Promise<boolean> {\n return refreshSession();\n },\n /** Check if client has a valid session */\n isAuthenticated(): boolean {\n return accessToken !== null;\n },\n /** Manually set tokens (e.g., from SSR or cookie restoration) */\n setTokens(access: string, refresh: string): void {\n accessToken = access;\n refreshToken = refresh;\n },\n };\n\n const customer = {\n /** Get current customer profile */\n async me(): Promise<Customer> {\n return request(\"GET\", \"/storefront/auth/me\", { auth: true });\n },\n /** Get customer's order history */\n async orders(params?: ListParams): Promise<PaginatedResponse<Order>> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/orders`, { params, auth: true });\n },\n /** Get customer's saved addresses */\n async addresses(): Promise<Address[]> {\n const me = await request<Customer>(\"GET\", \"/storefront/auth/me\", { auth: true });\n return request(\"GET\", `/storefront-api/customer/${me.id}/addresses`, { auth: true });\n },\n };\n\n const blog = {\n /** List published blog posts */\n async list(params?: ListParams & { tags?: string }): Promise<PaginatedResponse<BlogPost>> {\n return request(\"GET\", \"/storefront-api/blog/posts\", { params });\n },\n /** Get a blog post by slug */\n async get(slug: string): Promise<BlogPost> {\n return request(\"GET\", `/storefront-api/blog/posts/${slug}`);\n },\n };\n\n const bookings = {\n /** List bookable services */\n async services(): Promise<BookableService[]> {\n return request(\"GET\", \"/bookings-public/services\");\n },\n /** List bookable staff */\n async staff(): Promise<Array<{ id: string; name: string; avatar?: string }>> {\n return request(\"GET\", \"/bookings-public/staff\");\n },\n /** Check available time slots */\n async availability(params: {\n serviceId: string;\n date: string;\n staffId?: string;\n }): Promise<TimeSlot[]> {\n return request(\"GET\", \"/bookings-public/availability\", { params });\n },\n /** Create a booking */\n async book(data: {\n serviceId: string;\n date: string;\n startTime: string;\n staffId?: string;\n customer: { name: string; email: string; phone?: string };\n }): Promise<Booking> {\n return request(\"POST\", \"/bookings-public/book\", { body: data });\n },\n };\n\n const forms = {\n /** Get a published form by ID or slug */\n async get(idOrSlug: string): Promise<FormDefinition> {\n return request(\"GET\", `/public/forms/${idOrSlug}`);\n },\n /** Submit form response */\n async submit(formId: string, data: Record<string, unknown>): Promise<{ id: string }> {\n return request(\"POST\", `/public/forms/${formId}/submit`, { body: data });\n },\n /** Upload file for a form file field */\n async uploadFile(formId: string, file: File): Promise<{ url: string }> {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetchFn(`${apiUrl}/public/forms/${formId}/upload`, {\n method: \"POST\",\n headers: { \"X-Workspace-Id\": config.workspaceId },\n body: formData,\n });\n if (!res.ok) throw await parseError(res);\n return res.json();\n },\n };\n\n // ── Stateful cart (client-side, localStorage-persisted) ──\n\n const CART_KEY = \"managesales_cart_\" + config.workspaceId;\n const hasLS = () => {\n try {\n return config.persistCart !== false && typeof localStorage !== \"undefined\";\n } catch {\n return false;\n }\n };\n const loadCart = (): CartState | null => {\n if (!hasLS()) return null;\n try {\n const s = localStorage.getItem(CART_KEY);\n return s ? JSON.parse(s) : null;\n } catch {\n return null;\n }\n };\n const saveCart = (st: CartState): void => {\n if (!hasLS()) return;\n try {\n localStorage.setItem(CART_KEY, JSON.stringify(st));\n } catch {\n /* ignore persistence errors (quota, privacy mode, etc.) */\n }\n };\n let __lineSeq = 0;\n const genId = (p: string): string =>\n typeof crypto !== \"undefined\" && crypto.randomUUID ? p + crypto.randomUUID() : p + Date.now() + \"_\" + ++__lineSeq;\n const nowIso = (): string => new Date().toISOString();\n const freshCart = (): CartState => ({ id: genId(\"cart_\"), lines: [], createdAt: nowIso(), updatedAt: nowIso() });\n\n function makeCart(state: CartState): StorefrontCart {\n const persist = () => {\n state.updatedAt = nowIso();\n saveCart(state);\n };\n const cartObj: StorefrontCart = {\n get id() {\n return state.id;\n },\n get lines() {\n return state.lines;\n },\n get itemCount() {\n return state.lines.reduce((n, l) => n + l.quantity, 0);\n },\n get subtotal() {\n return state.lines.reduce((s, l) => s + l.unitPrice * l.quantity, 0);\n },\n // Supplying unitPrice alone does not skip the lookup — productName must also be\n // provided, otherwise this falls through to the products.get() network lookup below.\n async addLineItem(input: AddCartLineItemInput): Promise<StorefrontCart> {\n let line: CartLine;\n if (input.unitPrice != null && input.productName) {\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n productName: input.productName,\n imageUrl: input.imageUrl,\n };\n } else {\n const p = await products.get(input.productId);\n const v = input.variantId && Array.isArray(p.variants) ? p.variants.find((x) => x.id === input.variantId) : undefined;\n line = {\n id: genId(\"line_\"),\n productId: input.productId,\n variantId: input.variantId,\n quantity: input.quantity,\n unitPrice: v && v.price != null ? v.price : p.price,\n productName: p.name,\n imageUrl: Array.isArray(p.images) && p.images.length > 0 ? p.images[0].url : undefined,\n };\n }\n const existing = state.lines.find((l) => l.productId === line.productId && l.variantId === line.variantId);\n if (existing) existing.quantity += line.quantity;\n else state.lines.push(line);\n persist();\n return cartObj;\n },\n updateLineItem(lineId: string, quantity: number): StorefrontCart {\n const l = state.lines.find((x) => x.id === lineId);\n if (l) {\n if (quantity <= 0) state.lines = state.lines.filter((x) => x.id !== lineId);\n else l.quantity = quantity;\n persist();\n }\n return cartObj;\n },\n removeLineItem(lineId: string): StorefrontCart {\n state.lines = state.lines.filter((x) => x.id !== lineId);\n persist();\n return cartObj;\n },\n clear(): StorefrontCart {\n state.lines = [];\n persist();\n return cartObj;\n },\n async checkout(opts?: { clearOnSuccess?: boolean; couponCode?: string }): Promise<CheckoutSession> {\n const session = await checkout.create(\n state.lines.map((l) => ({\n productId: l.productId,\n variantId: l.variantId,\n productName: l.productName,\n quantity: l.quantity,\n unitPrice: l.unitPrice,\n imageUrl: l.imageUrl,\n })),\n opts && opts.couponCode ? { couponCode: opts.couponCode } : undefined,\n );\n if (opts && opts.clearOnSuccess) cartObj.clear();\n return session;\n },\n };\n return cartObj;\n }\n\n const cart = {\n /** Create a new, empty cart (replaces any persisted cart) */\n create(): StorefrontCart {\n const st = freshCart();\n saveCart(st);\n return makeCart(st);\n },\n /** Get the current cart — loaded from storage if persisted, otherwise a fresh one */\n current(): StorefrontCart {\n return makeCart(loadCart() || freshCart());\n },\n /** Recover an abandoned cart by recovery token */\n async recover(token: string): Promise<CheckoutSession> {\n return request(\"GET\", `/abandoned-carts/recover/${token}`);\n },\n };\n\n // ── Alias namespaces (convenience wrappers over existing methods) ──\n\n /** Alias for `client.customer.orders` — order history for the logged-in customer */\n const orders = {\n /** Get customer's order history (delegates to `customer.orders`) */\n list: (params?: ListParams): Promise<PaginatedResponse<Order>> => customer.orders(params),\n };\n\n /** Convenience namespace bundling `auth` + `customer` under one name */\n const customers = {\n login: auth.login,\n register: auth.register,\n loginWithGoogle: auth.loginWithGoogle,\n logout: auth.logout,\n isAuthenticated: auth.isAuthenticated,\n setTokens: auth.setTokens,\n me: customer.me,\n orders: customer.orders,\n addresses: customer.addresses,\n };\n\n // ── Public API ───────────────────────────────────────────────────\n\n return {\n store,\n products,\n collections,\n discounts,\n checkout,\n auth,\n customer,\n blog,\n bookings,\n forms,\n cart,\n orders,\n customers,\n };\n}\n\n// ── Type export for TypeScript users ──\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@managesales/storefront",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Resource-based TypeScript client for building storefronts on the ManageSales Storefront API. Zero runtime dependencies, built-in auth and token refresh.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",