@asteby/storefront 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/money.ts","../src/query.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { StorefrontErrorCode } from './types.js'\n\nexport type StorefrontErrorInit = {\n status: number\n code: StorefrontErrorCode\n message: string\n field?: string\n /** Request URL that failed (without credentials). */\n url?: string\n cause?: unknown\n}\n\n/**\n * Error thrown by the client for any non-2xx response, network failure,\n * timeout or abort. `status` is `0` when no HTTP response was received.\n */\nexport class StorefrontError extends Error {\n override readonly name = 'StorefrontError'\n readonly status: number\n readonly code: StorefrontErrorCode\n readonly field: string | undefined\n readonly url: string | undefined\n\n constructor(init: StorefrontErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause })\n this.status = init.status\n this.code = init.code\n this.field = init.field\n this.url = init.url\n }\n\n toJSON() {\n return { name: this.name, status: this.status, code: this.code, message: this.message, field: this.field }\n }\n}\n\nexport function isStorefrontError(err: unknown): err is StorefrontError {\n return err instanceof StorefrontError || (typeof err === 'object' && err !== null && (err as { name?: unknown }).name === 'StorefrontError')\n}\n\nconst STATUS_CODES: Record<number, StorefrontErrorCode> = {\n 400: 'validation',\n 401: 'unauthorized',\n 403: 'forbidden',\n 404: 'not_found',\n 409: 'conflict',\n 422: 'invalid_state',\n 429: 'rate_limited',\n}\n\nexport function defaultCodeForStatus(status: number): StorefrontErrorCode {\n return STATUS_CODES[status] ?? (status >= 500 ? 'server_error' : 'invalid_response')\n}\n","import type { Money } from './types.js'\n\nexport type FormatMoneyOptions = {\n /** Drop `.00` when the amount is a whole number. */\n withoutTrailingZeros?: boolean\n /** Format as a plain number, without the currency symbol. */\n withoutCurrency?: boolean\n /** `symbol` (default), `narrowSymbol`, `code` or `name`. */\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name'\n}\n\n/** Parses a contract `Money` amount into a JS number (`\"1899.00\"` → `1899`). */\nexport function parseMoney(money: Money | string | null | undefined): number {\n if (money == null) return 0\n const raw = typeof money === 'string' ? money : money.amount\n const n = Number.parseFloat(raw)\n return Number.isFinite(n) ? n : 0\n}\n\n/**\n * Formats `Money` with `Intl.NumberFormat`. Works in every runtime (no DOM).\n * Falls back to `\"<amount> <code>\"` when the runtime lacks the currency.\n */\nexport function formatMoney(money: Money, locale?: string, options: FormatMoneyOptions = {}): string {\n const value = parseMoney(money)\n const whole = Number.isInteger(value)\n const digits = options.withoutTrailingZeros && whole ? 0 : undefined\n try {\n const fmt = new Intl.NumberFormat(locale, {\n ...(options.withoutCurrency\n ? { style: 'decimal', minimumFractionDigits: digits ?? 2, maximumFractionDigits: digits ?? 2 }\n : {\n style: 'currency',\n currency: money.currency_code,\n currencyDisplay: options.currencyDisplay ?? 'symbol',\n ...(digits === 0 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}),\n }),\n })\n return fmt.format(value)\n } catch {\n const amount = digits === 0 ? String(value) : value.toFixed(2)\n return options.withoutCurrency ? amount : `${amount} ${money.currency_code}`\n }\n}\n\n/** Builds a `Money` from a number, rounding to cents. */\nexport function toMoney(value: number, currencyCode: string): Money {\n return { amount: (Math.round(value * 100) / 100).toFixed(2), currency_code: currencyCode }\n}\n\n/**\n * True for public (`pk_`) tokens, the only ones that may reach a browser.\n * Private (`sk_`) tokens must stay on the server.\n */\nexport function isTokenPublishable(token: string | null | undefined): boolean {\n return typeof token === 'string' && token.startsWith('pk_')\n}\n","import type { ProductSort } from './types.js'\n\nexport type QueryValue = string | number | boolean | null | undefined\nexport type QueryParams = Record<string, QueryValue | QueryValue[]>\n\nexport type PaginationParams = {\n /** Page size (1–100; articles accept at most 50). */\n first?: number\n /** Cursor from `page_info.end_cursor`. */\n after?: string | null\n}\n\nexport type ProductListParams = PaginationParams & {\n /** Free-text search. */\n q?: string\n /** Collection handle. */\n collection?: string\n sort?: ProductSort\n /** Only products available for sale. */\n available?: boolean\n price_min?: number | string\n price_max?: number | string\n /**\n * Attribute filters, serialized as repeated `filter.<key>=<value>` params.\n * Values of one key are OR-ed; different keys are AND-ed.\n * e.g. `{ vendor: ['A', 'B'], rim: 16 }`.\n */\n filters?: Record<string, QueryValue | QueryValue[]>\n /** Restrict to these handles (max 100). Serialized comma-separated. */\n handles?: string[]\n}\n\nexport type CollectionListParams = PaginationParams\n\nexport type ArticleListParams = Omit<PaginationParams, 'first'> & {\n /** Page size (1–50). The API answers 400 `validation` above 50. */\n first?: number\n tag?: string\n q?: string\n}\n\n/** Appends params to a URLSearchParams, repeating keys for arrays and skipping nullish values. */\nexport function appendParams(search: URLSearchParams, params: QueryParams | undefined): URLSearchParams {\n if (!params) return search\n for (const [key, raw] of Object.entries(params)) {\n const values = Array.isArray(raw) ? raw : [raw]\n for (const v of values) {\n if (v === undefined || v === null || v === '') continue\n search.append(key, String(v))\n }\n }\n return search\n}\n\n/** Serializes product list params per the contract (`filter.<attr>` repeated, `handles` comma-separated). */\nexport function productListQuery(params: ProductListParams = {}): URLSearchParams {\n const { filters, handles, ...rest } = params\n const search = appendParams(new URLSearchParams(), rest as QueryParams)\n if (handles && handles.length > 0) search.set('handles', handles.join(','))\n if (filters) {\n for (const [key, raw] of Object.entries(filters)) {\n const name = key.startsWith('filter.') ? key : `filter.${key}`\n appendParams(search, { [name]: raw })\n }\n }\n return search\n}\n\n/** Reads `filter.<key>` params back into a filters record (useful in route loaders). */\nexport function parseProductFilters(search: URLSearchParams): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const [key, value] of search) {\n if (!key.startsWith('filter.')) continue\n const name = key.slice('filter.'.length)\n ;(out[name] ??= []).push(value)\n }\n return out\n}\n","import { StorefrontError, defaultCodeForStatus } from './errors.js'\nimport { isTokenPublishable } from './money.js'\nimport {\n appendParams,\n productListQuery,\n type ArticleListParams,\n type CollectionListParams,\n type PaginationParams,\n type ProductListParams,\n type QueryParams,\n} from './query.js'\nimport type {\n Address,\n AddressInput,\n Article,\n Cart,\n CartBuyerInput,\n CartLineInput,\n CartLineUpdateInput,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerSession,\n CustomerSessionInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n InvoiceRequest,\n InvoiceResult,\n Menu,\n Order,\n Page,\n Product,\n ProductConnection,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n} from './types.js'\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\n/** Context passed to `onRequest` / `onResponse` hooks. */\nexport type StorefrontRequestContext = {\n method: string\n /** Absolute URL, including the query string. */\n url: string\n /** Route path relative to `baseUrl`, e.g. `/storefront/products/abc`. */\n path: string\n /** Final `RequestInit` (headers already merged). Hooks may mutate it. */\n init: RequestInit & { headers: Headers }\n /** Per-call options as given by the caller. */\n options: RequestOptions\n}\n\nexport type StorefrontResponseContext = StorefrontRequestContext & {\n response: Response\n /** Milliseconds spent waiting for the response. */\n durationMs: number\n}\n\nexport type StorefrontClientOptions = {\n /** Base URL of the gateway, e.g. `https://ops.example.com/api/gw`. Routes are appended as `/storefront/...`. */\n baseUrl: string\n /** `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. */\n token: string\n /** Buyer session (`X-Customer-Token`) for `/storefront/customer/*` routes. */\n customerToken?: string | null\n /** Custom fetch (defaults to `globalThis.fetch`). */\n fetch?: FetchLike\n /** Sent as `Accept-Language`. */\n locale?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /** Abort requests that take longer than this (default: no timeout). */\n timeoutMs?: number\n /**\n * Runs before every request. Return a `Response` to short-circuit the\n * network (e.g. an SSR cache hit); return nothing to continue.\n */\n onRequest?: (ctx: StorefrontRequestContext) => void | Response | Promise<void | Response>\n /** Runs after every response (including short-circuited ones), before parsing. */\n onResponse?: (ctx: StorefrontResponseContext) => void | Promise<void>\n}\n\n/** Per-call options. Unknown keys (e.g. Next.js `next`) are forwarded to `fetch` as-is. */\nexport type RequestOptions = {\n cache?: RequestCache\n signal?: AbortSignal\n /** Framework fetch extensions, forwarded verbatim (e.g. `{ revalidate: 60, tags: ['products'] }`). */\n next?: Record<string, unknown>\n headers?: Record<string, string>\n /** Overrides the client-level timeout for this call. */\n timeoutMs?: number\n /** Overrides the client-level customer token for this call. */\n customerToken?: string | null\n [key: string]: unknown\n}\n\nexport type WriteOptions = RequestOptions & {\n /** `Idempotency-Key` header. Auto-generated for checkout when omitted. */\n idempotencyKey?: string\n}\n\nexport type PreviewOptions = RequestOptions & {\n /** Signed preview token: returns the draft (`private, no-store`). */\n preview?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'\n\ntype RequestSpec = {\n method: HttpMethod\n path: string\n query?: URLSearchParams | QueryParams\n body?: unknown\n options?: WriteOptions\n /** Resolve `null` instead of throwing on 404. */\n nullOn404?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'idempotencyKey', 'preview', 'signal'])\n\n/** Generates an idempotency key (crypto.randomUUID when available). */\nexport function generateIdempotencyKey(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (c?.randomUUID) return c.randomUUID()\n // Non-cryptographic fallback for very old runtimes; the key only needs to be unique.\n return 'idem-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2)\n}\n\nfunction joinUrl(baseUrl: string, path: string): string {\n return baseUrl.replace(/\\/+$/, '') + path\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment)\n}\n\nfunction linkSignals(signals: (AbortSignal | undefined)[]): { signal: AbortSignal | undefined; cleanup: () => void } {\n const active = signals.filter((s): s is AbortSignal => !!s)\n if (active.length === 0) return { signal: undefined, cleanup: () => {} }\n if (active.length === 1) return { signal: active[0], cleanup: () => {} }\n const controller = new AbortController()\n const listeners: [AbortSignal, () => void][] = []\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason)\n break\n }\n const on = () => controller.abort(s.reason)\n s.addEventListener('abort', on, { once: true })\n listeners.push([s, on])\n }\n return {\n signal: controller.signal,\n cleanup: () => listeners.forEach(([s, on]) => s.removeEventListener('abort', on)),\n }\n}\n\nasync function readError(res: Response, url: string): Promise<StorefrontError> {\n let body: Partial<StorefrontErrorBody> | undefined\n try {\n const text = await res.text()\n body = text ? (JSON.parse(text) as Partial<StorefrontErrorBody>) : undefined\n } catch {\n body = undefined\n }\n const e = body?.error\n return new StorefrontError({\n status: res.status,\n code: e?.code ?? defaultCodeForStatus(res.status),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n url,\n })\n}\n\nexport function createStorefrontClient(config: StorefrontClientOptions) {\n if (!config.baseUrl) throw new TypeError('createStorefrontClient: baseUrl is required')\n if (!config.token) throw new TypeError('createStorefrontClient: token is required')\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n if (isBrowser && !isTokenPublishable(config.token) && config.token.startsWith('sk_')) {\n console.warn('[@asteby/storefront] A private sk_ token is being used in a browser. Use a public pk_ token instead.')\n }\n\n async function request<T>(spec: RequestSpec & { nullOn404: true }): Promise<T | null>\n async function request<T>(spec: RequestSpec): Promise<T>\n async function request<T>(spec: RequestSpec): Promise<T | null> {\n const fetchImpl: FetchLike | undefined = config.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new TypeError('createStorefrontClient: no fetch available; pass `fetch` in options')\n\n const options: WriteOptions = spec.options ?? {}\n const search = spec.query instanceof URLSearchParams ? spec.query : appendParams(new URLSearchParams(), spec.query)\n const qs = search.toString()\n const url = joinUrl(config.baseUrl, spec.path) + (qs ? `?${qs}` : '')\n\n const headers = new Headers(config.headers)\n headers.set('Accept', 'application/json')\n headers.set('Authorization', `Bearer ${config.token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n if (options.idempotencyKey) headers.set('Idempotency-Key', options.idempotencyKey)\n if (spec.body !== undefined) headers.set('Content-Type', 'application/json')\n for (const [k, v] of Object.entries(options.headers ?? {})) headers.set(k, v)\n\n // Forward passthrough options (cache, next, ...) to fetch.\n const passthrough: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(options)) if (!OWN_OPTION_KEYS.has(k) && v !== undefined) passthrough[k] = v\n\n const timeoutMs = options.timeoutMs ?? config.timeoutMs\n const timeoutController = timeoutMs && timeoutMs > 0 ? new AbortController() : undefined\n const timer = timeoutController\n ? setTimeout(() => timeoutController.abort(new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url })), timeoutMs)\n : undefined\n const linked = linkSignals([options.signal, timeoutController?.signal])\n\n const init: RequestInit & { headers: Headers } = {\n ...passthrough,\n method: spec.method,\n headers,\n ...(spec.body !== undefined ? { body: JSON.stringify(spec.body) } : {}),\n ...(linked.signal ? { signal: linked.signal } : {}),\n }\n const ctx: StorefrontRequestContext = { method: spec.method, url, path: spec.path, init, options }\n\n const started = Date.now()\n let res: Response\n try {\n const hooked = config.onRequest ? await config.onRequest(ctx) : undefined\n res = hooked instanceof Response ? hooked : await fetchImpl(url, init)\n } catch (err) {\n if (timeoutController?.signal.aborted) {\n throw new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url, cause: err })\n }\n if (options.signal?.aborted) {\n throw new StorefrontError({ status: 0, code: 'aborted', message: 'Request aborted', url, cause: err })\n }\n if (err instanceof StorefrontError) throw err\n throw new StorefrontError({ status: 0, code: 'network', message: err instanceof Error ? err.message : 'Network error', url, cause: err })\n } finally {\n if (timer) clearTimeout(timer)\n linked.cleanup()\n }\n\n if (config.onResponse) await config.onResponse({ ...ctx, response: res, durationMs: Date.now() - started })\n\n if (res.status === 404 && spec.nullOn404) {\n // Drain the body so the connection can be reused.\n await res.text().catch(() => undefined)\n return null\n }\n if (res.status === 304) {\n throw new StorefrontError({ status: 304, code: 'not_modified', message: 'Not modified', url })\n }\n if (!res.ok) throw await readError(res, url)\n if (res.status === 204) return undefined as T\n\n const text = await res.text()\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch (err) {\n throw new StorefrontError({ status: res.status, code: 'invalid_response', message: 'Response is not valid JSON', url, cause: err })\n }\n }\n\n const get = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const getOrNull = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, nullOn404: true, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const write = <T>(method: HttpMethod, path: string, body?: unknown, options?: WriteOptions) =>\n request<T>({ method, path, ...(body !== undefined ? { body } : {}), ...(options ? { options } : {}) })\n\n const cartPath = (id: string, rest = '') => `/storefront/carts/${enc(id)}${rest}`\n const previewQuery = (options?: PreviewOptions) => (options?.preview ? { preview: options.preview } : undefined)\n\n const client = {\n /** Resolved configuration (read-only). */\n config: Object.freeze({ ...config }) as Readonly<StorefrontClientOptions>,\n\n /** Low-level escape hatch: any route under `baseUrl`. */\n request,\n\n /** Returns a new client that sends the given buyer session token. */\n withCustomerToken(customerToken: string | null) {\n return createStorefrontClient({ ...config, customerToken })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n products: {\n list: (params?: ProductListParams, options?: RequestOptions) =>\n get<ProductConnection>('/storefront/products', productListQuery(params), options),\n /** `null` when the product does not exist or is unpublished. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Product>(`/storefront/products/${enc(handle)}`, undefined, options),\n recommendations: (handle: string, options?: RequestOptions) =>\n get<{ nodes: Product[] }>(`/storefront/products/${enc(handle)}/recommendations`, undefined, options),\n },\n\n collections: {\n list: (params?: CollectionListParams, options?: RequestOptions) =>\n get<Connection<Collection>>('/storefront/collections', params as QueryParams, options),\n /** `null` when the collection does not exist. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Collection>(`/storefront/collections/${enc(handle)}`, undefined, options),\n },\n\n stock: {\n /** Stock for up to 250 SKUs. */\n get: (skus: string[], options?: RequestOptions) =>\n get<{ nodes: StockLevel[] }>('/storefront/stock', { sku: skus }, options),\n },\n\n carts: {\n create: (input: { lines?: CartLineInput[] } = {}, options?: WriteOptions) =>\n write<Cart>('POST', '/storefront/carts', input, options),\n /** `null` when the cart does not exist (e.g. expired cookie). */\n get: (id: string, options?: RequestOptions) => getOrNull<Cart>(cartPath(id), undefined, options),\n addLines: (id: string, lines: CartLineInput[], options?: WriteOptions) =>\n write<Cart>('POST', cartPath(id, '/lines'), { lines }, options),\n /** Quantity `0` removes the line. */\n updateLines: (id: string, lines: CartLineUpdateInput[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines }, options),\n removeLines: (id: string, lineIds: string[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines: lineIds.map((lid) => ({ id: lid, quantity: 0 })) }, options),\n setDiscountCodes: (id: string, codes: string[], options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/discount-codes'), { codes }, options),\n setBuyer: (id: string, buyer: CartBuyerInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/buyer'), buyer, options),\n setShippingAddress: (id: string, address: AddressInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/shipping-address'), address, options),\n deliveryOptions: (id: string, options?: RequestOptions) =>\n get<DeliveryOptions>(cartPath(id, '/delivery-options'), undefined, options),\n /** Payment providers active for the cart's market; send the chosen `key` as `payment_method`. */\n paymentMethods: (id: string, options?: RequestOptions) =>\n get<PaymentMethods>(cartPath(id, '/payment-methods'), undefined, options),\n setDelivery: (id: string, delivery: DeliveryInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/delivery'), delivery, options),\n /** Reserves stock and creates the order. Sends `Idempotency-Key` (auto-generated if omitted). */\n checkout: (id: string, input: CheckoutInput, options: WriteOptions = {}) =>\n write<CheckoutResult>('POST', cartPath(id, '/checkout'), input, {\n ...options,\n idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),\n }),\n },\n\n checkouts: {\n /**\n * Reads a placed checkout (same shape as the `carts.checkout` result). `order.number` is `null` until OPS\n * has created the order (a few hundred ms after checkout); poll once or twice and, if it is still `null`,\n * keep telling the buyer the number will arrive by email. Needs a server token (`checkout:write`).\n * `null` when the checkout does not exist. Never cache.\n */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<CheckoutResult>(`/storefront/checkouts/${enc(id)}`, undefined, options),\n },\n\n customer: {\n /** Sends a one-time code by email or SMS/WhatsApp. */\n requestOtp: (identifier: CustomerIdentifier, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/otp', identifier, options),\n /** Exchanges the code for a buyer session (`token` goes in `customerToken`). */\n createSession: (input: CustomerSessionInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/session', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n orders: (params?: PaginationParams, options?: RequestOptions) =>\n get<Connection<Order>>('/storefront/customer/orders', params as QueryParams, options),\n /** `null` when the order does not exist or belongs to someone else. */\n order: (id: string, options?: RequestOptions) =>\n getOrNull<Order>(`/storefront/customer/orders/${enc(id)}`, undefined, options),\n requestReturn: (orderId: string, input: ReturnRequestInput, options?: WriteOptions) =>\n write<ReturnRequest>('POST', `/storefront/customer/orders/${enc(orderId)}/returns`, input, options),\n requestInvoice: (orderId: string, input: InvoiceRequest, options?: WriteOptions) =>\n write<InvoiceResult>('POST', `/storefront/customer/orders/${enc(orderId)}/invoice`, input, options),\n addresses: {\n list: (options?: RequestOptions) => get<{ nodes: Address[] }>('/storefront/customer/addresses', undefined, options),\n create: (address: AddressInput, options?: WriteOptions) =>\n write<Address>('POST', '/storefront/customer/addresses', address, options),\n update: (id: string, address: Partial<AddressInput>, options?: WriteOptions) =>\n write<Address>('PATCH', `/storefront/customer/addresses/${enc(id)}`, address, options),\n delete: (id: string, options?: WriteOptions) =>\n write<void>('DELETE', `/storefront/customer/addresses/${enc(id)}`, undefined, options),\n },\n },\n\n content: {\n theme: (options?: RequestOptions) => get<Theme>('/storefront/content/theme', undefined, options),\n /** `null` when the page does not exist. */\n page: (handle: string, options?: PreviewOptions) =>\n getOrNull<Page>(`/storefront/content/pages/${enc(handle)}`, previewQuery(options), options),\n /** `null` when the menu does not exist. */\n menu: (handle: string, options?: RequestOptions) =>\n getOrNull<Menu>(`/storefront/content/menus/${enc(handle)}`, undefined, options),\n articles: (params?: ArticleListParams, options?: RequestOptions) =>\n get<Connection<Article>>('/storefront/content/articles', params as QueryParams, options),\n /** `null` when the article does not exist. */\n article: (handle: string, options?: PreviewOptions) =>\n getOrNull<Article>(`/storefront/content/articles/${enc(handle)}`, previewQuery(options), options),\n },\n }\n return client\n}\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/geo.ts","../src/money.ts","../src/query.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { StorefrontErrorCode } from './types.js'\n\nexport type StorefrontErrorInit = {\n status: number\n code: StorefrontErrorCode\n message: string\n field?: string\n /** Request URL that failed (without credentials). */\n url?: string\n cause?: unknown\n}\n\n/**\n * Error thrown by the client for any non-2xx response, network failure,\n * timeout or abort. `status` is `0` when no HTTP response was received.\n */\nexport class StorefrontError extends Error {\n override readonly name = 'StorefrontError'\n readonly status: number\n readonly code: StorefrontErrorCode\n readonly field: string | undefined\n readonly url: string | undefined\n\n constructor(init: StorefrontErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause })\n this.status = init.status\n this.code = init.code\n this.field = init.field\n this.url = init.url\n }\n\n toJSON() {\n return { name: this.name, status: this.status, code: this.code, message: this.message, field: this.field }\n }\n}\n\nexport function isStorefrontError(err: unknown): err is StorefrontError {\n return err instanceof StorefrontError || (typeof err === 'object' && err !== null && (err as { name?: unknown }).name === 'StorefrontError')\n}\n\nconst STATUS_CODES: Record<number, StorefrontErrorCode> = {\n 400: 'validation',\n 401: 'unauthorized',\n 403: 'forbidden',\n 404: 'not_found',\n 409: 'conflict',\n 422: 'invalid_state',\n 429: 'rate_limited',\n}\n\nexport function defaultCodeForStatus(status: number): StorefrontErrorCode {\n return STATUS_CODES[status] ?? (status >= 500 ? 'server_error' : 'invalid_response')\n}\n","/**\n * Geo helpers: pure TypeScript, no network and no DOM. Works in Node 20, edge\n * runtimes and browsers. Behaviour is pinned by `geo-vectors.json`, which the\n * Go side copies verbatim, so keep both implementations in sync.\n */\n\nexport type GeoPoint = { lat: number; lng: number }\n\n/** `(0, 0)` means \"unset\" on this platform, so it is never a valid point. */\ntype MaybePoint = { lat?: number | null; lng?: number | null } | null | undefined\n\nexport type OpeningHours = {\n /** `day`: 1 = Monday ... 7 = Sunday. Several entries per day are allowed. A `close` at or before `open` crosses midnight. */\n weekly: { day: number; open: string; close: string }[]\n /** Dated overrides of the weekly rule. `closed`, or both `open` and `close`. */\n exceptions?: { date: string; closed?: true; open?: string; close?: string; note?: string }[]\n}\n\nexport type OpenStatus = {\n open: boolean\n /** ISO instant (UTC) when the current interval ends; `null` when closed. */\n closesAt: string | null\n /** ISO instant (UTC) of the next opening; `null` when open or none within 8 days. */\n nextOpenAt: string | null\n}\n\nconst RAD = Math.PI / 180\n\n/** Great-circle distance in km (haversine, earth radius 6371.0088 km). */\nexport function distanceKm(a: GeoPoint, b: GeoPoint): number {\n const dLat = (b.lat - a.lat) * RAD\n const dLng = (b.lng - a.lng) * RAD\n const h = Math.sin(dLat / 2) ** 2 + Math.cos(a.lat * RAD) * Math.cos(b.lat * RAD) * Math.sin(dLng / 2) ** 2\n return 2 * 6371.0088 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h))\n}\n\n/** Finite, in range and not the `(0, 0)` \"unset\" pair. */\nexport function isValidPoint(p: MaybePoint): p is GeoPoint {\n const { lat, lng } = p ?? {}\n // Number.isFinite is false for null, undefined and non-numbers.\n return Number.isFinite(lat) && Number.isFinite(lng) && Math.abs(lat!) <= 90 && Math.abs(lng!) <= 180 && !(lat === 0 && lng === 0)\n}\n\n/** `'19.43,-99.13'` (spaces allowed) to a point; `null` when malformed or invalid. */\nexport function parseLatLng(s: string | null | undefined): GeoPoint | null {\n const [a, b, ...rest] = (s ?? '').split(',')\n const p = !rest.length && a?.trim() && b?.trim() ? { lat: Number(a), lng: Number(b) } : null\n return isValidPoint(p) ? p : null\n}\n\nexport type RankOptions<T> = {\n /** Keep items at most this far away (inclusive). */\n radiusKm?: number\n /** Keep the first N after sorting. */\n limit?: number\n /** Defaults to reading `lat` / `lng` from the item. */\n getPoint?: (item: T) => MaybePoint\n}\n\n/**\n * Sorts by distance from `origin` (stable: ties keep input order). Items without\n * a valid point are EXCLUDED, not placed last, because they have no distance.\n */\nexport function rankByDistance<T>(\n items: readonly T[],\n origin: GeoPoint,\n { radiusKm, limit, getPoint = (i) => i as MaybePoint }: RankOptions<T> = {},\n): { item: T; distanceKm: number }[] {\n const out: { item: T; distanceKm: number }[] = []\n for (const item of items) {\n const p = getPoint(item)\n if (!isValidPoint(p)) continue\n const d = distanceKm(origin, p)\n if (radiusKm === undefined || d <= radiusKm) out.push({ item, distanceKm: d })\n }\n // Array.prototype.sort is stable (ES2019), so ties keep input order.\n out.sort((x, y) => x.distanceKm - y.distanceKm)\n return limit === undefined ? out : out.slice(0, Math.max(0, limit))\n}\n\n/** Under 1 km: meters rounded to 50 m. Otherwise km with one decimal. */\nexport function formatDistance(km: number, locale = 'es-MX'): string {\n const m = Math.round((km * 1000) / 50) * 50\n const [value, unit, digits] = m < 1000 ? [m, 'meter', 0] : [km, 'kilometer', 1]\n return new Intl.NumberFormat(locale, {\n style: 'unit', unit, minimumFractionDigits: digits, maximumFractionDigits: digits,\n }).format(value)\n}\n\n/** Destination for directions: coordinates when valid, else the address text. */\nexport function directionsUrl(\n location: { lat?: number | null; lng?: number | null; address?: string | null; city?: string | null },\n { provider = 'google' }: { provider?: 'google' | 'apple' | 'geo' } = {},\n): string | null {\n const ll = isValidPoint(location) ? `${location.lat},${location.lng}` : null\n const text = [location.address, location.city].filter(Boolean).join(', ')\n const dest = ll ?? text\n if (!dest) return null\n const q = encodeURIComponent(dest)\n if (provider === 'apple') return `https://maps.apple.com/?daddr=${q}`\n if (provider === 'geo') return ll ? `geo:${ll}?q=${ll}` : `geo:0,0?q=${q}`\n return `https://www.google.com/maps/dir/?api=1&destination=${q}`\n}\n\n// --- opening hours -------------------------------------------------------\n\nconst toMin = (t: string | undefined): number => {\n const m = /^(\\d{1,2}):(\\d{2})$/.exec(t ?? '')\n return m ? Number(m[1]) * 60 + Number(m[2]) : NaN\n}\n\ntype Iv = [number, number]\n\n/** Intervals in minutes; an end at or before the start crosses midnight. */\nconst interval = (open: string | undefined, close: string | undefined): Iv[] => {\n const s = toMin(open)\n let e = toMin(close)\n if (Number.isNaN(s) || Number.isNaN(e)) return []\n if (e <= s) e += 1440\n return [[s, e]]\n}\n\nconst dayIntervals = (h: OpeningHours, day: number, date: string): Iv[] => {\n const x = h.exceptions?.find((e) => e.date === date)\n if (x?.closed) return []\n if (x && x.open && x.close) return interval(x.open, x.close)\n return h.weekly.filter((w) => w.day === day).flatMap((w) => interval(w.open, w.close))\n}\n\n/**\n * Whether the place is open at `now` in the IANA `timeZone` (throws RangeError\n * for an unknown zone). Looks 8 days ahead for the next opening. Handles\n * intervals crossing midnight, several per day, dated exceptions and DST.\n */\nexport function openStatus(hours: OpeningHours, timeZone: string, now: Date = new Date()): OpenStatus {\n const fmt = new Intl.DateTimeFormat('en-US', {\n timeZone, hourCycle: 'h23', year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric',\n })\n // Wall-clock minutes since the epoch as seen in `timeZone`.\n const wall = (ms: number): number => {\n const p: Record<string, number> = {}\n for (const { type, value } of fmt.formatToParts(ms)) p[type] = Number(value)\n return Date.UTC(p.year!, p.month! - 1, p.day!, (p.hour ?? 0) % 24, p.minute!) / 60000\n }\n const nowMs = now.getTime()\n const w = wall(nowMs)\n const day0 = Math.floor(w / 1440) * 1440\n // Offset from UTC, in minutes, at an instant.\n const offset = (ms: number): number => wall(ms) - Math.floor(ms / 60000)\n const toInstant = (t: number): string => {\n const guess = (t - offset(nowMs)) * 60000\n return new Date((t - offset(guess)) * 60000).toISOString()\n }\n\n const all: Iv[] = []\n for (let d = -1; d <= 8; d++) {\n const at = new Date((day0 + d * 1440) * 60000)\n const day = at.getUTCDay() || 7\n for (const [s, e] of dayIntervals(hours, day, at.toISOString().slice(0, 10))) all.push([day0 + d * 1440 + s, day0 + d * 1440 + e])\n }\n all.sort((a, b) => a[0] - b[0])\n const merged: Iv[] = []\n for (const iv of all) {\n const last = merged[merged.length - 1]\n if (last && iv[0] <= last[1]) last[1] = Math.max(last[1], iv[1])\n else merged.push([iv[0], iv[1]])\n }\n const current = merged.find(([s, e]) => s <= w && w < e)\n if (current) return { open: true, closesAt: toInstant(current[1]), nextOpenAt: null }\n const next = merged.find(([s]) => s > w)\n return { open: false, closesAt: null, nextOpenAt: next ? toInstant(next[0]) : null }\n}\n\ntype Run = { from: number; to: number; iv: Iv[] }\n\n/** Consecutive days (1..7) with identical intervals, in week order. */\nconst runs = (h: OpeningHours): Run[] => {\n const out: Run[] = []\n for (let day = 1; day <= 7; day++) {\n const iv = h.weekly.filter((x) => x.day === day).flatMap((x) => interval(x.open, x.close)).sort((a, b) => a[0] - b[0])\n if (!iv.length) continue\n const last = out[out.length - 1]\n if (last && last.to === day - 1 && JSON.stringify(last.iv) === JSON.stringify(iv)) last.to = day\n else out.push({ from: day, to: day, iv })\n }\n return out\n}\n\n/** Hour (24 for an end at midnight) and padded minutes of a minute-of-day value. */\nconst hm = (min: number): [number, string] => [min && min % 1440 === 0 ? 24 : Math.floor(min / 60) % 24, String(min % 60).padStart(2, '0')]\n\n/** Compact text, e.g. `Lun–Vie 9:00–19:00 · Sáb 9:00–14:00` (24 h) or `Mon–Fri 9:00 AM–7:00 PM` (en). */\nexport function formatOpeningHours(hours: OpeningHours, locale = 'es-MX'): string {\n const en = /^en/i.test(locale)\n const name = (d: number): string => {\n const s = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' }).format(Date.UTC(2024, 0, d)).replace(/\\.$/, '')\n return s.charAt(0).toUpperCase() + s.slice(1)\n }\n const time = (min: number): string => {\n const [h, m] = hm(min)\n return en ? `${h % 12 || 12}:${m} ${h % 24 < 12 ? 'AM' : 'PM'}` : `${h}:${m}`\n }\n return runs(hours)\n .map((r) => `${name(r.from)}${r.from === r.to ? '' : '–' + name(r.to)} ${r.iv.map(([s, e]) => `${time(s)}–${time(e)}`).join(', ')}`)\n .join(' · ')\n}\n\n/** schema.org `openingHours` strings, one per interval, e.g. `Mo-Fr 09:00-19:00`. */\nexport function toSchemaOpeningHours(hours: OpeningHours): string[] {\n const code = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']\n const t = (min: number): string => { const [h, m] = hm(min); return `${String(h).padStart(2, '0')}:${m}` }\n return runs(hours).flatMap((r) =>\n r.iv.map(([s, e]) => `${code[r.from - 1]}${r.from === r.to ? '' : '-' + code[r.to - 1]} ${t(s)}-${t(e)}`),\n )\n}\n","import type { Money } from './types.js'\n\nexport type FormatMoneyOptions = {\n /** Drop `.00` when the amount is a whole number. */\n withoutTrailingZeros?: boolean\n /** Format as a plain number, without the currency symbol. */\n withoutCurrency?: boolean\n /** `symbol` (default), `narrowSymbol`, `code` or `name`. */\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name'\n}\n\n/** Parses a contract `Money` amount into a JS number (`\"1899.00\"` → `1899`). */\nexport function parseMoney(money: Money | string | null | undefined): number {\n if (money == null) return 0\n const raw = typeof money === 'string' ? money : money.amount\n const n = Number.parseFloat(raw)\n return Number.isFinite(n) ? n : 0\n}\n\n/**\n * Formats `Money` with `Intl.NumberFormat`. Works in every runtime (no DOM).\n * Falls back to `\"<amount> <code>\"` when the runtime lacks the currency.\n */\nexport function formatMoney(money: Money, locale?: string, options: FormatMoneyOptions = {}): string {\n const value = parseMoney(money)\n const whole = Number.isInteger(value)\n const digits = options.withoutTrailingZeros && whole ? 0 : undefined\n try {\n const fmt = new Intl.NumberFormat(locale, {\n ...(options.withoutCurrency\n ? { style: 'decimal', minimumFractionDigits: digits ?? 2, maximumFractionDigits: digits ?? 2 }\n : {\n style: 'currency',\n currency: money.currency_code,\n currencyDisplay: options.currencyDisplay ?? 'symbol',\n ...(digits === 0 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}),\n }),\n })\n return fmt.format(value)\n } catch {\n const amount = digits === 0 ? String(value) : value.toFixed(2)\n return options.withoutCurrency ? amount : `${amount} ${money.currency_code}`\n }\n}\n\n/** Builds a `Money` from a number, rounding to cents. */\nexport function toMoney(value: number, currencyCode: string): Money {\n return { amount: (Math.round(value * 100) / 100).toFixed(2), currency_code: currencyCode }\n}\n\n/**\n * True for public (`pk_`) tokens, the only ones that may reach a browser.\n * Private (`sk_`) tokens must stay on the server.\n */\nexport function isTokenPublishable(token: string | null | undefined): boolean {\n return typeof token === 'string' && token.startsWith('pk_')\n}\n","import type { ProductSort } from './types.js'\n\nexport type QueryValue = string | number | boolean | null | undefined\nexport type QueryParams = Record<string, QueryValue | QueryValue[]>\n\nexport type PaginationParams = {\n /** Page size (1–100; articles accept at most 50). */\n first?: number\n /** Cursor from `page_info.end_cursor`. */\n after?: string | null\n}\n\nexport type ProductListParams = PaginationParams & {\n /** Free-text search. */\n q?: string\n /** Collection handle. */\n collection?: string\n sort?: ProductSort\n /** Only products available for sale. */\n available?: boolean\n price_min?: number | string\n price_max?: number | string\n /**\n * Attribute filters, serialized as repeated `filter.<key>=<value>` params.\n * Values of one key are OR-ed; different keys are AND-ed.\n * e.g. `{ vendor: ['A', 'B'], rim: 16 }`.\n */\n filters?: Record<string, QueryValue | QueryValue[]>\n /** Restrict to these handles (max 100). Serialized comma-separated. */\n handles?: string[]\n}\n\nexport type CollectionListParams = PaginationParams\n\nexport type ArticleListParams = Omit<PaginationParams, 'first'> & {\n /** Page size (1–50). The API answers 400 `validation` above 50. */\n first?: number\n tag?: string\n q?: string\n}\n\n/** Appends params to a URLSearchParams, repeating keys for arrays and skipping nullish values. */\nexport function appendParams(search: URLSearchParams, params: QueryParams | undefined): URLSearchParams {\n if (!params) return search\n for (const [key, raw] of Object.entries(params)) {\n const values = Array.isArray(raw) ? raw : [raw]\n for (const v of values) {\n if (v === undefined || v === null || v === '') continue\n search.append(key, String(v))\n }\n }\n return search\n}\n\n/** Serializes product list params per the contract (`filter.<attr>` repeated, `handles` comma-separated). */\nexport function productListQuery(params: ProductListParams = {}): URLSearchParams {\n const { filters, handles, ...rest } = params\n const search = appendParams(new URLSearchParams(), rest as QueryParams)\n if (handles && handles.length > 0) search.set('handles', handles.join(','))\n if (filters) {\n for (const [key, raw] of Object.entries(filters)) {\n const name = key.startsWith('filter.') ? key : `filter.${key}`\n appendParams(search, { [name]: raw })\n }\n }\n return search\n}\n\n/** Reads `filter.<key>` params back into a filters record (useful in route loaders). */\nexport function parseProductFilters(search: URLSearchParams): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const [key, value] of search) {\n if (!key.startsWith('filter.')) continue\n const name = key.slice('filter.'.length)\n ;(out[name] ??= []).push(value)\n }\n return out\n}\n","import { StorefrontError, defaultCodeForStatus } from './errors.js'\nimport { isValidPoint, type GeoPoint } from './geo.js'\nimport { isTokenPublishable } from './money.js'\nimport {\n appendParams,\n productListQuery,\n type ArticleListParams,\n type CollectionListParams,\n type PaginationParams,\n type ProductListParams,\n type QueryParams,\n} from './query.js'\nimport type {\n Address,\n AddressInput,\n Article,\n Cart,\n CartBuyerInput,\n CartLineInput,\n CartLineUpdateInput,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerSession,\n CustomerSessionInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n InvoiceRequest,\n Location,\n LocationListParams,\n NearestLocation,\n InvoiceResult,\n Menu,\n Order,\n Page,\n Product,\n ProductConnection,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n} from './types.js'\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\n/** Context passed to `onRequest` / `onResponse` hooks. */\nexport type StorefrontRequestContext = {\n method: string\n /** Absolute URL, including the query string. */\n url: string\n /** Route path relative to `baseUrl`, e.g. `/storefront/products/abc`. */\n path: string\n /** Final `RequestInit` (headers already merged). Hooks may mutate it. */\n init: RequestInit & { headers: Headers }\n /** Per-call options as given by the caller. */\n options: RequestOptions\n}\n\nexport type StorefrontResponseContext = StorefrontRequestContext & {\n response: Response\n /** Milliseconds spent waiting for the response. */\n durationMs: number\n}\n\nexport type StorefrontClientOptions = {\n /** Base URL of the gateway, e.g. `https://ops.example.com/api/gw`. Routes are appended as `/storefront/...`. */\n baseUrl: string\n /** `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. */\n token: string\n /** Buyer session (`X-Customer-Token`) for `/storefront/customer/*` routes. */\n customerToken?: string | null\n /** Custom fetch (defaults to `globalThis.fetch`). */\n fetch?: FetchLike\n /** Sent as `Accept-Language`. */\n locale?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /** Abort requests that take longer than this (default: no timeout). */\n timeoutMs?: number\n /**\n * Runs before every request. Return a `Response` to short-circuit the\n * network (e.g. an SSR cache hit); return nothing to continue.\n */\n onRequest?: (ctx: StorefrontRequestContext) => void | Response | Promise<void | Response>\n /** Runs after every response (including short-circuited ones), before parsing. */\n onResponse?: (ctx: StorefrontResponseContext) => void | Promise<void>\n}\n\n/** Per-call options. Unknown keys (e.g. Next.js `next`) are forwarded to `fetch` as-is. */\nexport type RequestOptions = {\n cache?: RequestCache\n signal?: AbortSignal\n /** Framework fetch extensions, forwarded verbatim (e.g. `{ revalidate: 60, tags: ['products'] }`). */\n next?: Record<string, unknown>\n headers?: Record<string, string>\n /** Overrides the client-level timeout for this call. */\n timeoutMs?: number\n /** Overrides the client-level customer token for this call. */\n customerToken?: string | null\n [key: string]: unknown\n}\n\nexport type WriteOptions = RequestOptions & {\n /** `Idempotency-Key` header. Auto-generated for checkout when omitted. */\n idempotencyKey?: string\n}\n\nexport type PreviewOptions = RequestOptions & {\n /** Signed preview token: returns the draft (`private, no-store`). */\n preview?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'\n\ntype RequestSpec = {\n method: HttpMethod\n path: string\n query?: URLSearchParams | QueryParams\n body?: unknown\n options?: WriteOptions\n /** Resolve `null` instead of throwing on 404. */\n nullOn404?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'idempotencyKey', 'preview', 'signal'])\n\n/** Generates an idempotency key (crypto.randomUUID when available). */\nexport function generateIdempotencyKey(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (c?.randomUUID) return c.randomUUID()\n // Non-cryptographic fallback for very old runtimes; the key only needs to be unique.\n return 'idem-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2)\n}\n\nfunction joinUrl(baseUrl: string, path: string): string {\n return baseUrl.replace(/\\/+$/, '') + path\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment)\n}\n\nfunction linkSignals(signals: (AbortSignal | undefined)[]): { signal: AbortSignal | undefined; cleanup: () => void } {\n const active = signals.filter((s): s is AbortSignal => !!s)\n if (active.length === 0) return { signal: undefined, cleanup: () => {} }\n if (active.length === 1) return { signal: active[0], cleanup: () => {} }\n const controller = new AbortController()\n const listeners: [AbortSignal, () => void][] = []\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason)\n break\n }\n const on = () => controller.abort(s.reason)\n s.addEventListener('abort', on, { once: true })\n listeners.push([s, on])\n }\n return {\n signal: controller.signal,\n cleanup: () => listeners.forEach(([s, on]) => s.removeEventListener('abort', on)),\n }\n}\n\nasync function readError(res: Response, url: string): Promise<StorefrontError> {\n let body: Partial<StorefrontErrorBody> | undefined\n try {\n const text = await res.text()\n body = text ? (JSON.parse(text) as Partial<StorefrontErrorBody>) : undefined\n } catch {\n body = undefined\n }\n const e = body?.error\n return new StorefrontError({\n status: res.status,\n code: e?.code ?? defaultCodeForStatus(res.status),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n url,\n })\n}\n\nexport function createStorefrontClient(config: StorefrontClientOptions) {\n if (!config.baseUrl) throw new TypeError('createStorefrontClient: baseUrl is required')\n if (!config.token) throw new TypeError('createStorefrontClient: token is required')\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n if (isBrowser && !isTokenPublishable(config.token) && config.token.startsWith('sk_')) {\n console.warn('[@asteby/storefront] A private sk_ token is being used in a browser. Use a public pk_ token instead.')\n }\n\n async function request<T>(spec: RequestSpec & { nullOn404: true }): Promise<T | null>\n async function request<T>(spec: RequestSpec): Promise<T>\n async function request<T>(spec: RequestSpec): Promise<T | null> {\n const fetchImpl: FetchLike | undefined = config.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new TypeError('createStorefrontClient: no fetch available; pass `fetch` in options')\n\n const options: WriteOptions = spec.options ?? {}\n const search = spec.query instanceof URLSearchParams ? spec.query : appendParams(new URLSearchParams(), spec.query)\n const qs = search.toString()\n const url = joinUrl(config.baseUrl, spec.path) + (qs ? `?${qs}` : '')\n\n const headers = new Headers(config.headers)\n headers.set('Accept', 'application/json')\n headers.set('Authorization', `Bearer ${config.token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n if (options.idempotencyKey) headers.set('Idempotency-Key', options.idempotencyKey)\n if (spec.body !== undefined) headers.set('Content-Type', 'application/json')\n for (const [k, v] of Object.entries(options.headers ?? {})) headers.set(k, v)\n\n // Forward passthrough options (cache, next, ...) to fetch.\n const passthrough: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(options)) if (!OWN_OPTION_KEYS.has(k) && v !== undefined) passthrough[k] = v\n\n const timeoutMs = options.timeoutMs ?? config.timeoutMs\n const timeoutController = timeoutMs && timeoutMs > 0 ? new AbortController() : undefined\n const timer = timeoutController\n ? setTimeout(() => timeoutController.abort(new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url })), timeoutMs)\n : undefined\n const linked = linkSignals([options.signal, timeoutController?.signal])\n\n const init: RequestInit & { headers: Headers } = {\n ...passthrough,\n method: spec.method,\n headers,\n ...(spec.body !== undefined ? { body: JSON.stringify(spec.body) } : {}),\n ...(linked.signal ? { signal: linked.signal } : {}),\n }\n const ctx: StorefrontRequestContext = { method: spec.method, url, path: spec.path, init, options }\n\n const started = Date.now()\n let res: Response\n try {\n const hooked = config.onRequest ? await config.onRequest(ctx) : undefined\n res = hooked instanceof Response ? hooked : await fetchImpl(url, init)\n } catch (err) {\n if (timeoutController?.signal.aborted) {\n throw new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url, cause: err })\n }\n if (options.signal?.aborted) {\n throw new StorefrontError({ status: 0, code: 'aborted', message: 'Request aborted', url, cause: err })\n }\n if (err instanceof StorefrontError) throw err\n throw new StorefrontError({ status: 0, code: 'network', message: err instanceof Error ? err.message : 'Network error', url, cause: err })\n } finally {\n if (timer) clearTimeout(timer)\n linked.cleanup()\n }\n\n if (config.onResponse) await config.onResponse({ ...ctx, response: res, durationMs: Date.now() - started })\n\n if (res.status === 404 && spec.nullOn404) {\n // Drain the body so the connection can be reused.\n await res.text().catch(() => undefined)\n return null\n }\n if (res.status === 304) {\n throw new StorefrontError({ status: 304, code: 'not_modified', message: 'Not modified', url })\n }\n if (!res.ok) throw await readError(res, url)\n if (res.status === 204) return undefined as T\n\n const text = await res.text()\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch (err) {\n throw new StorefrontError({ status: res.status, code: 'invalid_response', message: 'Response is not valid JSON', url, cause: err })\n }\n }\n\n const get = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const getOrNull = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, nullOn404: true, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const write = <T>(method: HttpMethod, path: string, body?: unknown, options?: WriteOptions) =>\n request<T>({ method, path, ...(body !== undefined ? { body } : {}), ...(options ? { options } : {}) })\n\n const cartPath = (id: string, rest = '') => `/storefront/carts/${enc(id)}${rest}`\n const previewQuery = (options?: PreviewOptions) => (options?.preview ? { preview: options.preview } : undefined)\n\n const client = {\n /** Resolved configuration (read-only). */\n config: Object.freeze({ ...config }) as Readonly<StorefrontClientOptions>,\n\n /** Low-level escape hatch: any route under `baseUrl`. */\n request,\n\n /** Returns a new client that sends the given buyer session token. */\n withCustomerToken(customerToken: string | null) {\n return createStorefrontClient({ ...config, customerToken })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n products: {\n list: (params?: ProductListParams, options?: RequestOptions) =>\n get<ProductConnection>('/storefront/products', productListQuery(params), options),\n /** `null` when the product does not exist or is unpublished. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Product>(`/storefront/products/${enc(handle)}`, undefined, options),\n recommendations: (handle: string, options?: RequestOptions) =>\n get<{ nodes: Product[] }>(`/storefront/products/${enc(handle)}/recommendations`, undefined, options),\n },\n\n collections: {\n list: (params?: CollectionListParams, options?: RequestOptions) =>\n get<Connection<Collection>>('/storefront/collections', params as QueryParams, options),\n /** `null` when the collection does not exist. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Collection>(`/storefront/collections/${enc(handle)}`, undefined, options),\n },\n\n locations: {\n /** Branches of the shop. With `postal_code` they come ordered by distance (`distance_km`). */\n list: (params?: LocationListParams, options?: RequestOptions) =>\n get<{ nodes: Location[] }>('/storefront/locations', params as QueryParams, options),\n /** `null` when the branch does not exist or is not visible. */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<Location>(`/storefront/locations/${enc(id)}`, undefined, options),\n /**\n * Branches ordered by distance to a point, closest first. The server rounds the coordinates (0.01°, ~1 km)\n * and never stores them; this client does not log or keep them either. The answer is `private, no-store`\n * (it depends on the buyer's position), so do not put it in a shared cache. Note `onRequest` hooks and\n * `fetch` wrappers do see the URL: do not log it. Throws `TypeError` for an invalid point.\n */\n nearest: (point: GeoPoint, options?: RequestOptions) => {\n if (!isValidPoint(point)) throw new TypeError('locations.nearest: lat/lng must be a valid point')\n return get<{ nodes: NearestLocation[] }>('/storefront/locations/nearest', { lat: point.lat, lng: point.lng }, { cache: 'no-store', ...options })\n },\n },\n\n stock: {\n /** Stock for up to 250 SKUs. */\n get: (skus: string[], options?: RequestOptions) =>\n get<{ nodes: StockLevel[] }>('/storefront/stock', { sku: skus }, options),\n },\n\n carts: {\n create: (input: { lines?: CartLineInput[] } = {}, options?: WriteOptions) =>\n write<Cart>('POST', '/storefront/carts', input, options),\n /** `null` when the cart does not exist (e.g. expired cookie). */\n get: (id: string, options?: RequestOptions) => getOrNull<Cart>(cartPath(id), undefined, options),\n addLines: (id: string, lines: CartLineInput[], options?: WriteOptions) =>\n write<Cart>('POST', cartPath(id, '/lines'), { lines }, options),\n /** Quantity `0` removes the line. */\n updateLines: (id: string, lines: CartLineUpdateInput[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines }, options),\n removeLines: (id: string, lineIds: string[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines: lineIds.map((lid) => ({ id: lid, quantity: 0 })) }, options),\n setDiscountCodes: (id: string, codes: string[], options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/discount-codes'), { codes }, options),\n setBuyer: (id: string, buyer: CartBuyerInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/buyer'), buyer, options),\n setShippingAddress: (id: string, address: AddressInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/shipping-address'), address, options),\n deliveryOptions: (id: string, options?: RequestOptions) =>\n get<DeliveryOptions>(cartPath(id, '/delivery-options'), undefined, options),\n /** Payment providers active for the cart's market; send the chosen `key` as `payment_method`. */\n paymentMethods: (id: string, options?: RequestOptions) =>\n get<PaymentMethods>(cartPath(id, '/payment-methods'), undefined, options),\n setDelivery: (id: string, delivery: DeliveryInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/delivery'), delivery, options),\n /** Reserves stock and creates the order. Sends `Idempotency-Key` (auto-generated if omitted). */\n checkout: (id: string, input: CheckoutInput, options: WriteOptions = {}) =>\n write<CheckoutResult>('POST', cartPath(id, '/checkout'), input, {\n ...options,\n idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),\n }),\n },\n\n checkouts: {\n /**\n * Reads a placed checkout (same shape as the `carts.checkout` result). `order.number` is `null` until OPS\n * has created the order (a few hundred ms after checkout); poll once or twice and, if it is still `null`,\n * keep telling the buyer the number will arrive by email. Needs a server token (`checkout:write`).\n * `null` when the checkout does not exist. Never cache.\n */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<CheckoutResult>(`/storefront/checkouts/${enc(id)}`, undefined, options),\n },\n\n customer: {\n /** Sends a one-time code by email or SMS/WhatsApp. */\n requestOtp: (identifier: CustomerIdentifier, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/otp', identifier, options),\n /** Exchanges the code for a buyer session (`token` goes in `customerToken`). */\n createSession: (input: CustomerSessionInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/session', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n orders: (params?: PaginationParams, options?: RequestOptions) =>\n get<Connection<Order>>('/storefront/customer/orders', params as QueryParams, options),\n /** `null` when the order does not exist or belongs to someone else. */\n order: (id: string, options?: RequestOptions) =>\n getOrNull<Order>(`/storefront/customer/orders/${enc(id)}`, undefined, options),\n requestReturn: (orderId: string, input: ReturnRequestInput, options?: WriteOptions) =>\n write<ReturnRequest>('POST', `/storefront/customer/orders/${enc(orderId)}/returns`, input, options),\n requestInvoice: (orderId: string, input: InvoiceRequest, options?: WriteOptions) =>\n write<InvoiceResult>('POST', `/storefront/customer/orders/${enc(orderId)}/invoice`, input, options),\n addresses: {\n list: (options?: RequestOptions) => get<{ nodes: Address[] }>('/storefront/customer/addresses', undefined, options),\n create: (address: AddressInput, options?: WriteOptions) =>\n write<Address>('POST', '/storefront/customer/addresses', address, options),\n update: (id: string, address: Partial<AddressInput>, options?: WriteOptions) =>\n write<Address>('PATCH', `/storefront/customer/addresses/${enc(id)}`, address, options),\n delete: (id: string, options?: WriteOptions) =>\n write<void>('DELETE', `/storefront/customer/addresses/${enc(id)}`, undefined, options),\n },\n },\n\n content: {\n theme: (options?: RequestOptions) => get<Theme>('/storefront/content/theme', undefined, options),\n /** `null` when the page does not exist. */\n page: (handle: string, options?: PreviewOptions) =>\n getOrNull<Page>(`/storefront/content/pages/${enc(handle)}`, previewQuery(options), options),\n /** `null` when the menu does not exist. */\n menu: (handle: string, options?: RequestOptions) =>\n getOrNull<Menu>(`/storefront/content/menus/${enc(handle)}`, undefined, options),\n articles: (params?: ArticleListParams, options?: RequestOptions) =>\n get<Connection<Article>>('/storefront/content/articles', params as QueryParams, options),\n /** `null` when the article does not exist. */\n article: (handle: string, options?: PreviewOptions) =>\n getOrNull<Article>(`/storefront/content/articles/${enc(handle)}`, previewQuery(options), options),\n },\n }\n return client\n}\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,7 @@
1
- import { V as ProductSort, a1 as Shop, T as ProductConnection, Q as Product, q as Connection, p as Collection, a5 as StockLevel, i as CartLineInput, C as Cart, k as CartLineUpdateInput, d as CartBuyerInput, a as AddressInput, w as DeliveryOptions, L as PaymentMethods, D as DeliveryInput, m as CheckoutInput, o as CheckoutResult, s as CustomerIdentifier, u as CustomerSessionInput, t as CustomerSession, r as Customer, O as Order, Y as ReturnRequestInput, X as ReturnRequest, y as InvoiceRequest, z as InvoiceResult, A as Address, a8 as Theme, P as Page, M as Menu, b as Article, a7 as StorefrontErrorCode, E as Money } from './types-CTXB8Dnl.cjs';
2
- export { c as CartBuyer, e as CartCost, f as CartDelivery, g as CartDiscountCode, h as CartLine, j as CartLineMerchandise, l as CheckoutInfo, n as CheckoutPayment, v as DeliveryMethod, F as Facet, x as FacetValue, I as Image, B as MenuItem, G as MoneyRange, H as OrderLine, J as PageInfo, K as PaymentMethod, N as PickupOption, R as ProductAttributeValue, S as ProductCategory, U as ProductOption, W as ProductVariant, Z as SEO, _ as Section, $ as SelectedOption, a0 as ShippingRate, a2 as ShopBranch, a3 as ShopContact, a4 as ShopPolicies, a6 as StorefrontErrorBody, a9 as UnavailableRateProvider } from './types-CTXB8Dnl.cjs';
1
+ import { GeoPoint } from './geo.cjs';
2
+ export { OpenStatus, OpeningHours } from './geo.cjs';
3
+ import { $ as ProductSort, a7 as Shop, Z as ProductConnection, W as Product, q as Connection, p as Collection, G as LocationListParams, L as Location, O as NearestLocation, ab as StockLevel, i as CartLineInput, C as Cart, k as CartLineUpdateInput, d as CartBuyerInput, a as AddressInput, w as DeliveryOptions, U as PaymentMethods, D as DeliveryInput, m as CheckoutInput, o as CheckoutResult, s as CustomerIdentifier, u as CustomerSessionInput, t as CustomerSession, r as Customer, P as Order, a2 as ReturnRequestInput, a1 as ReturnRequest, y as InvoiceRequest, z as InvoiceResult, A as Address, ae as Theme, R as Page, M as Menu, b as Article, ad as StorefrontErrorCode, K as Money } from './types-D300wdPF.cjs';
4
+ export { c as CartBuyer, e as CartCost, f as CartDelivery, g as CartDiscountCode, h as CartLine, j as CartLineMerchandise, l as CheckoutInfo, n as CheckoutPayment, v as DeliveryMethod, F as Facet, x as FacetValue, I as Image, B as LocationContacts, E as LocationKind, H as LocationPickup, J as MenuItem, N as MoneyRange, Q as OrderLine, S as PageInfo, T as PaymentMethod, V as PickupOption, X as ProductAttributeValue, Y as ProductCategory, _ as ProductOption, a0 as ProductVariant, a3 as SEO, a4 as Section, a5 as SelectedOption, a6 as ShippingRate, a8 as ShopBranch, a9 as ShopContact, aa as ShopPolicies, ac as StorefrontErrorBody, af as UnavailableRateProvider } from './types-D300wdPF.cjs';
3
5
 
4
6
  type QueryValue = string | number | boolean | null | undefined;
5
7
  type QueryParams = Record<string, QueryValue | QueryValue[]>;
@@ -146,6 +148,23 @@ declare function createStorefrontClient(config: StorefrontClientOptions): {
146
148
  /** `null` when the collection does not exist. */
147
149
  get: (handle: string, options?: RequestOptions) => Promise<Collection | null>;
148
150
  };
151
+ locations: {
152
+ /** Branches of the shop. With `postal_code` they come ordered by distance (`distance_km`). */
153
+ list: (params?: LocationListParams, options?: RequestOptions) => Promise<{
154
+ nodes: Location[];
155
+ }>;
156
+ /** `null` when the branch does not exist or is not visible. */
157
+ get: (id: string, options?: RequestOptions) => Promise<Location | null>;
158
+ /**
159
+ * Branches ordered by distance to a point, closest first. The server rounds the coordinates (0.01°, ~1 km)
160
+ * and never stores them; this client does not log or keep them either. The answer is `private, no-store`
161
+ * (it depends on the buyer's position), so do not put it in a shared cache. Note `onRequest` hooks and
162
+ * `fetch` wrappers do see the URL: do not log it. Throws `TypeError` for an invalid point.
163
+ */
164
+ nearest: (point: GeoPoint, options?: RequestOptions) => Promise<{
165
+ nodes: NearestLocation[];
166
+ }>;
167
+ };
149
168
  stock: {
150
169
  /** Stock for up to 250 SKUs. */
151
170
  get: (skus: string[], options?: RequestOptions) => Promise<{
@@ -267,4 +286,4 @@ declare function toMoney(value: number, currencyCode: string): Money;
267
286
  */
268
287
  declare function isTokenPublishable(token: string | null | undefined): boolean;
269
288
 
270
- export { Address, AddressInput, Article, type ArticleListParams, Cart, CartBuyerInput, CartLineInput, CartLineUpdateInput, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeliveryInput, DeliveryOptions, type FetchLike, type FormatMoneyOptions, InvoiceRequest, InvoiceResult, Menu, Money, Order, Page, type PaginationParams, PaymentMethods, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, type QueryParams, type QueryValue, type RequestOptions, ReturnRequest, ReturnRequestInput, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, type WriteOptions, appendParams, createStorefrontClient, formatMoney, generateIdempotencyKey, isStorefrontError, isTokenPublishable, parseMoney, parseProductFilters, productListQuery, toMoney };
289
+ export { Address, AddressInput, Article, type ArticleListParams, Cart, CartBuyerInput, CartLineInput, CartLineUpdateInput, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeliveryInput, DeliveryOptions, type FetchLike, type FormatMoneyOptions, GeoPoint, InvoiceRequest, InvoiceResult, Location, LocationListParams, Menu, Money, NearestLocation, Order, Page, type PaginationParams, PaymentMethods, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, type QueryParams, type QueryValue, type RequestOptions, ReturnRequest, ReturnRequestInput, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, type WriteOptions, appendParams, createStorefrontClient, formatMoney, generateIdempotencyKey, isStorefrontError, isTokenPublishable, parseMoney, parseProductFilters, productListQuery, toMoney };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { V as ProductSort, a1 as Shop, T as ProductConnection, Q as Product, q as Connection, p as Collection, a5 as StockLevel, i as CartLineInput, C as Cart, k as CartLineUpdateInput, d as CartBuyerInput, a as AddressInput, w as DeliveryOptions, L as PaymentMethods, D as DeliveryInput, m as CheckoutInput, o as CheckoutResult, s as CustomerIdentifier, u as CustomerSessionInput, t as CustomerSession, r as Customer, O as Order, Y as ReturnRequestInput, X as ReturnRequest, y as InvoiceRequest, z as InvoiceResult, A as Address, a8 as Theme, P as Page, M as Menu, b as Article, a7 as StorefrontErrorCode, E as Money } from './types-CTXB8Dnl.js';
2
- export { c as CartBuyer, e as CartCost, f as CartDelivery, g as CartDiscountCode, h as CartLine, j as CartLineMerchandise, l as CheckoutInfo, n as CheckoutPayment, v as DeliveryMethod, F as Facet, x as FacetValue, I as Image, B as MenuItem, G as MoneyRange, H as OrderLine, J as PageInfo, K as PaymentMethod, N as PickupOption, R as ProductAttributeValue, S as ProductCategory, U as ProductOption, W as ProductVariant, Z as SEO, _ as Section, $ as SelectedOption, a0 as ShippingRate, a2 as ShopBranch, a3 as ShopContact, a4 as ShopPolicies, a6 as StorefrontErrorBody, a9 as UnavailableRateProvider } from './types-CTXB8Dnl.js';
1
+ import { GeoPoint } from './geo.js';
2
+ export { OpenStatus, OpeningHours } from './geo.js';
3
+ import { $ as ProductSort, a7 as Shop, Z as ProductConnection, W as Product, q as Connection, p as Collection, G as LocationListParams, L as Location, O as NearestLocation, ab as StockLevel, i as CartLineInput, C as Cart, k as CartLineUpdateInput, d as CartBuyerInput, a as AddressInput, w as DeliveryOptions, U as PaymentMethods, D as DeliveryInput, m as CheckoutInput, o as CheckoutResult, s as CustomerIdentifier, u as CustomerSessionInput, t as CustomerSession, r as Customer, P as Order, a2 as ReturnRequestInput, a1 as ReturnRequest, y as InvoiceRequest, z as InvoiceResult, A as Address, ae as Theme, R as Page, M as Menu, b as Article, ad as StorefrontErrorCode, K as Money } from './types-BmC-RDo8.js';
4
+ export { c as CartBuyer, e as CartCost, f as CartDelivery, g as CartDiscountCode, h as CartLine, j as CartLineMerchandise, l as CheckoutInfo, n as CheckoutPayment, v as DeliveryMethod, F as Facet, x as FacetValue, I as Image, B as LocationContacts, E as LocationKind, H as LocationPickup, J as MenuItem, N as MoneyRange, Q as OrderLine, S as PageInfo, T as PaymentMethod, V as PickupOption, X as ProductAttributeValue, Y as ProductCategory, _ as ProductOption, a0 as ProductVariant, a3 as SEO, a4 as Section, a5 as SelectedOption, a6 as ShippingRate, a8 as ShopBranch, a9 as ShopContact, aa as ShopPolicies, ac as StorefrontErrorBody, af as UnavailableRateProvider } from './types-BmC-RDo8.js';
3
5
 
4
6
  type QueryValue = string | number | boolean | null | undefined;
5
7
  type QueryParams = Record<string, QueryValue | QueryValue[]>;
@@ -146,6 +148,23 @@ declare function createStorefrontClient(config: StorefrontClientOptions): {
146
148
  /** `null` when the collection does not exist. */
147
149
  get: (handle: string, options?: RequestOptions) => Promise<Collection | null>;
148
150
  };
151
+ locations: {
152
+ /** Branches of the shop. With `postal_code` they come ordered by distance (`distance_km`). */
153
+ list: (params?: LocationListParams, options?: RequestOptions) => Promise<{
154
+ nodes: Location[];
155
+ }>;
156
+ /** `null` when the branch does not exist or is not visible. */
157
+ get: (id: string, options?: RequestOptions) => Promise<Location | null>;
158
+ /**
159
+ * Branches ordered by distance to a point, closest first. The server rounds the coordinates (0.01°, ~1 km)
160
+ * and never stores them; this client does not log or keep them either. The answer is `private, no-store`
161
+ * (it depends on the buyer's position), so do not put it in a shared cache. Note `onRequest` hooks and
162
+ * `fetch` wrappers do see the URL: do not log it. Throws `TypeError` for an invalid point.
163
+ */
164
+ nearest: (point: GeoPoint, options?: RequestOptions) => Promise<{
165
+ nodes: NearestLocation[];
166
+ }>;
167
+ };
149
168
  stock: {
150
169
  /** Stock for up to 250 SKUs. */
151
170
  get: (skus: string[], options?: RequestOptions) => Promise<{
@@ -267,4 +286,4 @@ declare function toMoney(value: number, currencyCode: string): Money;
267
286
  */
268
287
  declare function isTokenPublishable(token: string | null | undefined): boolean;
269
288
 
270
- export { Address, AddressInput, Article, type ArticleListParams, Cart, CartBuyerInput, CartLineInput, CartLineUpdateInput, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeliveryInput, DeliveryOptions, type FetchLike, type FormatMoneyOptions, InvoiceRequest, InvoiceResult, Menu, Money, Order, Page, type PaginationParams, PaymentMethods, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, type QueryParams, type QueryValue, type RequestOptions, ReturnRequest, ReturnRequestInput, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, type WriteOptions, appendParams, createStorefrontClient, formatMoney, generateIdempotencyKey, isStorefrontError, isTokenPublishable, parseMoney, parseProductFilters, productListQuery, toMoney };
289
+ export { Address, AddressInput, Article, type ArticleListParams, Cart, CartBuyerInput, CartLineInput, CartLineUpdateInput, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeliveryInput, DeliveryOptions, type FetchLike, type FormatMoneyOptions, GeoPoint, InvoiceRequest, InvoiceResult, Location, LocationListParams, Menu, Money, NearestLocation, Order, Page, type PaginationParams, PaymentMethods, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, type QueryParams, type QueryValue, type RequestOptions, ReturnRequest, ReturnRequestInput, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, type WriteOptions, appendParams, createStorefrontClient, formatMoney, generateIdempotencyKey, isStorefrontError, isTokenPublishable, parseMoney, parseProductFilters, productListQuery, toMoney };
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { isValidPoint } from './chunk-45R47HYO.js';
2
+
1
3
  // src/errors.ts
2
4
  var StorefrontError = class extends Error {
3
5
  name = "StorefrontError";
@@ -252,6 +254,22 @@ function createStorefrontClient(config) {
252
254
  /** `null` when the collection does not exist. */
253
255
  get: (handle, options) => getOrNull(`/storefront/collections/${enc(handle)}`, void 0, options)
254
256
  },
257
+ locations: {
258
+ /** Branches of the shop. With `postal_code` they come ordered by distance (`distance_km`). */
259
+ list: (params, options) => get("/storefront/locations", params, options),
260
+ /** `null` when the branch does not exist or is not visible. */
261
+ get: (id, options) => getOrNull(`/storefront/locations/${enc(id)}`, void 0, options),
262
+ /**
263
+ * Branches ordered by distance to a point, closest first. The server rounds the coordinates (0.01°, ~1 km)
264
+ * and never stores them; this client does not log or keep them either. The answer is `private, no-store`
265
+ * (it depends on the buyer's position), so do not put it in a shared cache. Note `onRequest` hooks and
266
+ * `fetch` wrappers do see the URL: do not log it. Throws `TypeError` for an invalid point.
267
+ */
268
+ nearest: (point, options) => {
269
+ if (!isValidPoint(point)) throw new TypeError("locations.nearest: lat/lng must be a valid point");
270
+ return get("/storefront/locations/nearest", { lat: point.lat, lng: point.lng }, { cache: "no-store", ...options });
271
+ }
272
+ },
255
273
  stock: {
256
274
  /** Stock for up to 250 SKUs. */
257
275
  get: (skus, options) => get("/storefront/stock", { sku: skus }, options)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/money.ts","../src/query.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { StorefrontErrorCode } from './types.js'\n\nexport type StorefrontErrorInit = {\n status: number\n code: StorefrontErrorCode\n message: string\n field?: string\n /** Request URL that failed (without credentials). */\n url?: string\n cause?: unknown\n}\n\n/**\n * Error thrown by the client for any non-2xx response, network failure,\n * timeout or abort. `status` is `0` when no HTTP response was received.\n */\nexport class StorefrontError extends Error {\n override readonly name = 'StorefrontError'\n readonly status: number\n readonly code: StorefrontErrorCode\n readonly field: string | undefined\n readonly url: string | undefined\n\n constructor(init: StorefrontErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause })\n this.status = init.status\n this.code = init.code\n this.field = init.field\n this.url = init.url\n }\n\n toJSON() {\n return { name: this.name, status: this.status, code: this.code, message: this.message, field: this.field }\n }\n}\n\nexport function isStorefrontError(err: unknown): err is StorefrontError {\n return err instanceof StorefrontError || (typeof err === 'object' && err !== null && (err as { name?: unknown }).name === 'StorefrontError')\n}\n\nconst STATUS_CODES: Record<number, StorefrontErrorCode> = {\n 400: 'validation',\n 401: 'unauthorized',\n 403: 'forbidden',\n 404: 'not_found',\n 409: 'conflict',\n 422: 'invalid_state',\n 429: 'rate_limited',\n}\n\nexport function defaultCodeForStatus(status: number): StorefrontErrorCode {\n return STATUS_CODES[status] ?? (status >= 500 ? 'server_error' : 'invalid_response')\n}\n","import type { Money } from './types.js'\n\nexport type FormatMoneyOptions = {\n /** Drop `.00` when the amount is a whole number. */\n withoutTrailingZeros?: boolean\n /** Format as a plain number, without the currency symbol. */\n withoutCurrency?: boolean\n /** `symbol` (default), `narrowSymbol`, `code` or `name`. */\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name'\n}\n\n/** Parses a contract `Money` amount into a JS number (`\"1899.00\"` → `1899`). */\nexport function parseMoney(money: Money | string | null | undefined): number {\n if (money == null) return 0\n const raw = typeof money === 'string' ? money : money.amount\n const n = Number.parseFloat(raw)\n return Number.isFinite(n) ? n : 0\n}\n\n/**\n * Formats `Money` with `Intl.NumberFormat`. Works in every runtime (no DOM).\n * Falls back to `\"<amount> <code>\"` when the runtime lacks the currency.\n */\nexport function formatMoney(money: Money, locale?: string, options: FormatMoneyOptions = {}): string {\n const value = parseMoney(money)\n const whole = Number.isInteger(value)\n const digits = options.withoutTrailingZeros && whole ? 0 : undefined\n try {\n const fmt = new Intl.NumberFormat(locale, {\n ...(options.withoutCurrency\n ? { style: 'decimal', minimumFractionDigits: digits ?? 2, maximumFractionDigits: digits ?? 2 }\n : {\n style: 'currency',\n currency: money.currency_code,\n currencyDisplay: options.currencyDisplay ?? 'symbol',\n ...(digits === 0 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}),\n }),\n })\n return fmt.format(value)\n } catch {\n const amount = digits === 0 ? String(value) : value.toFixed(2)\n return options.withoutCurrency ? amount : `${amount} ${money.currency_code}`\n }\n}\n\n/** Builds a `Money` from a number, rounding to cents. */\nexport function toMoney(value: number, currencyCode: string): Money {\n return { amount: (Math.round(value * 100) / 100).toFixed(2), currency_code: currencyCode }\n}\n\n/**\n * True for public (`pk_`) tokens, the only ones that may reach a browser.\n * Private (`sk_`) tokens must stay on the server.\n */\nexport function isTokenPublishable(token: string | null | undefined): boolean {\n return typeof token === 'string' && token.startsWith('pk_')\n}\n","import type { ProductSort } from './types.js'\n\nexport type QueryValue = string | number | boolean | null | undefined\nexport type QueryParams = Record<string, QueryValue | QueryValue[]>\n\nexport type PaginationParams = {\n /** Page size (1–100; articles accept at most 50). */\n first?: number\n /** Cursor from `page_info.end_cursor`. */\n after?: string | null\n}\n\nexport type ProductListParams = PaginationParams & {\n /** Free-text search. */\n q?: string\n /** Collection handle. */\n collection?: string\n sort?: ProductSort\n /** Only products available for sale. */\n available?: boolean\n price_min?: number | string\n price_max?: number | string\n /**\n * Attribute filters, serialized as repeated `filter.<key>=<value>` params.\n * Values of one key are OR-ed; different keys are AND-ed.\n * e.g. `{ vendor: ['A', 'B'], rim: 16 }`.\n */\n filters?: Record<string, QueryValue | QueryValue[]>\n /** Restrict to these handles (max 100). Serialized comma-separated. */\n handles?: string[]\n}\n\nexport type CollectionListParams = PaginationParams\n\nexport type ArticleListParams = Omit<PaginationParams, 'first'> & {\n /** Page size (1–50). The API answers 400 `validation` above 50. */\n first?: number\n tag?: string\n q?: string\n}\n\n/** Appends params to a URLSearchParams, repeating keys for arrays and skipping nullish values. */\nexport function appendParams(search: URLSearchParams, params: QueryParams | undefined): URLSearchParams {\n if (!params) return search\n for (const [key, raw] of Object.entries(params)) {\n const values = Array.isArray(raw) ? raw : [raw]\n for (const v of values) {\n if (v === undefined || v === null || v === '') continue\n search.append(key, String(v))\n }\n }\n return search\n}\n\n/** Serializes product list params per the contract (`filter.<attr>` repeated, `handles` comma-separated). */\nexport function productListQuery(params: ProductListParams = {}): URLSearchParams {\n const { filters, handles, ...rest } = params\n const search = appendParams(new URLSearchParams(), rest as QueryParams)\n if (handles && handles.length > 0) search.set('handles', handles.join(','))\n if (filters) {\n for (const [key, raw] of Object.entries(filters)) {\n const name = key.startsWith('filter.') ? key : `filter.${key}`\n appendParams(search, { [name]: raw })\n }\n }\n return search\n}\n\n/** Reads `filter.<key>` params back into a filters record (useful in route loaders). */\nexport function parseProductFilters(search: URLSearchParams): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const [key, value] of search) {\n if (!key.startsWith('filter.')) continue\n const name = key.slice('filter.'.length)\n ;(out[name] ??= []).push(value)\n }\n return out\n}\n","import { StorefrontError, defaultCodeForStatus } from './errors.js'\nimport { isTokenPublishable } from './money.js'\nimport {\n appendParams,\n productListQuery,\n type ArticleListParams,\n type CollectionListParams,\n type PaginationParams,\n type ProductListParams,\n type QueryParams,\n} from './query.js'\nimport type {\n Address,\n AddressInput,\n Article,\n Cart,\n CartBuyerInput,\n CartLineInput,\n CartLineUpdateInput,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerSession,\n CustomerSessionInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n InvoiceRequest,\n InvoiceResult,\n Menu,\n Order,\n Page,\n Product,\n ProductConnection,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n} from './types.js'\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\n/** Context passed to `onRequest` / `onResponse` hooks. */\nexport type StorefrontRequestContext = {\n method: string\n /** Absolute URL, including the query string. */\n url: string\n /** Route path relative to `baseUrl`, e.g. `/storefront/products/abc`. */\n path: string\n /** Final `RequestInit` (headers already merged). Hooks may mutate it. */\n init: RequestInit & { headers: Headers }\n /** Per-call options as given by the caller. */\n options: RequestOptions\n}\n\nexport type StorefrontResponseContext = StorefrontRequestContext & {\n response: Response\n /** Milliseconds spent waiting for the response. */\n durationMs: number\n}\n\nexport type StorefrontClientOptions = {\n /** Base URL of the gateway, e.g. `https://ops.example.com/api/gw`. Routes are appended as `/storefront/...`. */\n baseUrl: string\n /** `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. */\n token: string\n /** Buyer session (`X-Customer-Token`) for `/storefront/customer/*` routes. */\n customerToken?: string | null\n /** Custom fetch (defaults to `globalThis.fetch`). */\n fetch?: FetchLike\n /** Sent as `Accept-Language`. */\n locale?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /** Abort requests that take longer than this (default: no timeout). */\n timeoutMs?: number\n /**\n * Runs before every request. Return a `Response` to short-circuit the\n * network (e.g. an SSR cache hit); return nothing to continue.\n */\n onRequest?: (ctx: StorefrontRequestContext) => void | Response | Promise<void | Response>\n /** Runs after every response (including short-circuited ones), before parsing. */\n onResponse?: (ctx: StorefrontResponseContext) => void | Promise<void>\n}\n\n/** Per-call options. Unknown keys (e.g. Next.js `next`) are forwarded to `fetch` as-is. */\nexport type RequestOptions = {\n cache?: RequestCache\n signal?: AbortSignal\n /** Framework fetch extensions, forwarded verbatim (e.g. `{ revalidate: 60, tags: ['products'] }`). */\n next?: Record<string, unknown>\n headers?: Record<string, string>\n /** Overrides the client-level timeout for this call. */\n timeoutMs?: number\n /** Overrides the client-level customer token for this call. */\n customerToken?: string | null\n [key: string]: unknown\n}\n\nexport type WriteOptions = RequestOptions & {\n /** `Idempotency-Key` header. Auto-generated for checkout when omitted. */\n idempotencyKey?: string\n}\n\nexport type PreviewOptions = RequestOptions & {\n /** Signed preview token: returns the draft (`private, no-store`). */\n preview?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'\n\ntype RequestSpec = {\n method: HttpMethod\n path: string\n query?: URLSearchParams | QueryParams\n body?: unknown\n options?: WriteOptions\n /** Resolve `null` instead of throwing on 404. */\n nullOn404?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'idempotencyKey', 'preview', 'signal'])\n\n/** Generates an idempotency key (crypto.randomUUID when available). */\nexport function generateIdempotencyKey(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (c?.randomUUID) return c.randomUUID()\n // Non-cryptographic fallback for very old runtimes; the key only needs to be unique.\n return 'idem-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2)\n}\n\nfunction joinUrl(baseUrl: string, path: string): string {\n return baseUrl.replace(/\\/+$/, '') + path\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment)\n}\n\nfunction linkSignals(signals: (AbortSignal | undefined)[]): { signal: AbortSignal | undefined; cleanup: () => void } {\n const active = signals.filter((s): s is AbortSignal => !!s)\n if (active.length === 0) return { signal: undefined, cleanup: () => {} }\n if (active.length === 1) return { signal: active[0], cleanup: () => {} }\n const controller = new AbortController()\n const listeners: [AbortSignal, () => void][] = []\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason)\n break\n }\n const on = () => controller.abort(s.reason)\n s.addEventListener('abort', on, { once: true })\n listeners.push([s, on])\n }\n return {\n signal: controller.signal,\n cleanup: () => listeners.forEach(([s, on]) => s.removeEventListener('abort', on)),\n }\n}\n\nasync function readError(res: Response, url: string): Promise<StorefrontError> {\n let body: Partial<StorefrontErrorBody> | undefined\n try {\n const text = await res.text()\n body = text ? (JSON.parse(text) as Partial<StorefrontErrorBody>) : undefined\n } catch {\n body = undefined\n }\n const e = body?.error\n return new StorefrontError({\n status: res.status,\n code: e?.code ?? defaultCodeForStatus(res.status),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n url,\n })\n}\n\nexport function createStorefrontClient(config: StorefrontClientOptions) {\n if (!config.baseUrl) throw new TypeError('createStorefrontClient: baseUrl is required')\n if (!config.token) throw new TypeError('createStorefrontClient: token is required')\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n if (isBrowser && !isTokenPublishable(config.token) && config.token.startsWith('sk_')) {\n console.warn('[@asteby/storefront] A private sk_ token is being used in a browser. Use a public pk_ token instead.')\n }\n\n async function request<T>(spec: RequestSpec & { nullOn404: true }): Promise<T | null>\n async function request<T>(spec: RequestSpec): Promise<T>\n async function request<T>(spec: RequestSpec): Promise<T | null> {\n const fetchImpl: FetchLike | undefined = config.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new TypeError('createStorefrontClient: no fetch available; pass `fetch` in options')\n\n const options: WriteOptions = spec.options ?? {}\n const search = spec.query instanceof URLSearchParams ? spec.query : appendParams(new URLSearchParams(), spec.query)\n const qs = search.toString()\n const url = joinUrl(config.baseUrl, spec.path) + (qs ? `?${qs}` : '')\n\n const headers = new Headers(config.headers)\n headers.set('Accept', 'application/json')\n headers.set('Authorization', `Bearer ${config.token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n if (options.idempotencyKey) headers.set('Idempotency-Key', options.idempotencyKey)\n if (spec.body !== undefined) headers.set('Content-Type', 'application/json')\n for (const [k, v] of Object.entries(options.headers ?? {})) headers.set(k, v)\n\n // Forward passthrough options (cache, next, ...) to fetch.\n const passthrough: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(options)) if (!OWN_OPTION_KEYS.has(k) && v !== undefined) passthrough[k] = v\n\n const timeoutMs = options.timeoutMs ?? config.timeoutMs\n const timeoutController = timeoutMs && timeoutMs > 0 ? new AbortController() : undefined\n const timer = timeoutController\n ? setTimeout(() => timeoutController.abort(new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url })), timeoutMs)\n : undefined\n const linked = linkSignals([options.signal, timeoutController?.signal])\n\n const init: RequestInit & { headers: Headers } = {\n ...passthrough,\n method: spec.method,\n headers,\n ...(spec.body !== undefined ? { body: JSON.stringify(spec.body) } : {}),\n ...(linked.signal ? { signal: linked.signal } : {}),\n }\n const ctx: StorefrontRequestContext = { method: spec.method, url, path: spec.path, init, options }\n\n const started = Date.now()\n let res: Response\n try {\n const hooked = config.onRequest ? await config.onRequest(ctx) : undefined\n res = hooked instanceof Response ? hooked : await fetchImpl(url, init)\n } catch (err) {\n if (timeoutController?.signal.aborted) {\n throw new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url, cause: err })\n }\n if (options.signal?.aborted) {\n throw new StorefrontError({ status: 0, code: 'aborted', message: 'Request aborted', url, cause: err })\n }\n if (err instanceof StorefrontError) throw err\n throw new StorefrontError({ status: 0, code: 'network', message: err instanceof Error ? err.message : 'Network error', url, cause: err })\n } finally {\n if (timer) clearTimeout(timer)\n linked.cleanup()\n }\n\n if (config.onResponse) await config.onResponse({ ...ctx, response: res, durationMs: Date.now() - started })\n\n if (res.status === 404 && spec.nullOn404) {\n // Drain the body so the connection can be reused.\n await res.text().catch(() => undefined)\n return null\n }\n if (res.status === 304) {\n throw new StorefrontError({ status: 304, code: 'not_modified', message: 'Not modified', url })\n }\n if (!res.ok) throw await readError(res, url)\n if (res.status === 204) return undefined as T\n\n const text = await res.text()\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch (err) {\n throw new StorefrontError({ status: res.status, code: 'invalid_response', message: 'Response is not valid JSON', url, cause: err })\n }\n }\n\n const get = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const getOrNull = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, nullOn404: true, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const write = <T>(method: HttpMethod, path: string, body?: unknown, options?: WriteOptions) =>\n request<T>({ method, path, ...(body !== undefined ? { body } : {}), ...(options ? { options } : {}) })\n\n const cartPath = (id: string, rest = '') => `/storefront/carts/${enc(id)}${rest}`\n const previewQuery = (options?: PreviewOptions) => (options?.preview ? { preview: options.preview } : undefined)\n\n const client = {\n /** Resolved configuration (read-only). */\n config: Object.freeze({ ...config }) as Readonly<StorefrontClientOptions>,\n\n /** Low-level escape hatch: any route under `baseUrl`. */\n request,\n\n /** Returns a new client that sends the given buyer session token. */\n withCustomerToken(customerToken: string | null) {\n return createStorefrontClient({ ...config, customerToken })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n products: {\n list: (params?: ProductListParams, options?: RequestOptions) =>\n get<ProductConnection>('/storefront/products', productListQuery(params), options),\n /** `null` when the product does not exist or is unpublished. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Product>(`/storefront/products/${enc(handle)}`, undefined, options),\n recommendations: (handle: string, options?: RequestOptions) =>\n get<{ nodes: Product[] }>(`/storefront/products/${enc(handle)}/recommendations`, undefined, options),\n },\n\n collections: {\n list: (params?: CollectionListParams, options?: RequestOptions) =>\n get<Connection<Collection>>('/storefront/collections', params as QueryParams, options),\n /** `null` when the collection does not exist. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Collection>(`/storefront/collections/${enc(handle)}`, undefined, options),\n },\n\n stock: {\n /** Stock for up to 250 SKUs. */\n get: (skus: string[], options?: RequestOptions) =>\n get<{ nodes: StockLevel[] }>('/storefront/stock', { sku: skus }, options),\n },\n\n carts: {\n create: (input: { lines?: CartLineInput[] } = {}, options?: WriteOptions) =>\n write<Cart>('POST', '/storefront/carts', input, options),\n /** `null` when the cart does not exist (e.g. expired cookie). */\n get: (id: string, options?: RequestOptions) => getOrNull<Cart>(cartPath(id), undefined, options),\n addLines: (id: string, lines: CartLineInput[], options?: WriteOptions) =>\n write<Cart>('POST', cartPath(id, '/lines'), { lines }, options),\n /** Quantity `0` removes the line. */\n updateLines: (id: string, lines: CartLineUpdateInput[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines }, options),\n removeLines: (id: string, lineIds: string[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines: lineIds.map((lid) => ({ id: lid, quantity: 0 })) }, options),\n setDiscountCodes: (id: string, codes: string[], options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/discount-codes'), { codes }, options),\n setBuyer: (id: string, buyer: CartBuyerInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/buyer'), buyer, options),\n setShippingAddress: (id: string, address: AddressInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/shipping-address'), address, options),\n deliveryOptions: (id: string, options?: RequestOptions) =>\n get<DeliveryOptions>(cartPath(id, '/delivery-options'), undefined, options),\n /** Payment providers active for the cart's market; send the chosen `key` as `payment_method`. */\n paymentMethods: (id: string, options?: RequestOptions) =>\n get<PaymentMethods>(cartPath(id, '/payment-methods'), undefined, options),\n setDelivery: (id: string, delivery: DeliveryInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/delivery'), delivery, options),\n /** Reserves stock and creates the order. Sends `Idempotency-Key` (auto-generated if omitted). */\n checkout: (id: string, input: CheckoutInput, options: WriteOptions = {}) =>\n write<CheckoutResult>('POST', cartPath(id, '/checkout'), input, {\n ...options,\n idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),\n }),\n },\n\n checkouts: {\n /**\n * Reads a placed checkout (same shape as the `carts.checkout` result). `order.number` is `null` until OPS\n * has created the order (a few hundred ms after checkout); poll once or twice and, if it is still `null`,\n * keep telling the buyer the number will arrive by email. Needs a server token (`checkout:write`).\n * `null` when the checkout does not exist. Never cache.\n */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<CheckoutResult>(`/storefront/checkouts/${enc(id)}`, undefined, options),\n },\n\n customer: {\n /** Sends a one-time code by email or SMS/WhatsApp. */\n requestOtp: (identifier: CustomerIdentifier, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/otp', identifier, options),\n /** Exchanges the code for a buyer session (`token` goes in `customerToken`). */\n createSession: (input: CustomerSessionInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/session', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n orders: (params?: PaginationParams, options?: RequestOptions) =>\n get<Connection<Order>>('/storefront/customer/orders', params as QueryParams, options),\n /** `null` when the order does not exist or belongs to someone else. */\n order: (id: string, options?: RequestOptions) =>\n getOrNull<Order>(`/storefront/customer/orders/${enc(id)}`, undefined, options),\n requestReturn: (orderId: string, input: ReturnRequestInput, options?: WriteOptions) =>\n write<ReturnRequest>('POST', `/storefront/customer/orders/${enc(orderId)}/returns`, input, options),\n requestInvoice: (orderId: string, input: InvoiceRequest, options?: WriteOptions) =>\n write<InvoiceResult>('POST', `/storefront/customer/orders/${enc(orderId)}/invoice`, input, options),\n addresses: {\n list: (options?: RequestOptions) => get<{ nodes: Address[] }>('/storefront/customer/addresses', undefined, options),\n create: (address: AddressInput, options?: WriteOptions) =>\n write<Address>('POST', '/storefront/customer/addresses', address, options),\n update: (id: string, address: Partial<AddressInput>, options?: WriteOptions) =>\n write<Address>('PATCH', `/storefront/customer/addresses/${enc(id)}`, address, options),\n delete: (id: string, options?: WriteOptions) =>\n write<void>('DELETE', `/storefront/customer/addresses/${enc(id)}`, undefined, options),\n },\n },\n\n content: {\n theme: (options?: RequestOptions) => get<Theme>('/storefront/content/theme', undefined, options),\n /** `null` when the page does not exist. */\n page: (handle: string, options?: PreviewOptions) =>\n getOrNull<Page>(`/storefront/content/pages/${enc(handle)}`, previewQuery(options), options),\n /** `null` when the menu does not exist. */\n menu: (handle: string, options?: RequestOptions) =>\n getOrNull<Menu>(`/storefront/content/menus/${enc(handle)}`, undefined, options),\n articles: (params?: ArticleListParams, options?: RequestOptions) =>\n get<Connection<Article>>('/storefront/content/articles', params as QueryParams, options),\n /** `null` when the article does not exist. */\n article: (handle: string, options?: PreviewOptions) =>\n getOrNull<Article>(`/storefront/content/articles/${enc(handle)}`, previewQuery(options), options),\n },\n }\n return client\n}\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/money.ts","../src/query.ts","../src/client.ts"],"names":[],"mappings":";;;AAgBO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EACvB,IAAA,GAAO,iBAAA;AAAA,EAChB,MAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAA;AAAA,EAET,YAAY,IAAA,EAA2B;AACrC,IAAA,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,KAAA,KAAU,MAAA,GAAY,SAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,CAAA;AAChF,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAAA,EAClB;AAAA,EAEA,MAAA,GAAS;AACP,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,QAAQ,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,KAAA,EAAO,KAAK,KAAA,EAAM;AAAA,EAC3G;AACF;AAEO,SAAS,kBAAkB,GAAA,EAAsC;AACtE,EAAA,OAAO,GAAA,YAAe,mBAAoB,OAAO,GAAA,KAAQ,YAAY,GAAA,KAAQ,IAAA,IAAS,IAA2B,IAAA,KAAS,iBAAA;AAC5H;AAEA,IAAM,YAAA,GAAoD;AAAA,EACxD,GAAA,EAAK,YAAA;AAAA,EACL,GAAA,EAAK,cAAA;AAAA,EACL,GAAA,EAAK,WAAA;AAAA,EACL,GAAA,EAAK,WAAA;AAAA,EACL,GAAA,EAAK,UAAA;AAAA,EACL,GAAA,EAAK,eAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAEO,SAAS,qBAAqB,MAAA,EAAqC;AACxE,EAAA,OAAO,YAAA,CAAa,MAAM,CAAA,KAAM,MAAA,IAAU,MAAM,cAAA,GAAiB,kBAAA,CAAA;AACnE;;;ACxCO,SAAS,WAAW,KAAA,EAAkD;AAC3E,EAAA,IAAI,KAAA,IAAS,MAAM,OAAO,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,OAAO,KAAA,KAAU,QAAA,GAAW,QAAQ,KAAA,CAAM,MAAA;AACtD,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,UAAA,CAAW,GAAG,CAAA;AAC/B,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA;AAClC;AAMO,SAAS,WAAA,CAAY,KAAA,EAAc,MAAA,EAAiB,OAAA,GAA8B,EAAC,EAAW;AACnG,EAAA,MAAM,KAAA,GAAQ,WAAW,KAAK,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,SAAA,CAAU,KAAK,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,oBAAA,IAAwB,KAAA,GAAQ,CAAA,GAAI,MAAA;AAC3D,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,MACxC,GAAI,OAAA,CAAQ,eAAA,GACR,EAAE,KAAA,EAAO,SAAA,EAAW,qBAAA,EAAuB,MAAA,IAAU,CAAA,EAAG,qBAAA,EAAuB,MAAA,IAAU,CAAA,EAAE,GAC3F;AAAA,QACE,KAAA,EAAO,UAAA;AAAA,QACP,UAAU,KAAA,CAAM,aAAA;AAAA,QAChB,eAAA,EAAiB,QAAQ,eAAA,IAAmB,QAAA;AAAA,QAC5C,GAAI,WAAW,CAAA,GAAI,EAAE,uBAAuB,CAAA,EAAG,qBAAA,EAAuB,CAAA,EAAE,GAAI;AAAC;AAC/E,KACL,CAAA;AACD,IAAA,OAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,MAAA,GAAS,WAAW,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAC,CAAA;AAC7D,IAAA,OAAO,QAAQ,eAAA,GAAkB,MAAA,GAAS,GAAG,MAAM,CAAA,CAAA,EAAI,MAAM,aAAa,CAAA,CAAA;AAAA,EAC5E;AACF;AAGO,SAAS,OAAA,CAAQ,OAAe,YAAA,EAA6B;AAClE,EAAA,OAAO,EAAE,MAAA,EAAA,CAAS,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,GAAG,CAAA,GAAI,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAA,EAAG,aAAA,EAAe,YAAA,EAAa;AAC3F;AAMO,SAAS,mBAAmB,KAAA,EAA2C;AAC5E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,WAAW,KAAK,CAAA;AAC5D;;;ACdO,SAAS,YAAA,CAAa,QAAyB,MAAA,EAAkD;AACtG,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC/C,IAAA,MAAM,SAAS,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,GAAA,GAAM,CAAC,GAAG,CAAA;AAC9C,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,IAAQ,MAAM,EAAA,EAAI;AAC/C,MAAA,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gBAAA,CAAiB,MAAA,GAA4B,EAAC,EAAoB;AAChF,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAS,GAAG,MAAK,GAAI,MAAA;AACtC,EAAA,MAAM,MAAA,GAAS,YAAA,CAAa,IAAI,eAAA,IAAmB,IAAmB,CAAA;AACtE,EAAA,IAAI,OAAA,IAAW,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,IAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAC,CAAA;AAC1E,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAChD,MAAA,MAAM,OAAO,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,GAAI,GAAA,GAAM,UAAU,GAAG,CAAA,CAAA;AAC5D,MAAA,YAAA,CAAa,QAAQ,EAAE,CAAC,IAAI,GAAG,KAAK,CAAA;AAAA,IACtC;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,oBAAoB,MAAA,EAAmD;AACrF,EAAA,MAAM,MAAgC,EAAC;AACvC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,MAAA,EAAQ;AACjC,IAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA;AACtC,IAAA,CAAC,IAAI,IAAI,CAAA,KAAM,EAAC,EAAG,KAAK,KAAK,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAA;AACT;;;ACqDA,IAAM,eAAA,mBAAkB,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,aAAa,eAAA,EAAiB,gBAAA,EAAkB,SAAA,EAAW,QAAQ,CAAC,CAAA;AAGzG,SAAS,sBAAA,GAAiC;AAC/C,EAAA,MAAM,IAAK,UAAA,CAA0D,MAAA;AACrE,EAAA,IAAI,CAAA,EAAG,UAAA,EAAY,OAAO,CAAA,CAAE,UAAA,EAAW;AAEvC,EAAA,OAAO,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAA,GAAI,GAAA,GAAM,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AAC3H;AAEA,SAAS,OAAA,CAAQ,SAAiB,IAAA,EAAsB;AACtD,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,GAAI,IAAA;AACvC;AAEA,SAAS,IAAI,OAAA,EAAyB;AACpC,EAAA,OAAO,mBAAmB,OAAO,CAAA;AACnC;AAEA,SAAS,YAAY,OAAA,EAAgG;AACnH,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAwB,CAAC,CAAC,CAAC,CAAA;AAC1D,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAW,SAAS,MAAM;AAAA,EAAC,CAAA,EAAE;AACvE,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,EAAE,QAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,OAAA,EAAS,MAAM;AAAA,EAAC,CAAA,EAAE;AACvE,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,YAAyC,EAAC;AAChD,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,EAAE,OAAA,EAAS;AACb,MAAA,UAAA,CAAW,KAAA,CAAM,EAAE,MAAM,CAAA;AACzB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,EAAA,GAAK,MAAM,UAAA,CAAW,KAAA,CAAM,EAAE,MAAM,CAAA;AAC1C,IAAA,CAAA,CAAE,iBAAiB,OAAA,EAAS,EAAA,EAAI,EAAE,IAAA,EAAM,MAAM,CAAA;AAC9C,IAAA,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EACxB;AACA,EAAA,OAAO;AAAA,IACL,QAAQ,UAAA,CAAW,MAAA;AAAA,IACnB,OAAA,EAAS,MAAM,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAG,EAAE,CAAA,KAAM,CAAA,CAAE,mBAAA,CAAoB,OAAA,EAAS,EAAE,CAAC;AAAA,GAClF;AACF;AAEA,eAAe,SAAA,CAAU,KAAe,GAAA,EAAuC;AAC7E,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAA,GAAO,IAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,GAAqC,KAAA,CAAA;AAAA,EACrE,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,GAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAI,IAAA,EAAM,KAAA;AAChB,EAAA,OAAO,IAAI,eAAA,CAAgB;AAAA,IACzB,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,IAAA,EAAM,CAAA,EAAG,IAAA,IAAQ,oBAAA,CAAqB,IAAI,MAAM,CAAA;AAAA,IAChD,OAAA,EAAS,CAAA,EAAG,OAAA,IAAW,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,EAAG,GAAA,CAAI,UAAA,GAAa,GAAA,GAAM,GAAA,CAAI,UAAA,GAAa,EAAE,CAAA,CAAA;AAAA,IAC1G,GAAI,GAAG,KAAA,GAAQ,EAAE,OAAO,CAAA,CAAE,KAAA,KAAU,EAAC;AAAA,IACrC;AAAA,GACD,CAAA;AACH;AAEO,SAAS,uBAAuB,MAAA,EAAiC;AACtE,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,MAAM,IAAI,UAAU,6CAA6C,CAAA;AACtF,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,EAAO,MAAM,IAAI,UAAU,2CAA2C,CAAA;AAClF,EAAA,MAAM,SAAA,GAAY,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,QAAA,KAAa,WAAA;AACvE,EAAA,IAAI,SAAA,IAAa,CAAC,kBAAA,CAAmB,MAAA,CAAO,KAAK,KAAK,MAAA,CAAO,KAAA,CAAM,UAAA,CAAW,KAAK,CAAA,EAAG;AACpF,IAAA,OAAA,CAAQ,KAAK,sGAAsG,CAAA;AAAA,EACrH;AAIA,EAAA,eAAe,QAAW,IAAA,EAAsC;AAC9D,IAAA,MAAM,SAAA,GAAmC,OAAO,KAAA,KAAU,UAAA,CAAW,QAAQ,UAAA,CAAW,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,GAAI,MAAA,CAAA;AACjH,IAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,UAAU,qEAAqE,CAAA;AAEzG,IAAA,MAAM,OAAA,GAAwB,IAAA,CAAK,OAAA,IAAW,EAAC;AAC/C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,YAAiB,eAAA,GAAkB,IAAA,CAAK,KAAA,GAAQ,YAAA,CAAa,IAAI,eAAA,EAAgB,EAAG,IAAA,CAAK,KAAK,CAAA;AAClH,IAAA,MAAM,EAAA,GAAK,OAAO,QAAA,EAAS;AAC3B,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA,IAAK,EAAA,GAAK,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAA,CAAA;AAElE,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AAC1C,IAAA,OAAA,CAAQ,GAAA,CAAI,UAAU,kBAAkB,CAAA;AACxC,IAAA,OAAA,CAAQ,GAAA,CAAI,eAAA,EAAiB,CAAA,OAAA,EAAU,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AACrD,IAAA,IAAI,OAAO,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,iBAAA,EAAmB,OAAO,MAAM,CAAA;AAC/D,IAAA,MAAM,gBAAgB,OAAA,CAAQ,aAAA,KAAkB,MAAA,GAAY,OAAA,CAAQ,gBAAgB,MAAA,CAAO,aAAA;AAC3F,IAAA,IAAI,aAAA,EAAe,OAAA,CAAQ,GAAA,CAAI,kBAAA,EAAoB,aAAa,CAAA;AAChE,IAAA,IAAI,QAAQ,cAAA,EAAgB,OAAA,CAAQ,GAAA,CAAI,iBAAA,EAAmB,QAAQ,cAAc,CAAA;AACjF,IAAA,IAAI,KAAK,IAAA,KAAS,MAAA,EAAW,OAAA,CAAQ,GAAA,CAAI,gBAAgB,kBAAkB,CAAA;AAC3E,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAA,IAAW,EAAE,CAAA,EAAG,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAC,CAAA;AAG5E,IAAA,MAAM,cAAuC,EAAC;AAC9C,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG,IAAI,CAAC,eAAA,CAAgB,IAAI,CAAC,CAAA,IAAK,MAAM,MAAA,EAAW,WAAA,CAAY,CAAC,CAAA,GAAI,CAAA;AAE/G,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,IAAa,MAAA,CAAO,SAAA;AAC9C,IAAA,MAAM,oBAAoB,SAAA,IAAa,SAAA,GAAY,CAAA,GAAI,IAAI,iBAAgB,GAAI,MAAA;AAC/E,IAAA,MAAM,KAAA,GAAQ,oBACV,UAAA,CAAW,MAAM,kBAAkB,KAAA,CAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,SAAA,EAAW,OAAA,EAAS,2BAA2B,SAAS,CAAA,EAAA,CAAA,EAAM,KAAK,CAAC,CAAA,EAAG,SAAS,CAAA,GAChK,MAAA;AACJ,IAAA,MAAM,SAAS,WAAA,CAAY,CAAC,QAAQ,MAAA,EAAQ,iBAAA,EAAmB,MAAM,CAAC,CAAA;AAEtE,IAAA,MAAM,IAAA,GAA2C;AAAA,MAC/C,GAAG,WAAA;AAAA,MACH,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,OAAA;AAAA,MACA,GAAI,IAAA,CAAK,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAE,GAAI,EAAC;AAAA,MACrE,GAAI,OAAO,MAAA,GAAS,EAAE,QAAQ,MAAA,CAAO,MAAA,KAAW;AAAC,KACnD;AACA,IAAA,MAAM,GAAA,GAAgC,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,OAAA,EAAQ;AAEjG,IAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAA,CAAO,SAAA,GAAY,MAAM,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA,GAAI,KAAA,CAAA;AAChE,MAAA,GAAA,GAAM,kBAAkB,QAAA,GAAW,MAAA,GAAS,MAAM,SAAA,CAAU,KAAK,IAAI,CAAA;AAAA,IACvE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,iBAAA,EAAmB,OAAO,OAAA,EAAS;AACrC,QAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,GAAG,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAA,EAAM,GAAA,EAAK,KAAA,EAAO,KAAK,CAAA;AAAA,MAC9H;AACA,MAAA,IAAI,OAAA,CAAQ,QAAQ,OAAA,EAAS;AAC3B,QAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,iBAAA,EAAmB,GAAA,EAAK,KAAA,EAAO,GAAA,EAAK,CAAA;AAAA,MACvG;AACA,MAAA,IAAI,GAAA,YAAe,iBAAiB,MAAM,GAAA;AAC1C,MAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,SAAA,EAAW,OAAA,EAAS,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,eAAA,EAAiB,GAAA,EAAK,KAAA,EAAO,KAAK,CAAA;AAAA,IAC1I,CAAA,SAAE;AACA,MAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAC7B,MAAA,MAAA,CAAO,OAAA,EAAQ;AAAA,IACjB;AAEA,IAAA,IAAI,MAAA,CAAO,UAAA,EAAY,MAAM,MAAA,CAAO,WAAW,EAAE,GAAG,GAAA,EAAK,QAAA,EAAU,KAAK,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,SAAS,CAAA;AAE1G,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,IAAA,CAAK,SAAA,EAAW;AAExC,MAAA,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACtC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,GAAA,EAAK,MAAM,cAAA,EAAgB,OAAA,EAAS,cAAA,EAAgB,GAAA,EAAK,CAAA;AAAA,IAC/F;AACA,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,QAAU,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AAC3C,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,MAAA;AAE/B,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IACxB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,kBAAA,EAAoB,OAAA,EAAS,4BAAA,EAA8B,GAAA,EAAK,KAAA,EAAO,KAAK,CAAA;AAAA,IACpI;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,GAAM,CAAI,IAAA,EAAc,KAAA,EAAuC,OAAA,KACnE,QAAW,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,GAAI,KAAA,GAAQ,EAAE,KAAA,EAAM,GAAI,EAAC,EAAI,GAAI,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI,EAAC,EAAI,CAAA;AAClG,EAAA,MAAM,SAAA,GAAY,CAAI,IAAA,EAAc,KAAA,EAAuC,OAAA,KACzE,OAAA,CAAW,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,GAAI,QAAQ,EAAE,KAAA,EAAM,GAAI,EAAC,EAAI,GAAI,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI,EAAC,EAAI,CAAA;AACnH,EAAA,MAAM,KAAA,GAAQ,CAAI,MAAA,EAAoB,IAAA,EAAc,IAAA,EAAgB,YAClE,OAAA,CAAW,EAAE,MAAA,EAAQ,IAAA,EAAM,GAAI,IAAA,KAAS,SAAY,EAAE,IAAA,EAAK,GAAI,EAAC,EAAI,GAAI,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI,EAAC,EAAI,CAAA;AAEvG,EAAA,MAAM,QAAA,GAAW,CAAC,EAAA,EAAY,IAAA,GAAO,EAAA,KAAO,qBAAqB,GAAA,CAAI,EAAE,CAAC,CAAA,EAAG,IAAI,CAAA,CAAA;AAC/E,EAAA,MAAM,YAAA,GAAe,CAAC,OAAA,KAA8B,OAAA,EAAS,UAAU,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI,MAAA;AAEtG,EAAA,MAAM,MAAA,GAAS;AAAA;AAAA,IAEb,QAAQ,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,QAAQ,CAAA;AAAA;AAAA,IAGnC,OAAA;AAAA;AAAA,IAGA,kBAAkB,aAAA,EAA8B;AAC9C,MAAA,OAAO,sBAAA,CAAuB,EAAE,GAAG,MAAA,EAAQ,eAAe,CAAA;AAAA,IAC5D,CAAA;AAAA,IAEA,IAAA,EAAM;AAAA,MACJ,KAAK,CAAC,OAAA,KAA6B,GAAA,CAAU,kBAAA,EAAoB,QAAW,OAAO;AAAA,KACrF;AAAA,IAEA,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,CAAC,MAAA,EAA4B,OAAA,KACjC,IAAuB,sBAAA,EAAwB,gBAAA,CAAiB,MAAM,CAAA,EAAG,OAAO,CAAA;AAAA;AAAA,MAElF,GAAA,EAAK,CAAC,MAAA,EAAgB,OAAA,KACpB,SAAA,CAAmB,CAAA,qBAAA,EAAwB,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO,CAAA;AAAA,MAC9E,eAAA,EAAiB,CAAC,MAAA,EAAgB,OAAA,KAChC,GAAA,CAA0B,CAAA,qBAAA,EAAwB,GAAA,CAAI,MAAM,CAAC,CAAA,gBAAA,CAAA,EAAoB,MAAA,EAAW,OAAO;AAAA,KACvG;AAAA,IAEA,WAAA,EAAa;AAAA,MACX,MAAM,CAAC,MAAA,EAA+B,YACpC,GAAA,CAA4B,yBAAA,EAA2B,QAAuB,OAAO,CAAA;AAAA;AAAA,MAEvF,GAAA,EAAK,CAAC,MAAA,EAAgB,OAAA,KACpB,SAAA,CAAsB,CAAA,wBAAA,EAA2B,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO;AAAA,KACtF;AAAA,IAEA,SAAA,EAAW;AAAA;AAAA,MAET,MAAM,CAAC,MAAA,EAA6B,YAClC,GAAA,CAA2B,uBAAA,EAAyB,QAAuB,OAAO,CAAA;AAAA;AAAA,MAEpF,GAAA,EAAK,CAAC,EAAA,EAAY,OAAA,KAChB,SAAA,CAAoB,CAAA,sBAAA,EAAyB,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAO5E,OAAA,EAAS,CAAC,KAAA,EAAiB,OAAA,KAA6B;AACtD,QAAA,IAAI,CAAC,YAAA,CAAa,KAAK,GAAG,MAAM,IAAI,UAAU,kDAAkD,CAAA;AAChG,QAAA,OAAO,GAAA,CAAkC,+BAAA,EAAiC,EAAE,GAAA,EAAK,MAAM,GAAA,EAAK,GAAA,EAAK,KAAA,CAAM,GAAA,IAAO,EAAE,KAAA,EAAO,UAAA,EAAY,GAAG,SAAS,CAAA;AAAA,MACjJ;AAAA,KACF;AAAA,IAEA,KAAA,EAAO;AAAA;AAAA,MAEL,GAAA,EAAK,CAAC,IAAA,EAAgB,OAAA,KACpB,GAAA,CAA6B,qBAAqB,EAAE,GAAA,EAAK,IAAA,EAAK,EAAG,OAAO;AAAA,KAC5E;AAAA,IAEA,KAAA,EAAO;AAAA,MACL,MAAA,EAAQ,CAAC,KAAA,GAAqC,EAAC,EAAG,YAChD,KAAA,CAAY,MAAA,EAAQ,mBAAA,EAAqB,KAAA,EAAO,OAAO,CAAA;AAAA;AAAA,MAEzD,GAAA,EAAK,CAAC,EAAA,EAAY,OAAA,KAA6B,UAAgB,QAAA,CAAS,EAAE,CAAA,EAAG,MAAA,EAAW,OAAO,CAAA;AAAA,MAC/F,QAAA,EAAU,CAAC,EAAA,EAAY,KAAA,EAAwB,YAC7C,KAAA,CAAY,MAAA,EAAQ,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA,EAAG,EAAE,KAAA,IAAS,OAAO,CAAA;AAAA;AAAA,MAEhE,WAAA,EAAa,CAAC,EAAA,EAAY,KAAA,EAA8B,YACtD,KAAA,CAAY,OAAA,EAAS,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA,EAAG,EAAE,KAAA,IAAS,OAAO,CAAA;AAAA,MACjE,WAAA,EAAa,CAAC,EAAA,EAAY,OAAA,EAAmB,OAAA,KAC3C,MAAY,OAAA,EAAS,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA,EAAG,EAAE,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,MAAS,EAAE,EAAA,EAAI,GAAA,EAAK,QAAA,EAAU,CAAA,EAAE,CAAE,CAAA,EAAE,EAAG,OAAO,CAAA;AAAA,MACnH,gBAAA,EAAkB,CAAC,EAAA,EAAY,KAAA,EAAiB,YAC9C,KAAA,CAAY,KAAA,EAAO,QAAA,CAAS,EAAA,EAAI,iBAAiB,CAAA,EAAG,EAAE,KAAA,IAAS,OAAO,CAAA;AAAA,MACxE,QAAA,EAAU,CAAC,EAAA,EAAY,KAAA,EAAuB,OAAA,KAC5C,KAAA,CAAY,KAAA,EAAO,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA,EAAG,KAAA,EAAO,OAAO,CAAA;AAAA,MAC3D,kBAAA,EAAoB,CAAC,EAAA,EAAY,OAAA,EAAuB,OAAA,KACtD,KAAA,CAAY,KAAA,EAAO,QAAA,CAAS,EAAA,EAAI,mBAAmB,CAAA,EAAG,OAAA,EAAS,OAAO,CAAA;AAAA,MACxE,eAAA,EAAiB,CAAC,EAAA,EAAY,OAAA,KAC5B,GAAA,CAAqB,SAAS,EAAA,EAAI,mBAAmB,CAAA,EAAG,MAAA,EAAW,OAAO,CAAA;AAAA;AAAA,MAE5E,cAAA,EAAgB,CAAC,EAAA,EAAY,OAAA,KAC3B,GAAA,CAAoB,SAAS,EAAA,EAAI,kBAAkB,CAAA,EAAG,MAAA,EAAW,OAAO,CAAA;AAAA,MAC1E,WAAA,EAAa,CAAC,EAAA,EAAY,QAAA,EAAyB,OAAA,KACjD,KAAA,CAAY,KAAA,EAAO,QAAA,CAAS,EAAA,EAAI,WAAW,CAAA,EAAG,QAAA,EAAU,OAAO,CAAA;AAAA;AAAA,MAEjE,QAAA,EAAU,CAAC,EAAA,EAAY,KAAA,EAAsB,OAAA,GAAwB,EAAC,KACpE,KAAA,CAAsB,MAAA,EAAQ,QAAA,CAAS,EAAA,EAAI,WAAW,GAAG,KAAA,EAAO;AAAA,QAC9D,GAAG,OAAA;AAAA,QACH,cAAA,EAAgB,OAAA,CAAQ,cAAA,IAAkB,sBAAA;AAAuB,OAClE;AAAA,KACL;AAAA,IAEA,SAAA,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOT,GAAA,EAAK,CAAC,EAAA,EAAY,OAAA,KAChB,SAAA,CAA0B,CAAA,sBAAA,EAAyB,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO;AAAA,KACpF;AAAA,IAEA,QAAA,EAAU;AAAA;AAAA,MAER,UAAA,EAAY,CAAC,UAAA,EAAgC,OAAA,KAC3C,MAAY,MAAA,EAAQ,0BAAA,EAA4B,YAAY,OAAO,CAAA;AAAA;AAAA,MAErE,aAAA,EAAe,CAAC,KAAA,EAA6B,OAAA,KAC3C,MAAuB,MAAA,EAAQ,8BAAA,EAAgC,OAAO,OAAO,CAAA;AAAA,MAC/E,KAAK,CAAC,OAAA,KAA6B,GAAA,CAAc,sBAAA,EAAwB,QAAW,OAAO,CAAA;AAAA,MAC3F,QAAQ,CAAC,MAAA,EAA2B,YAClC,GAAA,CAAuB,6BAAA,EAA+B,QAAuB,OAAO,CAAA;AAAA;AAAA,MAEtF,KAAA,EAAO,CAAC,EAAA,EAAY,OAAA,KAClB,SAAA,CAAiB,CAAA,4BAAA,EAA+B,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO,CAAA;AAAA,MAC/E,aAAA,EAAe,CAAC,OAAA,EAAiB,KAAA,EAA2B,OAAA,KAC1D,KAAA,CAAqB,MAAA,EAAQ,CAAA,4BAAA,EAA+B,GAAA,CAAI,OAAO,CAAC,CAAA,QAAA,CAAA,EAAY,OAAO,OAAO,CAAA;AAAA,MACpG,cAAA,EAAgB,CAAC,OAAA,EAAiB,KAAA,EAAuB,OAAA,KACvD,KAAA,CAAqB,MAAA,EAAQ,CAAA,4BAAA,EAA+B,GAAA,CAAI,OAAO,CAAC,CAAA,QAAA,CAAA,EAAY,OAAO,OAAO,CAAA;AAAA,MACpG,SAAA,EAAW;AAAA,QACT,MAAM,CAAC,OAAA,KAA6B,GAAA,CAA0B,gCAAA,EAAkC,QAAW,OAAO,CAAA;AAAA,QAClH,MAAA,EAAQ,CAAC,OAAA,EAAuB,OAAA,KAC9B,MAAe,MAAA,EAAQ,gCAAA,EAAkC,SAAS,OAAO,CAAA;AAAA,QAC3E,MAAA,EAAQ,CAAC,EAAA,EAAY,OAAA,EAAgC,OAAA,KACnD,KAAA,CAAe,OAAA,EAAS,CAAA,+BAAA,EAAkC,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,SAAS,OAAO,CAAA;AAAA,QACvF,MAAA,EAAQ,CAAC,EAAA,EAAY,OAAA,KACnB,KAAA,CAAY,QAAA,EAAU,CAAA,+BAAA,EAAkC,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO;AAAA;AACzF,KACF;AAAA,IAEA,OAAA,EAAS;AAAA,MACP,OAAO,CAAC,OAAA,KAA6B,GAAA,CAAW,2BAAA,EAA6B,QAAW,OAAO,CAAA;AAAA;AAAA,MAE/F,IAAA,EAAM,CAAC,MAAA,EAAgB,OAAA,KACrB,SAAA,CAAgB,CAAA,0BAAA,EAA6B,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,YAAA,CAAa,OAAO,GAAG,OAAO,CAAA;AAAA;AAAA,MAE5F,IAAA,EAAM,CAAC,MAAA,EAAgB,OAAA,KACrB,SAAA,CAAgB,CAAA,0BAAA,EAA6B,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,MAAA,EAAW,OAAO,CAAA;AAAA,MAChF,UAAU,CAAC,MAAA,EAA4B,YACrC,GAAA,CAAyB,8BAAA,EAAgC,QAAuB,OAAO,CAAA;AAAA;AAAA,MAEzF,OAAA,EAAS,CAAC,MAAA,EAAgB,OAAA,KACxB,SAAA,CAAmB,CAAA,6BAAA,EAAgC,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,YAAA,CAAa,OAAO,GAAG,OAAO;AAAA;AACpG,GACF;AACA,EAAA,OAAO,MAAA;AACT","file":"index.js","sourcesContent":["import type { StorefrontErrorCode } from './types.js'\n\nexport type StorefrontErrorInit = {\n status: number\n code: StorefrontErrorCode\n message: string\n field?: string\n /** Request URL that failed (without credentials). */\n url?: string\n cause?: unknown\n}\n\n/**\n * Error thrown by the client for any non-2xx response, network failure,\n * timeout or abort. `status` is `0` when no HTTP response was received.\n */\nexport class StorefrontError extends Error {\n override readonly name = 'StorefrontError'\n readonly status: number\n readonly code: StorefrontErrorCode\n readonly field: string | undefined\n readonly url: string | undefined\n\n constructor(init: StorefrontErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause })\n this.status = init.status\n this.code = init.code\n this.field = init.field\n this.url = init.url\n }\n\n toJSON() {\n return { name: this.name, status: this.status, code: this.code, message: this.message, field: this.field }\n }\n}\n\nexport function isStorefrontError(err: unknown): err is StorefrontError {\n return err instanceof StorefrontError || (typeof err === 'object' && err !== null && (err as { name?: unknown }).name === 'StorefrontError')\n}\n\nconst STATUS_CODES: Record<number, StorefrontErrorCode> = {\n 400: 'validation',\n 401: 'unauthorized',\n 403: 'forbidden',\n 404: 'not_found',\n 409: 'conflict',\n 422: 'invalid_state',\n 429: 'rate_limited',\n}\n\nexport function defaultCodeForStatus(status: number): StorefrontErrorCode {\n return STATUS_CODES[status] ?? (status >= 500 ? 'server_error' : 'invalid_response')\n}\n","import type { Money } from './types.js'\n\nexport type FormatMoneyOptions = {\n /** Drop `.00` when the amount is a whole number. */\n withoutTrailingZeros?: boolean\n /** Format as a plain number, without the currency symbol. */\n withoutCurrency?: boolean\n /** `symbol` (default), `narrowSymbol`, `code` or `name`. */\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name'\n}\n\n/** Parses a contract `Money` amount into a JS number (`\"1899.00\"` → `1899`). */\nexport function parseMoney(money: Money | string | null | undefined): number {\n if (money == null) return 0\n const raw = typeof money === 'string' ? money : money.amount\n const n = Number.parseFloat(raw)\n return Number.isFinite(n) ? n : 0\n}\n\n/**\n * Formats `Money` with `Intl.NumberFormat`. Works in every runtime (no DOM).\n * Falls back to `\"<amount> <code>\"` when the runtime lacks the currency.\n */\nexport function formatMoney(money: Money, locale?: string, options: FormatMoneyOptions = {}): string {\n const value = parseMoney(money)\n const whole = Number.isInteger(value)\n const digits = options.withoutTrailingZeros && whole ? 0 : undefined\n try {\n const fmt = new Intl.NumberFormat(locale, {\n ...(options.withoutCurrency\n ? { style: 'decimal', minimumFractionDigits: digits ?? 2, maximumFractionDigits: digits ?? 2 }\n : {\n style: 'currency',\n currency: money.currency_code,\n currencyDisplay: options.currencyDisplay ?? 'symbol',\n ...(digits === 0 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}),\n }),\n })\n return fmt.format(value)\n } catch {\n const amount = digits === 0 ? String(value) : value.toFixed(2)\n return options.withoutCurrency ? amount : `${amount} ${money.currency_code}`\n }\n}\n\n/** Builds a `Money` from a number, rounding to cents. */\nexport function toMoney(value: number, currencyCode: string): Money {\n return { amount: (Math.round(value * 100) / 100).toFixed(2), currency_code: currencyCode }\n}\n\n/**\n * True for public (`pk_`) tokens, the only ones that may reach a browser.\n * Private (`sk_`) tokens must stay on the server.\n */\nexport function isTokenPublishable(token: string | null | undefined): boolean {\n return typeof token === 'string' && token.startsWith('pk_')\n}\n","import type { ProductSort } from './types.js'\n\nexport type QueryValue = string | number | boolean | null | undefined\nexport type QueryParams = Record<string, QueryValue | QueryValue[]>\n\nexport type PaginationParams = {\n /** Page size (1–100; articles accept at most 50). */\n first?: number\n /** Cursor from `page_info.end_cursor`. */\n after?: string | null\n}\n\nexport type ProductListParams = PaginationParams & {\n /** Free-text search. */\n q?: string\n /** Collection handle. */\n collection?: string\n sort?: ProductSort\n /** Only products available for sale. */\n available?: boolean\n price_min?: number | string\n price_max?: number | string\n /**\n * Attribute filters, serialized as repeated `filter.<key>=<value>` params.\n * Values of one key are OR-ed; different keys are AND-ed.\n * e.g. `{ vendor: ['A', 'B'], rim: 16 }`.\n */\n filters?: Record<string, QueryValue | QueryValue[]>\n /** Restrict to these handles (max 100). Serialized comma-separated. */\n handles?: string[]\n}\n\nexport type CollectionListParams = PaginationParams\n\nexport type ArticleListParams = Omit<PaginationParams, 'first'> & {\n /** Page size (1–50). The API answers 400 `validation` above 50. */\n first?: number\n tag?: string\n q?: string\n}\n\n/** Appends params to a URLSearchParams, repeating keys for arrays and skipping nullish values. */\nexport function appendParams(search: URLSearchParams, params: QueryParams | undefined): URLSearchParams {\n if (!params) return search\n for (const [key, raw] of Object.entries(params)) {\n const values = Array.isArray(raw) ? raw : [raw]\n for (const v of values) {\n if (v === undefined || v === null || v === '') continue\n search.append(key, String(v))\n }\n }\n return search\n}\n\n/** Serializes product list params per the contract (`filter.<attr>` repeated, `handles` comma-separated). */\nexport function productListQuery(params: ProductListParams = {}): URLSearchParams {\n const { filters, handles, ...rest } = params\n const search = appendParams(new URLSearchParams(), rest as QueryParams)\n if (handles && handles.length > 0) search.set('handles', handles.join(','))\n if (filters) {\n for (const [key, raw] of Object.entries(filters)) {\n const name = key.startsWith('filter.') ? key : `filter.${key}`\n appendParams(search, { [name]: raw })\n }\n }\n return search\n}\n\n/** Reads `filter.<key>` params back into a filters record (useful in route loaders). */\nexport function parseProductFilters(search: URLSearchParams): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const [key, value] of search) {\n if (!key.startsWith('filter.')) continue\n const name = key.slice('filter.'.length)\n ;(out[name] ??= []).push(value)\n }\n return out\n}\n","import { StorefrontError, defaultCodeForStatus } from './errors.js'\nimport { isValidPoint, type GeoPoint } from './geo.js'\nimport { isTokenPublishable } from './money.js'\nimport {\n appendParams,\n productListQuery,\n type ArticleListParams,\n type CollectionListParams,\n type PaginationParams,\n type ProductListParams,\n type QueryParams,\n} from './query.js'\nimport type {\n Address,\n AddressInput,\n Article,\n Cart,\n CartBuyerInput,\n CartLineInput,\n CartLineUpdateInput,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerSession,\n CustomerSessionInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n InvoiceRequest,\n Location,\n LocationListParams,\n NearestLocation,\n InvoiceResult,\n Menu,\n Order,\n Page,\n Product,\n ProductConnection,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n} from './types.js'\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\n/** Context passed to `onRequest` / `onResponse` hooks. */\nexport type StorefrontRequestContext = {\n method: string\n /** Absolute URL, including the query string. */\n url: string\n /** Route path relative to `baseUrl`, e.g. `/storefront/products/abc`. */\n path: string\n /** Final `RequestInit` (headers already merged). Hooks may mutate it. */\n init: RequestInit & { headers: Headers }\n /** Per-call options as given by the caller. */\n options: RequestOptions\n}\n\nexport type StorefrontResponseContext = StorefrontRequestContext & {\n response: Response\n /** Milliseconds spent waiting for the response. */\n durationMs: number\n}\n\nexport type StorefrontClientOptions = {\n /** Base URL of the gateway, e.g. `https://ops.example.com/api/gw`. Routes are appended as `/storefront/...`. */\n baseUrl: string\n /** `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. */\n token: string\n /** Buyer session (`X-Customer-Token`) for `/storefront/customer/*` routes. */\n customerToken?: string | null\n /** Custom fetch (defaults to `globalThis.fetch`). */\n fetch?: FetchLike\n /** Sent as `Accept-Language`. */\n locale?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /** Abort requests that take longer than this (default: no timeout). */\n timeoutMs?: number\n /**\n * Runs before every request. Return a `Response` to short-circuit the\n * network (e.g. an SSR cache hit); return nothing to continue.\n */\n onRequest?: (ctx: StorefrontRequestContext) => void | Response | Promise<void | Response>\n /** Runs after every response (including short-circuited ones), before parsing. */\n onResponse?: (ctx: StorefrontResponseContext) => void | Promise<void>\n}\n\n/** Per-call options. Unknown keys (e.g. Next.js `next`) are forwarded to `fetch` as-is. */\nexport type RequestOptions = {\n cache?: RequestCache\n signal?: AbortSignal\n /** Framework fetch extensions, forwarded verbatim (e.g. `{ revalidate: 60, tags: ['products'] }`). */\n next?: Record<string, unknown>\n headers?: Record<string, string>\n /** Overrides the client-level timeout for this call. */\n timeoutMs?: number\n /** Overrides the client-level customer token for this call. */\n customerToken?: string | null\n [key: string]: unknown\n}\n\nexport type WriteOptions = RequestOptions & {\n /** `Idempotency-Key` header. Auto-generated for checkout when omitted. */\n idempotencyKey?: string\n}\n\nexport type PreviewOptions = RequestOptions & {\n /** Signed preview token: returns the draft (`private, no-store`). */\n preview?: string\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'\n\ntype RequestSpec = {\n method: HttpMethod\n path: string\n query?: URLSearchParams | QueryParams\n body?: unknown\n options?: WriteOptions\n /** Resolve `null` instead of throwing on 404. */\n nullOn404?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'idempotencyKey', 'preview', 'signal'])\n\n/** Generates an idempotency key (crypto.randomUUID when available). */\nexport function generateIdempotencyKey(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (c?.randomUUID) return c.randomUUID()\n // Non-cryptographic fallback for very old runtimes; the key only needs to be unique.\n return 'idem-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2)\n}\n\nfunction joinUrl(baseUrl: string, path: string): string {\n return baseUrl.replace(/\\/+$/, '') + path\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment)\n}\n\nfunction linkSignals(signals: (AbortSignal | undefined)[]): { signal: AbortSignal | undefined; cleanup: () => void } {\n const active = signals.filter((s): s is AbortSignal => !!s)\n if (active.length === 0) return { signal: undefined, cleanup: () => {} }\n if (active.length === 1) return { signal: active[0], cleanup: () => {} }\n const controller = new AbortController()\n const listeners: [AbortSignal, () => void][] = []\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason)\n break\n }\n const on = () => controller.abort(s.reason)\n s.addEventListener('abort', on, { once: true })\n listeners.push([s, on])\n }\n return {\n signal: controller.signal,\n cleanup: () => listeners.forEach(([s, on]) => s.removeEventListener('abort', on)),\n }\n}\n\nasync function readError(res: Response, url: string): Promise<StorefrontError> {\n let body: Partial<StorefrontErrorBody> | undefined\n try {\n const text = await res.text()\n body = text ? (JSON.parse(text) as Partial<StorefrontErrorBody>) : undefined\n } catch {\n body = undefined\n }\n const e = body?.error\n return new StorefrontError({\n status: res.status,\n code: e?.code ?? defaultCodeForStatus(res.status),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n url,\n })\n}\n\nexport function createStorefrontClient(config: StorefrontClientOptions) {\n if (!config.baseUrl) throw new TypeError('createStorefrontClient: baseUrl is required')\n if (!config.token) throw new TypeError('createStorefrontClient: token is required')\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n if (isBrowser && !isTokenPublishable(config.token) && config.token.startsWith('sk_')) {\n console.warn('[@asteby/storefront] A private sk_ token is being used in a browser. Use a public pk_ token instead.')\n }\n\n async function request<T>(spec: RequestSpec & { nullOn404: true }): Promise<T | null>\n async function request<T>(spec: RequestSpec): Promise<T>\n async function request<T>(spec: RequestSpec): Promise<T | null> {\n const fetchImpl: FetchLike | undefined = config.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new TypeError('createStorefrontClient: no fetch available; pass `fetch` in options')\n\n const options: WriteOptions = spec.options ?? {}\n const search = spec.query instanceof URLSearchParams ? spec.query : appendParams(new URLSearchParams(), spec.query)\n const qs = search.toString()\n const url = joinUrl(config.baseUrl, spec.path) + (qs ? `?${qs}` : '')\n\n const headers = new Headers(config.headers)\n headers.set('Accept', 'application/json')\n headers.set('Authorization', `Bearer ${config.token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n if (options.idempotencyKey) headers.set('Idempotency-Key', options.idempotencyKey)\n if (spec.body !== undefined) headers.set('Content-Type', 'application/json')\n for (const [k, v] of Object.entries(options.headers ?? {})) headers.set(k, v)\n\n // Forward passthrough options (cache, next, ...) to fetch.\n const passthrough: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(options)) if (!OWN_OPTION_KEYS.has(k) && v !== undefined) passthrough[k] = v\n\n const timeoutMs = options.timeoutMs ?? config.timeoutMs\n const timeoutController = timeoutMs && timeoutMs > 0 ? new AbortController() : undefined\n const timer = timeoutController\n ? setTimeout(() => timeoutController.abort(new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url })), timeoutMs)\n : undefined\n const linked = linkSignals([options.signal, timeoutController?.signal])\n\n const init: RequestInit & { headers: Headers } = {\n ...passthrough,\n method: spec.method,\n headers,\n ...(spec.body !== undefined ? { body: JSON.stringify(spec.body) } : {}),\n ...(linked.signal ? { signal: linked.signal } : {}),\n }\n const ctx: StorefrontRequestContext = { method: spec.method, url, path: spec.path, init, options }\n\n const started = Date.now()\n let res: Response\n try {\n const hooked = config.onRequest ? await config.onRequest(ctx) : undefined\n res = hooked instanceof Response ? hooked : await fetchImpl(url, init)\n } catch (err) {\n if (timeoutController?.signal.aborted) {\n throw new StorefrontError({ status: 0, code: 'timeout', message: `Request timed out after ${timeoutMs}ms`, url, cause: err })\n }\n if (options.signal?.aborted) {\n throw new StorefrontError({ status: 0, code: 'aborted', message: 'Request aborted', url, cause: err })\n }\n if (err instanceof StorefrontError) throw err\n throw new StorefrontError({ status: 0, code: 'network', message: err instanceof Error ? err.message : 'Network error', url, cause: err })\n } finally {\n if (timer) clearTimeout(timer)\n linked.cleanup()\n }\n\n if (config.onResponse) await config.onResponse({ ...ctx, response: res, durationMs: Date.now() - started })\n\n if (res.status === 404 && spec.nullOn404) {\n // Drain the body so the connection can be reused.\n await res.text().catch(() => undefined)\n return null\n }\n if (res.status === 304) {\n throw new StorefrontError({ status: 304, code: 'not_modified', message: 'Not modified', url })\n }\n if (!res.ok) throw await readError(res, url)\n if (res.status === 204) return undefined as T\n\n const text = await res.text()\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch (err) {\n throw new StorefrontError({ status: res.status, code: 'invalid_response', message: 'Response is not valid JSON', url, cause: err })\n }\n }\n\n const get = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const getOrNull = <T>(path: string, query?: URLSearchParams | QueryParams, options?: RequestOptions) =>\n request<T>({ method: 'GET', path, nullOn404: true, ...(query ? { query } : {}), ...(options ? { options } : {}) })\n const write = <T>(method: HttpMethod, path: string, body?: unknown, options?: WriteOptions) =>\n request<T>({ method, path, ...(body !== undefined ? { body } : {}), ...(options ? { options } : {}) })\n\n const cartPath = (id: string, rest = '') => `/storefront/carts/${enc(id)}${rest}`\n const previewQuery = (options?: PreviewOptions) => (options?.preview ? { preview: options.preview } : undefined)\n\n const client = {\n /** Resolved configuration (read-only). */\n config: Object.freeze({ ...config }) as Readonly<StorefrontClientOptions>,\n\n /** Low-level escape hatch: any route under `baseUrl`. */\n request,\n\n /** Returns a new client that sends the given buyer session token. */\n withCustomerToken(customerToken: string | null) {\n return createStorefrontClient({ ...config, customerToken })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n products: {\n list: (params?: ProductListParams, options?: RequestOptions) =>\n get<ProductConnection>('/storefront/products', productListQuery(params), options),\n /** `null` when the product does not exist or is unpublished. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Product>(`/storefront/products/${enc(handle)}`, undefined, options),\n recommendations: (handle: string, options?: RequestOptions) =>\n get<{ nodes: Product[] }>(`/storefront/products/${enc(handle)}/recommendations`, undefined, options),\n },\n\n collections: {\n list: (params?: CollectionListParams, options?: RequestOptions) =>\n get<Connection<Collection>>('/storefront/collections', params as QueryParams, options),\n /** `null` when the collection does not exist. */\n get: (handle: string, options?: RequestOptions) =>\n getOrNull<Collection>(`/storefront/collections/${enc(handle)}`, undefined, options),\n },\n\n locations: {\n /** Branches of the shop. With `postal_code` they come ordered by distance (`distance_km`). */\n list: (params?: LocationListParams, options?: RequestOptions) =>\n get<{ nodes: Location[] }>('/storefront/locations', params as QueryParams, options),\n /** `null` when the branch does not exist or is not visible. */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<Location>(`/storefront/locations/${enc(id)}`, undefined, options),\n /**\n * Branches ordered by distance to a point, closest first. The server rounds the coordinates (0.01°, ~1 km)\n * and never stores them; this client does not log or keep them either. The answer is `private, no-store`\n * (it depends on the buyer's position), so do not put it in a shared cache. Note `onRequest` hooks and\n * `fetch` wrappers do see the URL: do not log it. Throws `TypeError` for an invalid point.\n */\n nearest: (point: GeoPoint, options?: RequestOptions) => {\n if (!isValidPoint(point)) throw new TypeError('locations.nearest: lat/lng must be a valid point')\n return get<{ nodes: NearestLocation[] }>('/storefront/locations/nearest', { lat: point.lat, lng: point.lng }, { cache: 'no-store', ...options })\n },\n },\n\n stock: {\n /** Stock for up to 250 SKUs. */\n get: (skus: string[], options?: RequestOptions) =>\n get<{ nodes: StockLevel[] }>('/storefront/stock', { sku: skus }, options),\n },\n\n carts: {\n create: (input: { lines?: CartLineInput[] } = {}, options?: WriteOptions) =>\n write<Cart>('POST', '/storefront/carts', input, options),\n /** `null` when the cart does not exist (e.g. expired cookie). */\n get: (id: string, options?: RequestOptions) => getOrNull<Cart>(cartPath(id), undefined, options),\n addLines: (id: string, lines: CartLineInput[], options?: WriteOptions) =>\n write<Cart>('POST', cartPath(id, '/lines'), { lines }, options),\n /** Quantity `0` removes the line. */\n updateLines: (id: string, lines: CartLineUpdateInput[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines }, options),\n removeLines: (id: string, lineIds: string[], options?: WriteOptions) =>\n write<Cart>('PATCH', cartPath(id, '/lines'), { lines: lineIds.map((lid) => ({ id: lid, quantity: 0 })) }, options),\n setDiscountCodes: (id: string, codes: string[], options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/discount-codes'), { codes }, options),\n setBuyer: (id: string, buyer: CartBuyerInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/buyer'), buyer, options),\n setShippingAddress: (id: string, address: AddressInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/shipping-address'), address, options),\n deliveryOptions: (id: string, options?: RequestOptions) =>\n get<DeliveryOptions>(cartPath(id, '/delivery-options'), undefined, options),\n /** Payment providers active for the cart's market; send the chosen `key` as `payment_method`. */\n paymentMethods: (id: string, options?: RequestOptions) =>\n get<PaymentMethods>(cartPath(id, '/payment-methods'), undefined, options),\n setDelivery: (id: string, delivery: DeliveryInput, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/delivery'), delivery, options),\n /** Reserves stock and creates the order. Sends `Idempotency-Key` (auto-generated if omitted). */\n checkout: (id: string, input: CheckoutInput, options: WriteOptions = {}) =>\n write<CheckoutResult>('POST', cartPath(id, '/checkout'), input, {\n ...options,\n idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),\n }),\n },\n\n checkouts: {\n /**\n * Reads a placed checkout (same shape as the `carts.checkout` result). `order.number` is `null` until OPS\n * has created the order (a few hundred ms after checkout); poll once or twice and, if it is still `null`,\n * keep telling the buyer the number will arrive by email. Needs a server token (`checkout:write`).\n * `null` when the checkout does not exist. Never cache.\n */\n get: (id: string, options?: RequestOptions) =>\n getOrNull<CheckoutResult>(`/storefront/checkouts/${enc(id)}`, undefined, options),\n },\n\n customer: {\n /** Sends a one-time code by email or SMS/WhatsApp. */\n requestOtp: (identifier: CustomerIdentifier, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/otp', identifier, options),\n /** Exchanges the code for a buyer session (`token` goes in `customerToken`). */\n createSession: (input: CustomerSessionInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/session', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n orders: (params?: PaginationParams, options?: RequestOptions) =>\n get<Connection<Order>>('/storefront/customer/orders', params as QueryParams, options),\n /** `null` when the order does not exist or belongs to someone else. */\n order: (id: string, options?: RequestOptions) =>\n getOrNull<Order>(`/storefront/customer/orders/${enc(id)}`, undefined, options),\n requestReturn: (orderId: string, input: ReturnRequestInput, options?: WriteOptions) =>\n write<ReturnRequest>('POST', `/storefront/customer/orders/${enc(orderId)}/returns`, input, options),\n requestInvoice: (orderId: string, input: InvoiceRequest, options?: WriteOptions) =>\n write<InvoiceResult>('POST', `/storefront/customer/orders/${enc(orderId)}/invoice`, input, options),\n addresses: {\n list: (options?: RequestOptions) => get<{ nodes: Address[] }>('/storefront/customer/addresses', undefined, options),\n create: (address: AddressInput, options?: WriteOptions) =>\n write<Address>('POST', '/storefront/customer/addresses', address, options),\n update: (id: string, address: Partial<AddressInput>, options?: WriteOptions) =>\n write<Address>('PATCH', `/storefront/customer/addresses/${enc(id)}`, address, options),\n delete: (id: string, options?: WriteOptions) =>\n write<void>('DELETE', `/storefront/customer/addresses/${enc(id)}`, undefined, options),\n },\n },\n\n content: {\n theme: (options?: RequestOptions) => get<Theme>('/storefront/content/theme', undefined, options),\n /** `null` when the page does not exist. */\n page: (handle: string, options?: PreviewOptions) =>\n getOrNull<Page>(`/storefront/content/pages/${enc(handle)}`, previewQuery(options), options),\n /** `null` when the menu does not exist. */\n menu: (handle: string, options?: RequestOptions) =>\n getOrNull<Menu>(`/storefront/content/menus/${enc(handle)}`, undefined, options),\n articles: (params?: ArticleListParams, options?: RequestOptions) =>\n get<Connection<Article>>('/storefront/content/articles', params as QueryParams, options),\n /** `null` when the article does not exist. */\n article: (handle: string, options?: PreviewOptions) =>\n getOrNull<Article>(`/storefront/content/articles/${enc(handle)}`, previewQuery(options), options),\n },\n }\n return client\n}\n\nexport type StorefrontClient = ReturnType<typeof createStorefrontClient>\n"]}