@asteby/storefront 0.14.0 → 0.16.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.
- package/dist/cli.js +19 -1
- package/dist/fiscal-document.cjs +72 -8
- package/dist/fiscal-document.cjs.map +1 -1
- package/dist/fiscal-document.d.cts +34 -4
- package/dist/fiscal-document.d.ts +34 -4
- package/dist/fiscal-document.js +71 -9
- package/dist/fiscal-document.js.map +1 -1
- package/dist/index.cjs +18 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/mock.cjs +121 -1
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.d.cts +3 -1
- package/dist/mock.d.ts +3 -1
- package/dist/mock.js +121 -1
- package/dist/mock.js.map +1 -1
- package/dist/mockup.d.cts +1 -1
- package/dist/mockup.d.ts +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.js +1 -1
- package/dist/{types-BeTemDg6.d.ts → types-DFK20t_g.d.ts} +55 -1
- package/dist/{types-BuKb-zbi.d.cts → types-TQPpYbac.d.cts} +55 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/money.ts","../src/query.ts","../src/client.ts","../src/payment-errors.ts","../src/diagnose.ts","../src/promotions.ts","../src/market.ts","../src/invoice-docs.ts","../src/delivery.ts"],"names":["fmt"],"mappings":"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","file":"index.js","sourcesContent":["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 CartRecommendations,\n PaymentAttemptResult,\n PaymentConfig,\n PaymentSubmitInput,\n PromotionsList,\n RecommendationPlacement,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerCapabilities,\n CustomerUpdateInput,\n CustomerPasswordLoginInput,\n CustomerRegisterInput,\n CustomerRegisterResult,\n CustomerResetPasswordInput,\n CustomerSession,\n CustomerSessionInput,\n CustomerSetPasswordInput,\n CustomerVerifyRegistrationInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n InvoiceFile,\n InvoiceFileKind,\n InvoiceRequest,\n Location,\n LocationListParams,\n NearestLocation,\n InvoiceResult,\n Menu,\n Order,\n Page,\n PendingPayment,\n Product,\n ProductConnection,\n Region,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n RestockSubscriptionInput,\n RestockSubscriptionResult,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n TokenIntrospection,\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 /**\n * `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. A function is called on\n * EVERY request, so a token read from a file (`createFileTokenSource` in `@asteby/storefront/node`) can rotate\n * without restarting the server.\n */\n token: string | (() => 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 /**\n * Public host of the storefront (`godsnutrition.com`), sent as `X-Storefront-Domain`. Platform (`pt_`)\n * tokens need it to pick the organization; with an org-scoped token it only scopes the market.\n */\n domain?: string\n /**\n * Market the request is for (`mx`, `us`), sent as `<domain>#<market>` in `X-Storefront-Domain`. It lets ONE\n * public domain serve several markets (the storefront routes by path prefix, e.g. `/us`): OPS honors it\n * when the organization has that market active and otherwise falls back to the domain's own market.\n * Ignored without `domain`.\n */\n market?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /**\n * IP address of the shopper, for SERVER-side calls (SSR, route actions) made with an\n * `sk_`/`pt_` token. Sent as `X-Storefront-Client-IP`, which the gateway honors only for\n * tokens issued with the `trust_client_ip` option: the rate limit is then charged per\n * shopper instead of to the store's single token bucket, and the OTP flow limits the\n * shopper's IP instead of the server's. Pass the IP from your own connection or trusted\n * proxy, never from a header the browser can forge. Never sent with a `pk_` token (the\n * gateway already separates those by caller IP). Invalid values are dropped.\n */\n clientIp?: string | null\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 /** Overrides the client-level shopper IP for this call (see `StorefrontClientOptions.clientIp`). */\n clientIp?: 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 * Never follow a redirect (`redirect: 'error'`, and a redirected answer is refused): for answers that carry the\n * buyer's documents, so neither the customer token nor the request ever travels to another host.\n */\n noRedirect?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'clientIp', 'idempotencyKey', 'preview', 'signal'])\n\n/** Header the gateway reads (only for tokens with `trust_client_ip`). */\nexport const CLIENT_IP_HEADER = 'X-Storefront-Client-IP'\n\n/**\n * Returns the single IP literal in `raw`, or undefined. Takes the form a server hands over\n * (`::ffff:1.2.3.4`, `[2001:db8::1]`) and rejects lists, ports, zones and text so the\n * header is never a forgery vector.\n */\nexport function normalizeClientIp(raw: string | null | undefined): string | undefined {\n if (!raw) return undefined\n let v = raw.trim()\n if (v.startsWith('[') && v.endsWith(']')) v = v.slice(1, -1)\n if (!v || v.length > 45 || /[\\s,%/]/.test(v)) return undefined\n if (/^[0-9]{1,3}(\\.[0-9]{1,3}){3}$/.test(v)) {\n return v.split('.').every((o) => Number(o) <= 255) ? v : undefined\n }\n // IPv6 (incl. IPv4-mapped): hex groups and colons, at most one \"::\".\n if (!v.includes(':') || !/^[0-9a-fA-F:.]+$/.test(v) || v.split('::').length > 2) return undefined\n try {\n new URL(`http://[${v}]/`)\n } catch {\n return undefined\n }\n return v\n}\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 // `.` and `..` (also as `%2e`) are dot segments: the URL parser would resolve them and the request would land on\n // another route with the same credentials.\n if (typeof segment !== 'string' || /^(?:\\.|%2e){1,2}$/i.test(segment)) throw new TypeError(`Invalid path segment: ${String(segment)}`)\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\nfunction scopeList(raw: unknown): string[] {\n return Array.isArray(raw) ? raw.filter((s): s is string => typeof s === 'string' && s.length > 0) : []\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 // The gateway may put `code` / `required_scopes` at the top level or inside `error` (or its `details`).\n const top = body as { code?: unknown; required_scopes?: unknown } | undefined\n const code = e?.code ?? (typeof top?.code === 'string' ? top.code : undefined)\n const requiredScopes = code === 'insufficient_scope' ? scopeList(e?.required_scopes ?? top?.required_scopes ?? (e?.details as { required_scopes?: unknown } | undefined)?.required_scopes) : []\n return new StorefrontError({\n status: res.status,\n code: code ?? defaultCodeForStatus(res.status),\n ...(requiredScopes.length ? { requiredScopes } : {}),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n ...(e?.details !== undefined ? { details: e.details } : {}),\n ...(typeof e?.retryable === 'boolean' ? { retryable: e.retryable } : {}),\n ...(typeof e?.retry_after === 'number' && e.retry_after > 0 ? { retryAfter: e.retry_after } : {}),\n ...(typeof e?.checkout_id === 'string' && e.checkout_id ? { checkoutId: e.checkout_id } : {}),\n ...(e?.cost !== undefined ? { cost: e.cost } : {}),\n ...(typeof e?.message_en === 'string' && e.message_en ? { messageEn: e.message_en } : {}),\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 currentToken = (): string => {\n const t = typeof config.token === 'function' ? config.token() : config.token\n if (!t) throw new StorefrontError({ status: 0, code: 'unauthorized', message: 'Storefront token is empty (token source returned nothing)' })\n return t\n }\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n const initialToken = typeof config.token === 'string' ? config.token : ''\n if (isBrowser && initialToken.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 const token = currentToken()\n headers.set('Authorization', `Bearer ${token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n if (config.domain) headers.set('X-Storefront-Domain', storefrontDomainHeader(config.domain, config.market))\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n const clientIp = options.clientIp !== undefined ? options.clientIp : config.clientIp\n // Server-side tokens only: a pk_ token already gets a per-caller bucket from the gateway.\n const ip = isTokenPublishable(token) ? undefined : normalizeClientIp(clientIp)\n if (ip) headers.set(CLIENT_IP_HEADER, ip)\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 ...(spec.noRedirect ? { redirect: 'error' as const } : {}),\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 (spec.noRedirect && res.redirected) {\n await res.text().catch(() => undefined)\n throw new StorefrontError({ status: 502, code: 'invalid_response', message: 'The answer was redirected; it is refused', url })\n }\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 token: {\n /**\n * What the token in use is and can do (`GET {baseUrl}/_token`, a gateway route, not a `/storefront` one).\n * Needs no scope, so it answers even when the token is under-provisioned: `missing_scopes` says what to repair.\n */\n introspect: async (options?: RequestOptions): Promise<TokenIntrospection> => {\n // OPS answers with the kernel envelope `{success, data}`; a flat object is accepted too.\n const body = await get<TokenIntrospection | { success?: boolean; data?: TokenIntrospection }>('/_token', undefined, options)\n const env = body as { success?: unknown; data?: TokenIntrospection }\n return typeof env?.success === 'boolean' && env.data ? env.data : (body as TokenIntrospection)\n },\n },\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 /** Returns a new client that reports the shopper's IP (`X-Storefront-Client-IP`) on every call. */\n withClientIp(clientIp: string | null | undefined) {\n return createStorefrontClient({ ...config, clientIp: clientIp ?? null })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n /**\n * How the market formats, taxes, addresses and invoices (`fiscal_id` carries the tax-id pattern, the regimes,\n * the invoice uses and the identity documents the buyer can upload). Cacheable; `null` when the organization\n * has no region configured.\n */\n region: (options?: RequestOptions) => getOrNull<Region>('/storefront/region', undefined, options),\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 restock: {\n /**\n * \"Notify me when it is back\". Idempotent per contact + SKU; always answers `202 pending`.\n * Only offered when `availability.notify_available` is true. Needs `customer:write`.\n */\n subscribe: (input: RestockSubscriptionInput, options?: WriteOptions) =>\n write<RestockSubscriptionResult>('POST', '/storefront/restock-subscriptions', input, 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 /** Order note (up to 1000 characters). `null` or empty clears it. */\n setNote: (id: string, note: string | null, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/note'), { note }, options),\n /**\n * Asks for an invoice for this cart (`null` or `{ requested: false }` withdraws it). The server validates the\n * data against the region BEFORE any charge: `422` with `field: 'invoice.<field>'` (e.g. `invoice.tax_regime`)\n * names what to fix. `409 already_checked_out` when the cart is already an order. Checkout uses it when\n * `CheckoutInput.invoice` is omitted.\n */\n setInvoice: (id: string, invoice: InvoiceRequest | null, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/invoice'), invoice ?? { requested: false }, options),\n /**\n * Cross-sell suggestions: only sellable variants, with `unlocks` when adding one reaches the next\n * discount tier. `first` 1-8 (default 4). `private, no-store`; ask on demand, not on every render.\n */\n recommendations: (id: string, params: { first?: number; placement?: RecommendationPlacement } = {}, options?: RequestOptions) =>\n get<CartRecommendations>(cartPath(id, '/recommendations'), params as QueryParams, 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 promotions: {\n /** Public promotions and the entry pop-up announcement for the request's market (cacheable). */\n list: (options?: RequestOptions) => get<PromotionsList>('/storefront/promotions', undefined, options),\n },\n\n checkouts: {\n /** What to mount for an embedded checkout (public key, options, amount) and whether it can still be paid. Never cache. */\n paymentConfig: (id: string, options?: RequestOptions) =>\n getOrNull<PaymentConfig>(`/storefront/checkouts/${enc(id)}/payment-config`, undefined, options),\n /**\n * Pays a checkout in the page. The browser brings only what the provider SDK returned (`provider_data`);\n * the amount is the server's. `idempotencyKey` is REQUIRED (use `paymentIdempotencyKey(checkoutId, attempt)`):\n * repeating a call with the same key never charges twice. Needs a server token (`checkout:write`).\n */\n pay: (id: string, input: PaymentSubmitInput, options: WriteOptions & { idempotencyKey: string }) => {\n if (!options || typeof options.idempotencyKey !== 'string' || !options.idempotencyKey.trim()) {\n throw new TypeError('checkouts.pay: idempotencyKey is required')\n }\n return write<PaymentAttemptResult>('POST', `/storefront/checkouts/${enc(id)}/payment`, input, options)\n },\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 /** What the store supports (password login, email verification, OTP channels). Drives which forms to show. */\n capabilities: (options?: RequestOptions) =>\n get<CustomerCapabilities>('/storefront/customer/capabilities', undefined, options),\n /**\n * Creates an account with email + password. `verification_required` (202): a code was emailed, finish with\n * `verifyRegistration`. `created` (201): the account exists and `session` is ready. `409` when the email is taken.\n */\n register: async (input: CustomerRegisterInput, options?: WriteOptions): Promise<CustomerRegisterResult> => {\n const res = await write<{ status: 'verification_required' } | CustomerSession>('POST', '/storefront/customer/register', input, options)\n return res && 'token' in res ? { status: 'created', session: res } : { status: 'verification_required' }\n },\n /** Confirms the emailed registration code and returns the new buyer session. */\n verifyRegistration: (input: CustomerVerifyRegistrationInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/register/verify', input, options),\n /** Email + password login. `401` for wrong credentials. */\n loginWithPassword: (input: CustomerPasswordLoginInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/login', input, options),\n /** Sets or changes the password of the signed-in buyer (`options.customerToken`, or a `withCustomerToken` client). */\n setPassword: (input: CustomerSetPasswordInput, options?: WriteOptions) =>\n write<void>('PUT', '/storefront/customer/password', input, options),\n /** Resets a forgotten password with the code from `requestOtp({ email })`. */\n resetPassword: (input: CustomerResetPasswordInput, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/password/reset', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n /** Updates the profile and the saved fiscal data; `fiscal: null` deletes the latter. `422` with `field: 'fiscal.<field>'`. */\n update: (input: CustomerUpdateInput, options?: WriteOptions) =>\n write<Customer>('PATCH', '/storefront/customer', input, 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 /**\n * Checkouts waiting for their payment (cash voucher: OXXO, SPEI). They are not orders yet; once the payment\n * confirms they leave this list and show up in `orders`.\n */\n pendingPayments: async (params?: PaginationParams, options?: RequestOptions): Promise<Connection<PendingPayment>> =>\n // An OPS older than the route answers 404: it has no pending payments to list (a 401 still throws).\n (await getOrNull<Connection<PendingPayment>>('/storefront/customer/pending-payments', params as QueryParams, options)) ?? {\n nodes: [],\n page_info: { has_next_page: false, end_cursor: null },\n total_count: 0,\n },\n /**\n * Reads one file (`pdf` | `xml`) of an invoice or credit note of the buyer's order, through the authenticated\n * route (`order_invoice_file`): the answer is the file itself (base64), never a URL, so neither the buyer token\n * nor a link of the PAC reaches the browser. Call it from YOUR server and stream the bytes\n * (`invoiceFileBytes`). `null` when the order, the document or the file does not exist or is not the buyer's.\n */\n invoiceFile: async (orderId: string, invoiceId: string, kind: InvoiceFileKind, options?: RequestOptions): Promise<InvoiceFile | null> => {\n if (kind !== 'pdf' && kind !== 'xml') throw new TypeError(\"invoiceFile: kind must be 'pdf' or 'xml'\")\n const file = await request<InvoiceFile>({\n method: 'GET',\n path: `/storefront/customer/orders/${enc(orderId)}/invoices/${enc(invoiceId)}/${kind}`,\n options: { ...options, cache: 'no-store' },\n nullOn404: true,\n noRedirect: true,\n })\n if (file === null) return null\n if (!file || typeof file.content_base64 !== 'string' || typeof file.filename !== 'string' || typeof file.content_type !== 'string') {\n throw new StorefrontError({ status: 502, code: 'invalid_response', message: 'The invoice file answer is not a file' })\n }\n return { filename: file.filename, content_type: file.content_type, content_base64: file.content_base64 }\n },\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\n/** `X-Storefront-Domain` value: the host, plus `#<market>` when a valid market code is given. */\nexport function storefrontDomainHeader(domain: string, market?: string | null): string {\n const host = domain.trim()\n const code = (market ?? '').trim().toLowerCase()\n return code && /^[a-z0-9_-]{1,32}$/.test(code) ? `${host}#${code}` : host\n}\n","/**\n * Classification of the failures of a card payment (`POST pay` / `GET status`). No texts, no DOM, no server APIs: the\n * shop's server uses it to answer with `kind` and `retryable`, and the browser transport uses it to decide whether to\n * repeat, ask for the status or give up.\n *\n * Rule that never changes: an INDETERMINATE result (`transient`, `in_progress`) is never charged again with another\n * idempotency key; it is repeated with the SAME key or its status is read.\n */\n\nexport type PaymentErrorClassKind =\n /** OPS or the provider did not answer (5xx, timeout, network). The charge may or may not have happened. */\n | 'transient'\n /** A payment is already in progress for this order (409): read the status, do not charge again. */\n | 'in_progress'\n /** Too many attempts (429). */\n | 'rate_limited'\n /** Credentials or configuration of the merchant with the provider: not the buyer's fault. */\n | 'merchant_config'\n /** The provider refused the charge at API level (`payment_provider_rejected`): definitive, nothing was charged. */\n | 'provider_declined'\n /** The cart already became an order and OPS will not open a new attempt (`422 invalid_state`). */\n | 'stale_checkout'\n | 'expired'\n | 'price_mismatch'\n | 'store_closed'\n | 'validation'\n | 'other'\n\nexport type PaymentErrorClass = { kind: PaymentErrorClassKind; retryable: boolean }\n\nexport type PaymentErrorLike = {\n status?: number | null\n code?: string | null\n field?: string | null\n /** `error.retryable` as OPS declared it (`StorefrontError.retryable`). */\n retryable?: boolean | null\n /** `error.checkout_id` (`StorefrontError.checkoutId`). */\n checkoutId?: string | null\n /** Raw `error.details`; a `retryable` inside is honoured too (older bodies). */\n details?: unknown\n}\n\n/** Did OPS expressly say the failure must NOT be repeated (`retryable: false`, on the error or inside `details`)? */\nexport function opsSaysNotRetryable(err: PaymentErrorLike): boolean {\n if (err.retryable === false) return true\n const d = err.details\n return typeof d === 'object' && d !== null && (d as { retryable?: unknown }).retryable === false\n}\n\n/** Field the shop's server sets when IT refuses a payment row that is not offered (so it is not read as a stale checkout). */\nexport const PAYMENT_CHOICE_REFUSED_FIELD = 'payment_choice'\n\nconst MERCHANT_CONFIG_CODE = /credential|not_configured|unconfigured|invalid_access|access_token|provider_config|merchant|invalid_public_key|unauthorized/i\n\n/**\n * What a payment failure means and whether repeating it can help. What OPS declares (`retryable`, stable codes) wins\n * over the HTTP status: a 502 with a stable code is an answer, not \"no response\".\n */\nexport function classifyPaymentError(err: PaymentErrorLike): PaymentErrorClass {\n const status = typeof err.status === 'number' ? err.status : 0\n const code = typeof err.code === 'string' ? err.code : ''\n if (code === 'store_not_ready') return { kind: 'store_closed', retryable: false }\n if (code === 'price_mismatch' || (status === 422 && err.field === 'expected_total')) return { kind: 'price_mismatch', retryable: false }\n if (status === 409 && (code === 'payment_in_progress' || err.field === 'payment_in_progress')) return { kind: 'in_progress', retryable: true }\n if (status === 409 && code === 'expired') return { kind: 'expired', retryable: false }\n if (status === 429 || code === 'too_many_attempts' || code === 'rate_limited') return { kind: 'rate_limited', retryable: true }\n if (status === 422 && code === 'invalid_state') {\n if (err.field === PAYMENT_CHOICE_REFUSED_FIELD) return { kind: 'other', retryable: false }\n return { kind: 'stale_checkout', retryable: false }\n }\n if (code === 'payment_provider_misconfigured') return { kind: 'merchant_config', retryable: false }\n if (code === 'payment_provider_rejected') return { kind: 'provider_declined', retryable: false }\n if (MERCHANT_CONFIG_CODE.test(code) || status === 401 || status === 403) return { kind: 'merchant_config', retryable: false }\n // OPS answered and said \"do not repeat\": definitive, not indeterminate (there is no lost answer to verify).\n if (status >= 500 && opsSaysNotRetryable(err)) return { kind: 'other', retryable: false }\n if (status === 0 || status >= 500 || code === 'network' || code === 'timeout' || code === 'unavailable') return { kind: 'transient', retryable: true }\n if (status === 400 || code === 'validation') return { kind: 'validation', retryable: false }\n return { kind: 'other', retryable: false }\n}\n","import type { StorefrontClient } from './client.js'\nimport { isStorefrontError } from './errors.js'\nimport type { TokenIntrospection } from './types.js'\n\n/** `sk_…a91f`: the prefix and the last four characters, never enough to use the token. */\nexport function maskToken(token: string | null | undefined): string {\n if (!token) return '(sin token)'\n const prefix = /^[a-z]{2}_/.exec(token)?.[0] ?? ''\n return token.length <= prefix.length + 8 ? `${prefix}…` : `${prefix}…${token.slice(-4)}`\n}\n\nexport type DiagnoseOptions = {\n /** Where the warning goes (default `console.warn`). Receives ONE line per problem. */\n log?: (message: string) => void\n /** Name of the connection, shown in the repair path. */\n connectionName?: string\n /** Give up after this long (default 3000 ms). */\n timeoutMs?: number\n}\n\n/** Where the operator repairs a connection in OPS (es-MX, as the screen names it). */\nexport function repairPath(connectionName?: string): string {\n return `OPS → Conexiones y API → ${connectionName ?? '<conexión>'} → Reparar permisos`\n}\n\n/**\n * Startup check of the store's credential: asks `token.introspect()` and, when scopes are missing, logs ONE clear\n * warning with the repair path (never the token, only `sk_…a91f`). It NEVER throws and is meant to be fired and\n * forgotten, so it cannot delay or break the boot:\n *\n * ```ts\n * void diagnose(storefront)\n * ```\n *\n * Resolves with the introspection, or `null` when it could not be obtained (older OPS, outage, bad token).\n */\nexport async function diagnose(client: StorefrontClient, options: DiagnoseOptions = {}): Promise<TokenIntrospection | null> {\n const log = options.log ?? ((m: string) => console.warn(m))\n const timeoutMs = options.timeoutMs ?? 3000\n const raw = client.config.token\n let mask: string\n try {\n mask = maskToken(typeof raw === 'function' ? raw() : raw)\n } catch {\n mask = maskToken(null)\n }\n try {\n const info = await client.token.introspect({ signal: AbortSignal.timeout(timeoutMs) })\n const missing = Array.isArray(info?.missing_scopes) ? info.missing_scopes : []\n if (missing.length > 0) {\n log(\n `[@asteby/storefront] La credencial ${mask} no tiene permisos que la tienda necesita: ${missing.join(', ')}. ` +\n `Repáralo en ${repairPath(options.connectionName)} (no hace falta cambiar la clave ni reiniciar).`,\n )\n }\n return info ?? null\n } catch (err) {\n if (isStorefrontError(err) && err.status === 401) {\n try {\n log(`[@asteby/storefront] OPS rechazó la credencial ${mask} (401): está revocada o vencida. Vuelve a conectar la tienda en OPS → Conexiones y API.`)\n } catch {\n /* a broken logger must not break boot */\n }\n }\n return null\n }\n}\n","/**\n * Promotion presentation: turns `Cart.promotions` (computed by OPS) into the\n * labels and bar states a storefront shows. Pure functions, no DOM.\n *\n * The shop never computes a discount here: `remaining`, `percent`, `reached`\n * and `percent_of_max` are the server's. The only arithmetic is clamping a\n * server percentage into 0-100 for `aria-valuenow`.\n */\nimport { availabilityLocale, formatAvailabilityMessage, type AvailabilityLocale } from './availability.js'\nimport { formatMoney } from './money.js'\nimport type { CartPromotions, Money, PromotionReward } from './types.js'\n\nexport type PromotionLocale = AvailabilityLocale\n\nexport type PromotionMessageKey =\n | 'discount.next'\n | 'discount.next_upgrade'\n | 'discount.applied'\n | 'discount.max'\n | 'discount.suppressed'\n | 'discount.unlocks'\n | 'discount.remaining'\n | 'shipping.progress'\n | 'shipping.reached'\n | 'shipping.always'\n | 'reward.free_shipping'\n | 'bar.discount'\n | 'bar.shipping'\n | 'popup.close'\n | 'popup.valid_until'\n | 'popup.limited_time'\n | 'popup.discount_tier'\n | 'popup.free_shipping_min'\n | 'popup.free_shipping_always'\n | 'upsell.title'\n | 'upsell.subtitle'\n | 'upsell.next_level'\n | 'upsell.you_miss'\n | 'upsell.unlocks_reward'\n | 'upsell.total_saved'\n | 'upsell.current_benefit'\n | 'upsell.status'\n | 'upsell.status_pending'\n | 'upsell.status_active'\n | 'upsell.next_reward'\n | 'upsell.suggestions'\n | 'upsell.add'\n | 'upsell.adding'\n | 'upsell.flavor'\n | 'upsell.unlocks_badge'\n | 'upsell.unlocked'\n | 'upsell.best'\n | 'upsell.skip'\n | 'upsell.continue'\n | 'upsell.footer'\n | 'upsell.sold_out'\n | 'upsell.error'\n | 'note.label'\n | 'note.placeholder'\n | 'note.save'\n | 'note.saving'\n | 'note.saved'\n | 'note.error'\n | 'note.counter'\n\nexport type PromotionMessages = Record<PromotionMessageKey, string>\n\nconst ES: PromotionMessages = {\n 'discount.next': 'Añade {remaining} para activar tu descuento automático',\n 'discount.next_upgrade': 'Añade {remaining} para subir a {reward}',\n 'discount.applied': '¡Tienes {reward} de descuento!',\n 'discount.max': '¡Tienes {reward} de descuento, el máximo!',\n 'discount.suppressed': 'Tu código de descuento ya te da un mejor precio.',\n 'discount.unlocks': 'Desbloqueas {reward} de descuento',\n 'discount.remaining': 'Te faltan {remaining}',\n 'shipping.progress': 'Añade {remaining} para envío gratis',\n 'shipping.reached': '¡Felicidades! Tienes envío gratis',\n 'shipping.always': 'Envío gratis en todo tu pedido',\n 'reward.free_shipping': 'Envío gratis',\n 'bar.discount': 'Progreso del descuento automático',\n 'bar.shipping': 'Progreso del envío gratis',\n 'popup.close': 'Cerrar',\n 'popup.valid_until': 'Válido hasta el {date}',\n 'popup.limited_time': 'Por tiempo limitado',\n 'popup.discount_tier': '{reward} comprando {threshold}',\n 'popup.free_shipping_min': 'Envío gratis desde {threshold}',\n 'popup.free_shipping_always': 'Envíos gratis sin mínimo de compra',\n 'upsell.title': 'Completa tu compra y desbloquea más',\n 'upsell.subtitle': 'Descuento automático',\n 'upsell.next_level': 'Siguiente nivel',\n 'upsell.you_miss': 'Te faltan {remaining}',\n 'upsell.unlocks_reward': 'Desbloqueas {reward} de descuento',\n 'upsell.total_saved': 'Total ahorrado',\n 'upsell.current_benefit': 'Beneficio actual',\n 'upsell.status': 'Estado',\n 'upsell.status_pending': 'Pendiente',\n 'upsell.status_active': 'Activo',\n 'upsell.next_reward': 'Siguiente recompensa {reward} · {threshold}',\n 'upsell.suggestions': 'Suma y desbloquea · Productos que pueden interesarte',\n 'upsell.add': 'Agregar y avanzar +',\n 'upsell.adding': 'Agregando…',\n 'upsell.flavor': 'Sabor',\n 'upsell.unlocks_badge': 'Desbloquea tu {reward}',\n 'upsell.unlocked': '¡Desbloqueaste {reward}!',\n 'upsell.best': 'Tienes el mejor descuento: {reward}',\n 'upsell.skip': 'Continuar sin agregar',\n 'upsell.continue': 'Continuar al pago',\n 'upsell.footer': 'Tu mejor descuento se aplica automáticamente',\n 'upsell.sold_out': 'Se agotó este sabor, elige otro.',\n 'upsell.error': 'No pudimos agregarlo. Intenta de nuevo.',\n 'note.label': 'Añadir nota',\n 'note.placeholder': 'Instrucciones para tu pedido',\n 'note.save': 'Guardar nota',\n 'note.saving': 'Guardando…',\n 'note.saved': 'Guardada',\n 'note.error': 'No se pudo guardar la nota. Intenta de nuevo.',\n 'note.counter': '{n} de {max} caracteres',\n}\n\nconst EN: PromotionMessages = {\n 'discount.next': 'Add {remaining} to unlock your automatic discount',\n 'discount.next_upgrade': 'Add {remaining} to move up to {reward}',\n 'discount.applied': 'You have {reward} off!',\n 'discount.max': 'You have {reward} off, the maximum!',\n 'discount.suppressed': 'Your discount code already gives you a better price.',\n 'discount.unlocks': 'Unlock {reward} off',\n 'discount.remaining': '{remaining} to go',\n 'shipping.progress': 'Add {remaining} for free shipping',\n 'shipping.reached': 'Congratulations! You get free shipping',\n 'shipping.always': 'Free shipping on your whole order',\n 'reward.free_shipping': 'Free shipping',\n 'bar.discount': 'Automatic discount progress',\n 'bar.shipping': 'Free shipping progress',\n 'popup.close': 'Close',\n 'popup.valid_until': 'Valid until {date}',\n 'popup.limited_time': 'Limited time',\n 'popup.discount_tier': '{reward} when you spend {threshold}',\n 'popup.free_shipping_min': 'Free shipping from {threshold}',\n 'popup.free_shipping_always': 'Free shipping, no minimum purchase',\n 'upsell.title': 'Complete your purchase and unlock more',\n 'upsell.subtitle': 'Automatic discount',\n 'upsell.next_level': 'Next level',\n 'upsell.you_miss': '{remaining} to go',\n 'upsell.unlocks_reward': 'Unlock {reward} off',\n 'upsell.total_saved': 'Total saved',\n 'upsell.current_benefit': 'Current benefit',\n 'upsell.status': 'Status',\n 'upsell.status_pending': 'Pending',\n 'upsell.status_active': 'Active',\n 'upsell.next_reward': 'Next reward {reward} · {threshold}',\n 'upsell.suggestions': 'Add and unlock · Products you may like',\n 'upsell.add': 'Add and move up +',\n 'upsell.adding': 'Adding…',\n 'upsell.flavor': 'Flavor',\n 'upsell.unlocks_badge': 'Unlocks your {reward}',\n 'upsell.unlocked': 'You unlocked {reward}!',\n 'upsell.best': 'You have the best discount: {reward}',\n 'upsell.skip': 'Continue without adding',\n 'upsell.continue': 'Continue to payment',\n 'upsell.footer': 'Your best discount is applied automatically',\n 'upsell.sold_out': 'This flavor sold out, pick another one.',\n 'upsell.error': 'We could not add it. Please try again.',\n 'note.label': 'Add a note',\n 'note.placeholder': 'Instructions for your order',\n 'note.save': 'Save note',\n 'note.saving': 'Saving…',\n 'note.saved': 'Saved',\n 'note.error': 'The note could not be saved. Please try again.',\n 'note.counter': '{n} of {max} characters',\n}\n\nconst CATALOG: Record<PromotionLocale, PromotionMessages> = { es: ES, en: EN }\n\n/** Catalog for a locale with the shop's per-key overrides applied. */\nexport function promotionMessages(locale: string | null | undefined, overrides?: Partial<PromotionMessages> | null): PromotionMessages {\n const base = CATALOG[availabilityLocale(locale)]\n if (!overrides) return base\n const out = { ...base }\n for (const [k, v] of Object.entries(overrides)) if (typeof v === 'string' && k in base) out[k as PromotionMessageKey] = v\n return out\n}\n\n/** Order-note limit enforced by the server (`validateNote`). */\nexport const NOTE_MAX_LENGTH = 1000\n\n/** Trims and caps a note; empty becomes `null` (the server clears the note). */\nexport function normalizeNote(note: string | null | undefined): string | null {\n const t = (note ?? '').trim()\n return t ? t.slice(0, NOTE_MAX_LENGTH) : null\n}\n\n/** `5 %` / `7.5 %` (es) or `5%` (en) / `$250` / `Envío gratis`. The values are the server's. */\nexport function rewardLabel(reward: PromotionReward, locale?: string | null, overrides?: Partial<PromotionMessages> | null): string {\n const m = promotionMessages(locale, overrides)\n if (reward.kind === 'free_shipping') return m['reward.free_shipping']\n if (reward.kind === 'fixed') return formatMoney(reward.amount, locale ?? undefined, { withoutTrailingZeros: true })\n const n = Number.parseFloat(reward.percent)\n let num = reward.percent\n try {\n if (Number.isFinite(n)) num = new Intl.NumberFormat(locale ?? undefined, { maximumFractionDigits: 4 }).format(n)\n } catch {\n /* keep the raw text */\n }\n return availabilityLocale(locale) === 'en' ? `${num}%` : `${num} %`\n}\n\n/** Display clamp for a server percentage (`aria-valuenow`). Not a calculation. */\nexport function clampPercent(value: unknown): number {\n const n = typeof value === 'number' ? value : Number.parseFloat(String(value))\n if (!Number.isFinite(n)) return 0\n return Math.min(100, Math.max(0, Math.round(n)))\n}\n\nexport type DiscountBarState = 'next' | 'upgrade' | 'max' | 'suppressed'\n\nexport type DiscountBarView = {\n state: DiscountBarState\n /** Server progress 0-100. */\n percent: number\n text: string\n /** `aria-valuetext`. */\n valueText: string\n remaining: Money | null\n /** Reward of the next tier (or the applied one at max). */\n rewardText: string | null\n appliedText: string | null\n nextText: string | null\n tiers: { id: string; label: string; threshold: string; reached: boolean; position: number }[]\n}\n\nexport type ShippingBarState = 'progress' | 'reached' | 'always'\n\nexport type ShippingBarView = {\n state: ShippingBarState\n percent: number\n text: string\n valueText: string\n remaining: Money | null\n /** `false` for `always`: there is nothing to fill. */\n showBar: boolean\n}\n\nexport type PromoProgressView = { discount: DiscountBarView | null; shipping: ShippingBarView | null }\n\nconst fmt = (money: Money, locale?: string | null) => formatMoney(money, locale ?? undefined, { withoutTrailingZeros: true })\n\n/**\n * Bars of the cart and the pre-payment modal. Both read the same `Cart.promotions`,\n * so they can never disagree. `null`/absent promotions give `{ discount: null, shipping: null }`.\n */\nexport function promoProgressView(\n promotions: CartPromotions | null | undefined,\n locale?: string | null,\n overrides?: Partial<PromotionMessages> | null,\n): PromoProgressView {\n if (!promotions) return { discount: null, shipping: null }\n const m = promotionMessages(locale, overrides)\n const f = (tpl: string, vars: Record<string, string>) => formatAvailabilityMessage(tpl, vars)\n\n let discount: DiscountBarView | null = null\n const hasTiers = promotions.tiers.length > 0 || promotions.next_tier !== null || promotions.applied !== null\n if (hasTiers) {\n const next = promotions.next_tier\n const applied = promotions.applied\n const appliedReward = applied ? rewardLabel(applied.reward, locale, overrides) : null\n let state: DiscountBarState\n let text: string\n if (promotions.suppressed?.reason === 'code_better' && !applied) {\n state = 'suppressed'\n text = m['discount.suppressed']\n } else if (!next) {\n state = 'max'\n text = appliedReward ? f(m['discount.max'], { reward: appliedReward }) : m['discount.suppressed']\n } else if (applied) {\n state = 'upgrade'\n text = f(m['discount.next_upgrade'], { remaining: fmt(next.remaining, locale), reward: rewardLabel(next.reward, locale, overrides) })\n } else {\n state = 'next'\n text = f(m['discount.next'], { remaining: fmt(next.remaining, locale) })\n }\n discount = {\n state,\n percent: clampPercent(promotions.percent_of_max),\n text,\n valueText: text,\n remaining: next?.remaining ?? null,\n rewardText: next ? rewardLabel(next.reward, locale, overrides) : appliedReward,\n appliedText: appliedReward ? f(m['discount.applied'], { reward: appliedReward }) : null,\n nextText: next ? f(m['discount.unlocks'], { reward: rewardLabel(next.reward, locale, overrides) }) : null,\n tiers: promotions.tiers.map((t) => ({\n id: t.id,\n label: rewardLabel(t.reward, locale, overrides),\n threshold: fmt(t.threshold, locale),\n reached: t.reached,\n position: clampPercent(t.percent_of_max),\n })),\n }\n }\n\n let shipping: ShippingBarView | null = null\n const fs = promotions.free_shipping\n if (fs) {\n const noMinimum = Number.parseFloat(fs.threshold.amount) === 0\n if (noMinimum) {\n shipping = { state: 'always', percent: 100, text: m['shipping.always'], valueText: m['shipping.always'], remaining: null, showBar: false }\n } else if (fs.reached) {\n shipping = { state: 'reached', percent: 100, text: m['shipping.reached'], valueText: m['shipping.reached'], remaining: null, showBar: true }\n } else {\n const text = f(m['shipping.progress'], { remaining: fmt(fs.remaining, locale) })\n shipping = { state: 'progress', percent: clampPercent(fs.percent), text, valueText: text, remaining: fs.remaining, showBar: true }\n }\n }\n return { discount, shipping }\n}\n","/**\n * Detección de mercado por visita (país + idioma), pura y sin DOM: sirve en el servidor de cualquier tienda.\n *\n * Reglas (mejores prácticas de i18n para comercio):\n * - El mercado canónico lo fija el DOMINIO (OPS liga cada dominio verificado a un mercado: org_domains.market_code).\n * Esto no lo decide la geolocalización: así cada URL tiene un solo idioma/moneda (SEO, hreflang, caché de CDN).\n * - La geolocalización solo SUGIERE (banner \"¿Ver la tienda de Estados Unidos?\"); nunca redirige sola, nunca a rastreadores\n * y respeta la elección guardada del comprador.\n * - Precios, impuestos y envío NO dependen de la IP: dependen del mercado del dominio y de la dirección de entrega.\n * - El país sale de las cabeceras que pone el CDN/proxy (no se puede confiar en ellas si el servidor está expuesto\n * directo a internet: solo se leen con `trustProxy`).\n */\n\nexport type MarketInfo = {\n /** Código del mercado en OPS (\"mx\", \"us\"). */\n code: string\n /** ISO 3166-1 alfa-2 a los que vende. */\n countries: string[]\n /** BCP 47 por defecto (\"es-MX\", \"en-US\"). */\n locale: string\n /** ISO 4217 (\"MXN\", \"USD\"). */\n currency: string\n /** Dominio público del mercado, si es distinto del actual (\"godsnutrition.com\"). */\n host?: string\n}\n\n/** Cabeceras de país de los CDN/proxies más comunes, en orden de preferencia. */\nexport const COUNTRY_HEADERS = ['cf-ipcountry', 'cloudfront-viewer-country', 'x-vercel-ip-country', 'x-appengine-country', 'x-country-code'] as const\n\nconst BOT = /bot|crawl|spider|slurp|bing|facebookexternalhit|embedly|preview|lighthouse|headless|curl|wget/i\n\n/** País del visitante según el CDN. `null` si no viene, es desconocido (XX), Tor (T1) o no es ISO alfa-2. */\nexport function visitorCountry(headers: Headers, { trustProxy = true }: { trustProxy?: boolean } = {}): string | null {\n if (!trustProxy) return null\n for (const name of COUNTRY_HEADERS) {\n const value = headers.get(name)?.trim().toUpperCase()\n if (value && /^[A-Z]{2}$/.test(value) && value !== 'XX' && value !== 'T1') return value\n }\n return null\n}\n\n/** Idiomas de Accept-Language ordenados por q (mayor primero), en minúsculas. */\nexport function preferredLanguages(acceptLanguage: string | null | undefined): string[] {\n if (!acceptLanguage) return []\n return acceptLanguage\n .split(',')\n .map((part, index) => {\n const [tag = '', ...params] = part.trim().split(';')\n const q = Number(params.find((p) => p.trim().startsWith('q='))?.split('=')[1] ?? 1)\n return { tag: tag.trim().toLowerCase(), q: Number.isFinite(q) ? q : 0, index }\n })\n .filter((l) => l.tag && l.tag !== '*' && l.q > 0)\n .sort((a, b) => b.q - a.q || a.index - b.index)\n .map((l) => l.tag)\n}\n\n/** Mejor idioma entre los que ofrece la tienda: coincidencia exacta, luego por idioma base; si no, el de `fallback`. */\nexport function negotiateLocale(acceptLanguage: string | null | undefined, available: string[], fallback: string): string {\n const lowered = new Map(available.map((l) => [l.toLowerCase(), l]))\n for (const wanted of preferredLanguages(acceptLanguage)) {\n const exact = lowered.get(wanted)\n if (exact) return exact\n const base = wanted.split('-')[0]\n const sameBase = available.find((l) => l.toLowerCase().split('-')[0] === base)\n if (sameBase) return sameBase\n }\n return fallback\n}\n\nexport type MarketSuggestion = {\n market: MarketInfo\n /** Qué disparó la sugerencia. El país manda; el idioma solo si el CDN no dio país. */\n reason: 'country' | 'language'\n}\n\n/**\n * ¿Conviene sugerir otro mercado a esta visita? `null` si no (ya está en el correcto, rastreador, ya eligió, o no hay otro).\n * `chosen` es el código que el comprador guardó al elegir a mano (\"market\" en cookie): si existe, no se vuelve a sugerir.\n */\nexport function suggestMarket({\n headers,\n markets,\n current,\n chosen,\n trustProxy = true,\n}: {\n headers: Headers\n markets: MarketInfo[]\n current: string\n chosen?: string | null\n trustProxy?: boolean\n}): MarketSuggestion | null {\n if (chosen || markets.length < 2) return null\n if (BOT.test(headers.get('user-agent') ?? '')) return null\n\n const country = visitorCountry(headers, { trustProxy })\n if (country) {\n const target = markets.find((m) => m.countries.includes(country))\n return target && target.code !== current ? { market: target, reason: 'country' } : null\n }\n // Sin país del CDN: la región del idioma del navegador (\"en-US\" → US), solo como pista débil.\n for (const tag of preferredLanguages(headers.get('accept-language'))) {\n const region = tag.split('-')[1]?.toUpperCase()\n if (!region) continue\n const target = markets.find((m) => m.countries.includes(region))\n if (target) return target.code !== current ? { market: target, reason: 'language' } : null\n }\n return null\n}\n\n/**\n * Enlaces `hreflang` para <head>: un alterno por mercado con dominio propio, más x-default (el mercado por defecto).\n * `path` es la ruta con query actual (\"/productos/x\"). Es lo que permite a buscadores servir cada país en su idioma.\n */\nexport function hreflangLinks(markets: MarketInfo[], path: string, defaultMarket: string, protocol = 'https'): { hrefLang: string; href: string }[] {\n const links = markets\n .filter((m) => m.host)\n .map((m) => ({ hrefLang: m.locale, href: `${protocol}://${m.host}${path}` }))\n const fallback = markets.find((m) => m.code === defaultMarket && m.host)\n if (fallback) links.push({ hrefLang: 'x-default', href: `${protocol}://${fallback.host}${path}` })\n return links\n}\n","/** Invoices and credit notes of an order, and the bytes of a downloaded file. Pure; no URL of the PAC ever passes here. */\nimport type { InvoiceDoc, InvoiceFile } from './types.js'\n\nexport type InvoiceGroup = { invoice: InvoiceDoc; creditNotes: InvoiceDoc[] }\n\n/**\n * Groups credit notes under the invoice they correct (`related_to`), keeping the server's order. A credit note whose\n * invoice is not in the list (or has no `related_to`) is returned in `orphans`, never dropped.\n */\nexport function groupInvoiceDocs(docs: readonly InvoiceDoc[] | null | undefined): { groups: InvoiceGroup[]; orphans: InvoiceDoc[] } {\n const list = Array.isArray(docs) ? docs.filter((d): d is InvoiceDoc => !!d && typeof d === 'object') : []\n const groups: InvoiceGroup[] = list.filter((d) => d.kind !== 'credit_note').map((invoice) => ({ invoice, creditNotes: [] }))\n const orphans: InvoiceDoc[] = []\n for (const d of list) {\n if (d.kind !== 'credit_note') continue\n const group = d.related_to ? groups.find((g) => g.invoice.id === d.related_to) : undefined\n if (group) group.creditNotes.push(d)\n else orphans.push(d)\n }\n return { groups, orphans }\n}\n\n/** Decodes `content_base64` of a downloaded invoice file. Throws `TypeError` when it is not valid base64. */\nexport function invoiceFileBytes(file: Pick<InvoiceFile, 'content_base64'>): Uint8Array {\n const raw = typeof file.content_base64 === 'string' ? file.content_base64.replace(/\\s+/g, '') : ''\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(raw) || raw.length % 4 === 1) throw new TypeError('invoice file is not valid base64')\n const bin = atob(raw)\n const out = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\n/** A download filename that is safe in a `Content-Disposition` header: no path, quotes, control characters or spaces. */\nexport function safeInvoiceFilename(name: unknown, fallback = 'factura'): string {\n const base = typeof name === 'string' ? (name.split(/[\\\\/]/).pop() ?? '') : ''\n const clean = base.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^\\.+/, '').slice(0, 80)\n return clean || fallback\n}\n","import type { DeliveryInput, DeliveryMethod, DeliveryOptions, UnavailableRateProvider } from './types.js'\n\n/** Kind of a delivery radio: `ship` (address only, quote later), `rate` (a quoted rate) or `pickup` (a branch). */\nexport type DeliveryChoiceKind = 'ship' | 'rate' | 'pickup'\n\nexport type DeliveryChoice = {\n kind: DeliveryChoiceKind\n /** Everything after the first `:` — a rate id may contain more colons (`rate:skydropx:<id>`). */\n id: string\n method: DeliveryMethod\n /** `ship:` — only the address is saved; the rate is picked on the next pass. */\n addressOnly: boolean\n}\n\n/**\n * Parses the value of the single delivery radio group: `ship:`, `rate:<id>` or `pickup:<branch>`.\n * Splits on the FIRST colon only, so ids like `skydropx:<id>` survive intact (`split(':', 2)` would\n * silently drop everything after the second colon). Anything unknown is treated as `rate`.\n */\nexport function parseDelivery(value: string | null | undefined): DeliveryChoice {\n const raw = (value ?? '').trim()\n const i = raw.indexOf(':')\n const head = i === -1 ? raw : raw.slice(0, i)\n const id = i === -1 ? '' : raw.slice(i + 1)\n const kind: DeliveryChoiceKind = head === 'pickup' ? 'pickup' : head === 'ship' ? 'ship' : 'rate'\n return { kind, id, method: kind === 'pickup' ? 'pickup' : 'shipping', addressOnly: kind === 'ship' }\n}\n\n/** The `setDelivery` payload for a choice; `null` when it only saves the address (`ship:`). */\nexport function deliveryInput(choice: DeliveryChoice): DeliveryInput | null {\n if (choice.addressOnly) return null\n if (choice.kind === 'pickup') return { method: 'pickup', branch_id: choice.id }\n return { method: 'shipping', rate_id: choice.id || undefined }\n}\n\n/** Reason code a rate provider reports when the cart has items without weight. */\nexport const MISSING_WEIGHT = 'missing_weight'\n\nexport type DeliveryNotices = {\n /** Providers that could not quote because some item has no weight. */\n missingWeight: UnavailableRateProvider[]\n /** Providers that failed for any other reason (timeouts, errors). */\n unavailable: UnavailableRateProvider[]\n /** `true` when the shopper should be told something is off with the quote. */\n hasNotices: boolean\n}\n\n/** Splits `delivery.unavailable` into the `missing_weight` notice and the generic one. */\nexport function deliveryNotices(delivery: Pick<DeliveryOptions, 'unavailable' | 'partial'> | null | undefined): DeliveryNotices {\n const all = delivery?.unavailable ?? []\n const missingWeight = all.filter((u) => u.code === MISSING_WEIGHT)\n const unavailable = all.filter((u) => u.code !== MISSING_WEIGHT)\n return {\n missingWeight,\n unavailable,\n hasNotices: missingWeight.length > 0 || unavailable.length > 0 || delivery?.partial === true,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/money.ts","../src/query.ts","../src/client.ts","../src/payment-errors.ts","../src/diagnose.ts","../src/promotions.ts","../src/market.ts","../src/invoice-docs.ts","../src/delivery.ts"],"names":["fmt"],"mappings":"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","file":"index.js","sourcesContent":["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 CartRecommendations,\n PaymentAttemptResult,\n PaymentConfig,\n PaymentSubmitInput,\n PromotionsList,\n RecommendationPlacement,\n CheckoutInput,\n CheckoutResult,\n Collection,\n Connection,\n Customer,\n CustomerIdentifier,\n CustomerCapabilities,\n CustomerUpdateInput,\n CustomerPasswordLoginInput,\n CustomerRegisterInput,\n CustomerRegisterResult,\n CustomerResetPasswordInput,\n CustomerSession,\n CustomerSessionInput,\n CustomerSetPasswordInput,\n CustomerVerifyRegistrationInput,\n DeliveryInput,\n DeliveryOptions,\n PaymentMethods,\n FiscalProfile,\n FiscalProfileInput,\n InvoiceFile,\n InvoiceFileKind,\n InvoiceRequest,\n Location,\n LocationListParams,\n NearestLocation,\n InvoiceResult,\n Menu,\n Order,\n Page,\n PendingPayment,\n Product,\n ProductConnection,\n Region,\n RegionPostalCode,\n ReturnRequest,\n ReturnRequestInput,\n Shop,\n RestockSubscriptionInput,\n RestockSubscriptionResult,\n StockLevel,\n StorefrontErrorBody,\n Theme,\n TokenIntrospection,\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 /**\n * `pk_...` (browser) or `sk_...` (server only). Sent as `Authorization: Bearer <token>`. A function is called on\n * EVERY request, so a token read from a file (`createFileTokenSource` in `@asteby/storefront/node`) can rotate\n * without restarting the server.\n */\n token: string | (() => 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 /**\n * Public host of the storefront (`godsnutrition.com`), sent as `X-Storefront-Domain`. Platform (`pt_`)\n * tokens need it to pick the organization; with an org-scoped token it only scopes the market.\n */\n domain?: string\n /**\n * Market the request is for (`mx`, `us`), sent as `<domain>#<market>` in `X-Storefront-Domain`. It lets ONE\n * public domain serve several markets (the storefront routes by path prefix, e.g. `/us`): OPS honors it\n * when the organization has that market active and otherwise falls back to the domain's own market.\n * Ignored without `domain`.\n */\n market?: string\n /** Extra headers on every request. */\n headers?: Record<string, string>\n /**\n * IP address of the shopper, for SERVER-side calls (SSR, route actions) made with an\n * `sk_`/`pt_` token. Sent as `X-Storefront-Client-IP`, which the gateway honors only for\n * tokens issued with the `trust_client_ip` option: the rate limit is then charged per\n * shopper instead of to the store's single token bucket, and the OTP flow limits the\n * shopper's IP instead of the server's. Pass the IP from your own connection or trusted\n * proxy, never from a header the browser can forge. Never sent with a `pk_` token (the\n * gateway already separates those by caller IP). Invalid values are dropped.\n */\n clientIp?: string | null\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 /** Overrides the client-level shopper IP for this call (see `StorefrontClientOptions.clientIp`). */\n clientIp?: 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 * Never follow a redirect (`redirect: 'error'`, and a redirected answer is refused): for answers that carry the\n * buyer's documents, so neither the customer token nor the request ever travels to another host.\n */\n noRedirect?: boolean\n}\n\nconst OWN_OPTION_KEYS = new Set(['headers', 'timeoutMs', 'customerToken', 'clientIp', 'idempotencyKey', 'preview', 'signal'])\n\n/** Header the gateway reads (only for tokens with `trust_client_ip`). */\nexport const CLIENT_IP_HEADER = 'X-Storefront-Client-IP'\n\n/**\n * Returns the single IP literal in `raw`, or undefined. Takes the form a server hands over\n * (`::ffff:1.2.3.4`, `[2001:db8::1]`) and rejects lists, ports, zones and text so the\n * header is never a forgery vector.\n */\nexport function normalizeClientIp(raw: string | null | undefined): string | undefined {\n if (!raw) return undefined\n let v = raw.trim()\n if (v.startsWith('[') && v.endsWith(']')) v = v.slice(1, -1)\n if (!v || v.length > 45 || /[\\s,%/]/.test(v)) return undefined\n if (/^[0-9]{1,3}(\\.[0-9]{1,3}){3}$/.test(v)) {\n return v.split('.').every((o) => Number(o) <= 255) ? v : undefined\n }\n // IPv6 (incl. IPv4-mapped): hex groups and colons, at most one \"::\".\n if (!v.includes(':') || !/^[0-9a-fA-F:.]+$/.test(v) || v.split('::').length > 2) return undefined\n try {\n new URL(`http://[${v}]/`)\n } catch {\n return undefined\n }\n return v\n}\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 // `.` and `..` (also as `%2e`) are dot segments: the URL parser would resolve them and the request would land on\n // another route with the same credentials.\n if (typeof segment !== 'string' || /^(?:\\.|%2e){1,2}$/i.test(segment)) throw new TypeError(`Invalid path segment: ${String(segment)}`)\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\nfunction scopeList(raw: unknown): string[] {\n return Array.isArray(raw) ? raw.filter((s): s is string => typeof s === 'string' && s.length > 0) : []\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 // The gateway may put `code` / `required_scopes` at the top level or inside `error` (or its `details`).\n const top = body as { code?: unknown; required_scopes?: unknown } | undefined\n const code = e?.code ?? (typeof top?.code === 'string' ? top.code : undefined)\n const requiredScopes = code === 'insufficient_scope' ? scopeList(e?.required_scopes ?? top?.required_scopes ?? (e?.details as { required_scopes?: unknown } | undefined)?.required_scopes) : []\n return new StorefrontError({\n status: res.status,\n code: code ?? defaultCodeForStatus(res.status),\n ...(requiredScopes.length ? { requiredScopes } : {}),\n message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? ' ' + res.statusText : ''}`,\n ...(e?.field ? { field: e.field } : {}),\n ...(e?.details !== undefined ? { details: e.details } : {}),\n ...(typeof e?.retryable === 'boolean' ? { retryable: e.retryable } : {}),\n ...(typeof e?.retry_after === 'number' && e.retry_after > 0 ? { retryAfter: e.retry_after } : {}),\n ...(typeof e?.checkout_id === 'string' && e.checkout_id ? { checkoutId: e.checkout_id } : {}),\n ...(e?.cost !== undefined ? { cost: e.cost } : {}),\n ...(typeof e?.message_en === 'string' && e.message_en ? { messageEn: e.message_en } : {}),\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 currentToken = (): string => {\n const t = typeof config.token === 'function' ? config.token() : config.token\n if (!t) throw new StorefrontError({ status: 0, code: 'unauthorized', message: 'Storefront token is empty (token source returned nothing)' })\n return t\n }\n const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'\n const initialToken = typeof config.token === 'string' ? config.token : ''\n if (isBrowser && initialToken.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 const token = currentToken()\n headers.set('Authorization', `Bearer ${token}`)\n if (config.locale) headers.set('Accept-Language', config.locale)\n if (config.domain) headers.set('X-Storefront-Domain', storefrontDomainHeader(config.domain, config.market))\n const customerToken = options.customerToken !== undefined ? options.customerToken : config.customerToken\n if (customerToken) headers.set('X-Customer-Token', customerToken)\n const clientIp = options.clientIp !== undefined ? options.clientIp : config.clientIp\n // Server-side tokens only: a pk_ token already gets a per-caller bucket from the gateway.\n const ip = isTokenPublishable(token) ? undefined : normalizeClientIp(clientIp)\n if (ip) headers.set(CLIENT_IP_HEADER, ip)\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 ...(spec.noRedirect ? { redirect: 'error' as const } : {}),\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 (spec.noRedirect && res.redirected) {\n await res.text().catch(() => undefined)\n throw new StorefrontError({ status: 502, code: 'invalid_response', message: 'The answer was redirected; it is refused', url })\n }\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 token: {\n /**\n * What the token in use is and can do (`GET {baseUrl}/_token`, a gateway route, not a `/storefront` one).\n * Needs no scope, so it answers even when the token is under-provisioned: `missing_scopes` says what to repair.\n */\n introspect: async (options?: RequestOptions): Promise<TokenIntrospection> => {\n // OPS answers with the kernel envelope `{success, data}`; a flat object is accepted too.\n const body = await get<TokenIntrospection | { success?: boolean; data?: TokenIntrospection }>('/_token', undefined, options)\n const env = body as { success?: unknown; data?: TokenIntrospection }\n return typeof env?.success === 'boolean' && env.data ? env.data : (body as TokenIntrospection)\n },\n },\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 /** Returns a new client that reports the shopper's IP (`X-Storefront-Client-IP`) on every call. */\n withClientIp(clientIp: string | null | undefined) {\n return createStorefrontClient({ ...config, clientIp: clientIp ?? null })\n },\n\n shop: {\n get: (options?: RequestOptions) => get<Shop>('/storefront/shop', undefined, options),\n },\n\n /**\n * How the market formats, taxes, addresses and invoices (`fiscal_id` carries the tax-id pattern, the regimes,\n * the invoice uses and the identity documents the buyer can upload). Cacheable; `null` when the organization\n * has no region configured.\n */\n region: (options?: RequestOptions) => getOrNull<Region>('/storefront/region', undefined, options),\n\n /**\n * State and municipality of a postal code from the region pack (`null` when the code is not in its catalog, or the\n * organization has no region pack). The source of `AddressFields.lookupPostalCode`: the state it fills is the one\n * the server checks the address against.\n */\n postalCode: (zip: string, options?: RequestOptions) => getOrNull<RegionPostalCode>('/storefront/region/postal-code', { zip: zip.trim() }, options),\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 restock: {\n /**\n * \"Notify me when it is back\". Idempotent per contact + SKU; always answers `202 pending`.\n * Only offered when `availability.notify_available` is true. Needs `customer:write`.\n */\n subscribe: (input: RestockSubscriptionInput, options?: WriteOptions) =>\n write<RestockSubscriptionResult>('POST', '/storefront/restock-subscriptions', input, 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 /** Order note (up to 1000 characters). `null` or empty clears it. */\n setNote: (id: string, note: string | null, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/note'), { note }, options),\n /**\n * Asks for an invoice for this cart (`null` or `{ requested: false }` withdraws it). The server validates the\n * data against the region BEFORE any charge: `422` with `field: 'invoice.<field>'` (e.g. `invoice.tax_regime`)\n * names what to fix. `409 already_checked_out` when the cart is already an order. Checkout uses it when\n * `CheckoutInput.invoice` is omitted.\n */\n setInvoice: (id: string, invoice: InvoiceRequest | null, options?: WriteOptions) =>\n write<Cart>('PUT', cartPath(id, '/invoice'), invoice ?? { requested: false }, options),\n /**\n * Cross-sell suggestions: only sellable variants, with `unlocks` when adding one reaches the next\n * discount tier. `first` 1-8 (default 4). `private, no-store`; ask on demand, not on every render.\n */\n recommendations: (id: string, params: { first?: number; placement?: RecommendationPlacement } = {}, options?: RequestOptions) =>\n get<CartRecommendations>(cartPath(id, '/recommendations'), params as QueryParams, 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 promotions: {\n /** Public promotions and the entry pop-up announcement for the request's market (cacheable). */\n list: (options?: RequestOptions) => get<PromotionsList>('/storefront/promotions', undefined, options),\n },\n\n checkouts: {\n /** What to mount for an embedded checkout (public key, options, amount) and whether it can still be paid. Never cache. */\n paymentConfig: (id: string, options?: RequestOptions) =>\n getOrNull<PaymentConfig>(`/storefront/checkouts/${enc(id)}/payment-config`, undefined, options),\n /**\n * Pays a checkout in the page. The browser brings only what the provider SDK returned (`provider_data`);\n * the amount is the server's. `idempotencyKey` is REQUIRED (use `paymentIdempotencyKey(checkoutId, attempt)`):\n * repeating a call with the same key never charges twice. Needs a server token (`checkout:write`).\n */\n pay: (id: string, input: PaymentSubmitInput, options: WriteOptions & { idempotencyKey: string }) => {\n if (!options || typeof options.idempotencyKey !== 'string' || !options.idempotencyKey.trim()) {\n throw new TypeError('checkouts.pay: idempotencyKey is required')\n }\n return write<PaymentAttemptResult>('POST', `/storefront/checkouts/${enc(id)}/payment`, input, options)\n },\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 /** What the store supports (password login, email verification, OTP channels). Drives which forms to show. */\n capabilities: (options?: RequestOptions) =>\n get<CustomerCapabilities>('/storefront/customer/capabilities', undefined, options),\n /**\n * Creates an account with email + password. `verification_required` (202): a code was emailed, finish with\n * `verifyRegistration`. `created` (201): the account exists and `session` is ready. `409` when the email is taken.\n */\n register: async (input: CustomerRegisterInput, options?: WriteOptions): Promise<CustomerRegisterResult> => {\n const res = await write<{ status: 'verification_required' } | CustomerSession>('POST', '/storefront/customer/register', input, options)\n return res && 'token' in res ? { status: 'created', session: res } : { status: 'verification_required' }\n },\n /** Confirms the emailed registration code and returns the new buyer session. */\n verifyRegistration: (input: CustomerVerifyRegistrationInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/register/verify', input, options),\n /** Email + password login. `401` for wrong credentials. */\n loginWithPassword: (input: CustomerPasswordLoginInput, options?: WriteOptions) =>\n write<CustomerSession>('POST', '/storefront/customer/login', input, options),\n /** Sets or changes the password of the signed-in buyer (`options.customerToken`, or a `withCustomerToken` client). */\n setPassword: (input: CustomerSetPasswordInput, options?: WriteOptions) =>\n write<void>('PUT', '/storefront/customer/password', input, options),\n /** Resets a forgotten password with the code from `requestOtp({ email })`. */\n resetPassword: (input: CustomerResetPasswordInput, options?: WriteOptions) =>\n write<void>('POST', '/storefront/customer/password/reset', input, options),\n get: (options?: RequestOptions) => get<Customer>('/storefront/customer', undefined, options),\n /** Updates the profile and the saved fiscal data; `fiscal: null` deletes the latter. `422` with `field: 'fiscal.<field>'`. */\n update: (input: CustomerUpdateInput, options?: WriteOptions) =>\n write<Customer>('PATCH', '/storefront/customer', input, 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 /**\n * Checkouts waiting for their payment (cash voucher: OXXO, SPEI). They are not orders yet; once the payment\n * confirms they leave this list and show up in `orders`.\n */\n pendingPayments: async (params?: PaginationParams, options?: RequestOptions): Promise<Connection<PendingPayment>> =>\n // An OPS older than the route answers 404: it has no pending payments to list (a 401 still throws).\n (await getOrNull<Connection<PendingPayment>>('/storefront/customer/pending-payments', params as QueryParams, options)) ?? {\n nodes: [],\n page_info: { has_next_page: false, end_cursor: null },\n total_count: 0,\n },\n /**\n * Reads one file (`pdf` | `xml`) of an invoice or credit note of the buyer's order, through the authenticated\n * route (`order_invoice_file`): the answer is the file itself (base64), never a URL, so neither the buyer token\n * nor a link of the PAC reaches the browser. Call it from YOUR server and stream the bytes\n * (`invoiceFileBytes`). `null` when the order, the document or the file does not exist or is not the buyer's.\n */\n invoiceFile: async (orderId: string, invoiceId: string, kind: InvoiceFileKind, options?: RequestOptions): Promise<InvoiceFile | null> => {\n if (kind !== 'pdf' && kind !== 'xml') throw new TypeError(\"invoiceFile: kind must be 'pdf' or 'xml'\")\n const file = await request<InvoiceFile>({\n method: 'GET',\n path: `/storefront/customer/orders/${enc(orderId)}/invoices/${enc(invoiceId)}/${kind}`,\n options: { ...options, cache: 'no-store' },\n nullOn404: true,\n noRedirect: true,\n })\n if (file === null) return null\n if (!file || typeof file.content_base64 !== 'string' || typeof file.filename !== 'string' || typeof file.content_type !== 'string') {\n throw new StorefrontError({ status: 502, code: 'invalid_response', message: 'The invoice file answer is not a file' })\n }\n return { filename: file.filename, content_type: file.content_type, content_base64: file.content_base64 }\n },\n /**\n * Saved fiscal profiles of the buyer (contract 1.9, `capabilities().fiscal_profiles`). Personal data: private,\n * never cached, never logged. `422` with `field: 'fiscal.<field>'` when the region rejects a value; `409` for a\n * repeated tax id or past the limit; `404` for a profile that is not the buyer's.\n */\n fiscalProfiles: {\n list: async (options?: RequestOptions): Promise<FiscalProfile[]> =>\n (await get<{ nodes: FiscalProfile[] }>('/storefront/customer/fiscal-profiles', undefined, { ...options, cache: 'no-store' })).nodes,\n create: (profile: FiscalProfileInput, options?: WriteOptions) =>\n write<FiscalProfile>('POST', '/storefront/customer/fiscal-profiles', profile, options),\n update: (id: string, profile: FiscalProfileInput, options?: WriteOptions) =>\n write<FiscalProfile>('PATCH', `/storefront/customer/fiscal-profiles/${enc(id)}`, profile, options),\n /** Physical delete (a profile leaves nothing behind). A saved default passes to another profile. */\n delete: (id: string, options?: WriteOptions) =>\n write<void>('DELETE', `/storefront/customer/fiscal-profiles/${enc(id)}`, undefined, options),\n },\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\n/** `X-Storefront-Domain` value: the host, plus `#<market>` when a valid market code is given. */\nexport function storefrontDomainHeader(domain: string, market?: string | null): string {\n const host = domain.trim()\n const code = (market ?? '').trim().toLowerCase()\n return code && /^[a-z0-9_-]{1,32}$/.test(code) ? `${host}#${code}` : host\n}\n","/**\n * Classification of the failures of a card payment (`POST pay` / `GET status`). No texts, no DOM, no server APIs: the\n * shop's server uses it to answer with `kind` and `retryable`, and the browser transport uses it to decide whether to\n * repeat, ask for the status or give up.\n *\n * Rule that never changes: an INDETERMINATE result (`transient`, `in_progress`) is never charged again with another\n * idempotency key; it is repeated with the SAME key or its status is read.\n */\n\nexport type PaymentErrorClassKind =\n /** OPS or the provider did not answer (5xx, timeout, network). The charge may or may not have happened. */\n | 'transient'\n /** A payment is already in progress for this order (409): read the status, do not charge again. */\n | 'in_progress'\n /** Too many attempts (429). */\n | 'rate_limited'\n /** Credentials or configuration of the merchant with the provider: not the buyer's fault. */\n | 'merchant_config'\n /** The provider refused the charge at API level (`payment_provider_rejected`): definitive, nothing was charged. */\n | 'provider_declined'\n /** The cart already became an order and OPS will not open a new attempt (`422 invalid_state`). */\n | 'stale_checkout'\n | 'expired'\n | 'price_mismatch'\n | 'store_closed'\n | 'validation'\n | 'other'\n\nexport type PaymentErrorClass = { kind: PaymentErrorClassKind; retryable: boolean }\n\nexport type PaymentErrorLike = {\n status?: number | null\n code?: string | null\n field?: string | null\n /** `error.retryable` as OPS declared it (`StorefrontError.retryable`). */\n retryable?: boolean | null\n /** `error.checkout_id` (`StorefrontError.checkoutId`). */\n checkoutId?: string | null\n /** Raw `error.details`; a `retryable` inside is honoured too (older bodies). */\n details?: unknown\n}\n\n/** Did OPS expressly say the failure must NOT be repeated (`retryable: false`, on the error or inside `details`)? */\nexport function opsSaysNotRetryable(err: PaymentErrorLike): boolean {\n if (err.retryable === false) return true\n const d = err.details\n return typeof d === 'object' && d !== null && (d as { retryable?: unknown }).retryable === false\n}\n\n/** Field the shop's server sets when IT refuses a payment row that is not offered (so it is not read as a stale checkout). */\nexport const PAYMENT_CHOICE_REFUSED_FIELD = 'payment_choice'\n\nconst MERCHANT_CONFIG_CODE = /credential|not_configured|unconfigured|invalid_access|access_token|provider_config|merchant|invalid_public_key|unauthorized/i\n\n/**\n * What a payment failure means and whether repeating it can help. What OPS declares (`retryable`, stable codes) wins\n * over the HTTP status: a 502 with a stable code is an answer, not \"no response\".\n */\nexport function classifyPaymentError(err: PaymentErrorLike): PaymentErrorClass {\n const status = typeof err.status === 'number' ? err.status : 0\n const code = typeof err.code === 'string' ? err.code : ''\n if (code === 'store_not_ready') return { kind: 'store_closed', retryable: false }\n if (code === 'price_mismatch' || (status === 422 && err.field === 'expected_total')) return { kind: 'price_mismatch', retryable: false }\n if (status === 409 && (code === 'payment_in_progress' || err.field === 'payment_in_progress')) return { kind: 'in_progress', retryable: true }\n if (status === 409 && code === 'expired') return { kind: 'expired', retryable: false }\n if (status === 429 || code === 'too_many_attempts' || code === 'rate_limited') return { kind: 'rate_limited', retryable: true }\n if (status === 422 && code === 'invalid_state') {\n if (err.field === PAYMENT_CHOICE_REFUSED_FIELD) return { kind: 'other', retryable: false }\n return { kind: 'stale_checkout', retryable: false }\n }\n if (code === 'payment_provider_misconfigured') return { kind: 'merchant_config', retryable: false }\n if (code === 'payment_provider_rejected') return { kind: 'provider_declined', retryable: false }\n if (MERCHANT_CONFIG_CODE.test(code) || status === 401 || status === 403) return { kind: 'merchant_config', retryable: false }\n // OPS answered and said \"do not repeat\": definitive, not indeterminate (there is no lost answer to verify).\n if (status >= 500 && opsSaysNotRetryable(err)) return { kind: 'other', retryable: false }\n if (status === 0 || status >= 500 || code === 'network' || code === 'timeout' || code === 'unavailable') return { kind: 'transient', retryable: true }\n if (status === 400 || code === 'validation') return { kind: 'validation', retryable: false }\n return { kind: 'other', retryable: false }\n}\n","import type { StorefrontClient } from './client.js'\nimport { isStorefrontError } from './errors.js'\nimport type { TokenIntrospection } from './types.js'\n\n/** `sk_…a91f`: the prefix and the last four characters, never enough to use the token. */\nexport function maskToken(token: string | null | undefined): string {\n if (!token) return '(sin token)'\n const prefix = /^[a-z]{2}_/.exec(token)?.[0] ?? ''\n return token.length <= prefix.length + 8 ? `${prefix}…` : `${prefix}…${token.slice(-4)}`\n}\n\nexport type DiagnoseOptions = {\n /** Where the warning goes (default `console.warn`). Receives ONE line per problem. */\n log?: (message: string) => void\n /** Name of the connection, shown in the repair path. */\n connectionName?: string\n /** Give up after this long (default 3000 ms). */\n timeoutMs?: number\n}\n\n/** Where the operator repairs a connection in OPS (es-MX, as the screen names it). */\nexport function repairPath(connectionName?: string): string {\n return `OPS → Conexiones y API → ${connectionName ?? '<conexión>'} → Reparar permisos`\n}\n\n/**\n * Startup check of the store's credential: asks `token.introspect()` and, when scopes are missing, logs ONE clear\n * warning with the repair path (never the token, only `sk_…a91f`). It NEVER throws and is meant to be fired and\n * forgotten, so it cannot delay or break the boot:\n *\n * ```ts\n * void diagnose(storefront)\n * ```\n *\n * Resolves with the introspection, or `null` when it could not be obtained (older OPS, outage, bad token).\n */\nexport async function diagnose(client: StorefrontClient, options: DiagnoseOptions = {}): Promise<TokenIntrospection | null> {\n const log = options.log ?? ((m: string) => console.warn(m))\n const timeoutMs = options.timeoutMs ?? 3000\n const raw = client.config.token\n let mask: string\n try {\n mask = maskToken(typeof raw === 'function' ? raw() : raw)\n } catch {\n mask = maskToken(null)\n }\n try {\n const info = await client.token.introspect({ signal: AbortSignal.timeout(timeoutMs) })\n const missing = Array.isArray(info?.missing_scopes) ? info.missing_scopes : []\n if (missing.length > 0) {\n log(\n `[@asteby/storefront] La credencial ${mask} no tiene permisos que la tienda necesita: ${missing.join(', ')}. ` +\n `Repáralo en ${repairPath(options.connectionName)} (no hace falta cambiar la clave ni reiniciar).`,\n )\n }\n return info ?? null\n } catch (err) {\n if (isStorefrontError(err) && err.status === 401) {\n try {\n log(`[@asteby/storefront] OPS rechazó la credencial ${mask} (401): está revocada o vencida. Vuelve a conectar la tienda en OPS → Conexiones y API.`)\n } catch {\n /* a broken logger must not break boot */\n }\n }\n return null\n }\n}\n","/**\n * Promotion presentation: turns `Cart.promotions` (computed by OPS) into the\n * labels and bar states a storefront shows. Pure functions, no DOM.\n *\n * The shop never computes a discount here: `remaining`, `percent`, `reached`\n * and `percent_of_max` are the server's. The only arithmetic is clamping a\n * server percentage into 0-100 for `aria-valuenow`.\n */\nimport { availabilityLocale, formatAvailabilityMessage, type AvailabilityLocale } from './availability.js'\nimport { formatMoney } from './money.js'\nimport type { CartPromotions, Money, PromotionReward } from './types.js'\n\nexport type PromotionLocale = AvailabilityLocale\n\nexport type PromotionMessageKey =\n | 'discount.next'\n | 'discount.next_upgrade'\n | 'discount.applied'\n | 'discount.max'\n | 'discount.suppressed'\n | 'discount.unlocks'\n | 'discount.remaining'\n | 'shipping.progress'\n | 'shipping.reached'\n | 'shipping.always'\n | 'reward.free_shipping'\n | 'bar.discount'\n | 'bar.shipping'\n | 'popup.close'\n | 'popup.valid_until'\n | 'popup.limited_time'\n | 'popup.discount_tier'\n | 'popup.free_shipping_min'\n | 'popup.free_shipping_always'\n | 'upsell.title'\n | 'upsell.subtitle'\n | 'upsell.next_level'\n | 'upsell.you_miss'\n | 'upsell.unlocks_reward'\n | 'upsell.total_saved'\n | 'upsell.current_benefit'\n | 'upsell.status'\n | 'upsell.status_pending'\n | 'upsell.status_active'\n | 'upsell.next_reward'\n | 'upsell.suggestions'\n | 'upsell.add'\n | 'upsell.adding'\n | 'upsell.flavor'\n | 'upsell.unlocks_badge'\n | 'upsell.unlocked'\n | 'upsell.best'\n | 'upsell.skip'\n | 'upsell.continue'\n | 'upsell.footer'\n | 'upsell.sold_out'\n | 'upsell.error'\n | 'note.label'\n | 'note.placeholder'\n | 'note.save'\n | 'note.saving'\n | 'note.saved'\n | 'note.error'\n | 'note.counter'\n\nexport type PromotionMessages = Record<PromotionMessageKey, string>\n\nconst ES: PromotionMessages = {\n 'discount.next': 'Añade {remaining} para activar tu descuento automático',\n 'discount.next_upgrade': 'Añade {remaining} para subir a {reward}',\n 'discount.applied': '¡Tienes {reward} de descuento!',\n 'discount.max': '¡Tienes {reward} de descuento, el máximo!',\n 'discount.suppressed': 'Tu código de descuento ya te da un mejor precio.',\n 'discount.unlocks': 'Desbloqueas {reward} de descuento',\n 'discount.remaining': 'Te faltan {remaining}',\n 'shipping.progress': 'Añade {remaining} para envío gratis',\n 'shipping.reached': '¡Felicidades! Tienes envío gratis',\n 'shipping.always': 'Envío gratis en todo tu pedido',\n 'reward.free_shipping': 'Envío gratis',\n 'bar.discount': 'Progreso del descuento automático',\n 'bar.shipping': 'Progreso del envío gratis',\n 'popup.close': 'Cerrar',\n 'popup.valid_until': 'Válido hasta el {date}',\n 'popup.limited_time': 'Por tiempo limitado',\n 'popup.discount_tier': '{reward} comprando {threshold}',\n 'popup.free_shipping_min': 'Envío gratis desde {threshold}',\n 'popup.free_shipping_always': 'Envíos gratis sin mínimo de compra',\n 'upsell.title': 'Completa tu compra y desbloquea más',\n 'upsell.subtitle': 'Descuento automático',\n 'upsell.next_level': 'Siguiente nivel',\n 'upsell.you_miss': 'Te faltan {remaining}',\n 'upsell.unlocks_reward': 'Desbloqueas {reward} de descuento',\n 'upsell.total_saved': 'Total ahorrado',\n 'upsell.current_benefit': 'Beneficio actual',\n 'upsell.status': 'Estado',\n 'upsell.status_pending': 'Pendiente',\n 'upsell.status_active': 'Activo',\n 'upsell.next_reward': 'Siguiente recompensa {reward} · {threshold}',\n 'upsell.suggestions': 'Suma y desbloquea · Productos que pueden interesarte',\n 'upsell.add': 'Agregar y avanzar +',\n 'upsell.adding': 'Agregando…',\n 'upsell.flavor': 'Sabor',\n 'upsell.unlocks_badge': 'Desbloquea tu {reward}',\n 'upsell.unlocked': '¡Desbloqueaste {reward}!',\n 'upsell.best': 'Tienes el mejor descuento: {reward}',\n 'upsell.skip': 'Continuar sin agregar',\n 'upsell.continue': 'Continuar al pago',\n 'upsell.footer': 'Tu mejor descuento se aplica automáticamente',\n 'upsell.sold_out': 'Se agotó este sabor, elige otro.',\n 'upsell.error': 'No pudimos agregarlo. Intenta de nuevo.',\n 'note.label': 'Añadir nota',\n 'note.placeholder': 'Instrucciones para tu pedido',\n 'note.save': 'Guardar nota',\n 'note.saving': 'Guardando…',\n 'note.saved': 'Guardada',\n 'note.error': 'No se pudo guardar la nota. Intenta de nuevo.',\n 'note.counter': '{n} de {max} caracteres',\n}\n\nconst EN: PromotionMessages = {\n 'discount.next': 'Add {remaining} to unlock your automatic discount',\n 'discount.next_upgrade': 'Add {remaining} to move up to {reward}',\n 'discount.applied': 'You have {reward} off!',\n 'discount.max': 'You have {reward} off, the maximum!',\n 'discount.suppressed': 'Your discount code already gives you a better price.',\n 'discount.unlocks': 'Unlock {reward} off',\n 'discount.remaining': '{remaining} to go',\n 'shipping.progress': 'Add {remaining} for free shipping',\n 'shipping.reached': 'Congratulations! You get free shipping',\n 'shipping.always': 'Free shipping on your whole order',\n 'reward.free_shipping': 'Free shipping',\n 'bar.discount': 'Automatic discount progress',\n 'bar.shipping': 'Free shipping progress',\n 'popup.close': 'Close',\n 'popup.valid_until': 'Valid until {date}',\n 'popup.limited_time': 'Limited time',\n 'popup.discount_tier': '{reward} when you spend {threshold}',\n 'popup.free_shipping_min': 'Free shipping from {threshold}',\n 'popup.free_shipping_always': 'Free shipping, no minimum purchase',\n 'upsell.title': 'Complete your purchase and unlock more',\n 'upsell.subtitle': 'Automatic discount',\n 'upsell.next_level': 'Next level',\n 'upsell.you_miss': '{remaining} to go',\n 'upsell.unlocks_reward': 'Unlock {reward} off',\n 'upsell.total_saved': 'Total saved',\n 'upsell.current_benefit': 'Current benefit',\n 'upsell.status': 'Status',\n 'upsell.status_pending': 'Pending',\n 'upsell.status_active': 'Active',\n 'upsell.next_reward': 'Next reward {reward} · {threshold}',\n 'upsell.suggestions': 'Add and unlock · Products you may like',\n 'upsell.add': 'Add and move up +',\n 'upsell.adding': 'Adding…',\n 'upsell.flavor': 'Flavor',\n 'upsell.unlocks_badge': 'Unlocks your {reward}',\n 'upsell.unlocked': 'You unlocked {reward}!',\n 'upsell.best': 'You have the best discount: {reward}',\n 'upsell.skip': 'Continue without adding',\n 'upsell.continue': 'Continue to payment',\n 'upsell.footer': 'Your best discount is applied automatically',\n 'upsell.sold_out': 'This flavor sold out, pick another one.',\n 'upsell.error': 'We could not add it. Please try again.',\n 'note.label': 'Add a note',\n 'note.placeholder': 'Instructions for your order',\n 'note.save': 'Save note',\n 'note.saving': 'Saving…',\n 'note.saved': 'Saved',\n 'note.error': 'The note could not be saved. Please try again.',\n 'note.counter': '{n} of {max} characters',\n}\n\nconst CATALOG: Record<PromotionLocale, PromotionMessages> = { es: ES, en: EN }\n\n/** Catalog for a locale with the shop's per-key overrides applied. */\nexport function promotionMessages(locale: string | null | undefined, overrides?: Partial<PromotionMessages> | null): PromotionMessages {\n const base = CATALOG[availabilityLocale(locale)]\n if (!overrides) return base\n const out = { ...base }\n for (const [k, v] of Object.entries(overrides)) if (typeof v === 'string' && k in base) out[k as PromotionMessageKey] = v\n return out\n}\n\n/** Order-note limit enforced by the server (`validateNote`). */\nexport const NOTE_MAX_LENGTH = 1000\n\n/** Trims and caps a note; empty becomes `null` (the server clears the note). */\nexport function normalizeNote(note: string | null | undefined): string | null {\n const t = (note ?? '').trim()\n return t ? t.slice(0, NOTE_MAX_LENGTH) : null\n}\n\n/** `5 %` / `7.5 %` (es) or `5%` (en) / `$250` / `Envío gratis`. The values are the server's. */\nexport function rewardLabel(reward: PromotionReward, locale?: string | null, overrides?: Partial<PromotionMessages> | null): string {\n const m = promotionMessages(locale, overrides)\n if (reward.kind === 'free_shipping') return m['reward.free_shipping']\n if (reward.kind === 'fixed') return formatMoney(reward.amount, locale ?? undefined, { withoutTrailingZeros: true })\n const n = Number.parseFloat(reward.percent)\n let num = reward.percent\n try {\n if (Number.isFinite(n)) num = new Intl.NumberFormat(locale ?? undefined, { maximumFractionDigits: 4 }).format(n)\n } catch {\n /* keep the raw text */\n }\n return availabilityLocale(locale) === 'en' ? `${num}%` : `${num} %`\n}\n\n/** Display clamp for a server percentage (`aria-valuenow`). Not a calculation. */\nexport function clampPercent(value: unknown): number {\n const n = typeof value === 'number' ? value : Number.parseFloat(String(value))\n if (!Number.isFinite(n)) return 0\n return Math.min(100, Math.max(0, Math.round(n)))\n}\n\nexport type DiscountBarState = 'next' | 'upgrade' | 'max' | 'suppressed'\n\nexport type DiscountBarView = {\n state: DiscountBarState\n /** Server progress 0-100. */\n percent: number\n text: string\n /** `aria-valuetext`. */\n valueText: string\n remaining: Money | null\n /** Reward of the next tier (or the applied one at max). */\n rewardText: string | null\n appliedText: string | null\n nextText: string | null\n tiers: { id: string; label: string; threshold: string; reached: boolean; position: number }[]\n}\n\nexport type ShippingBarState = 'progress' | 'reached' | 'always'\n\nexport type ShippingBarView = {\n state: ShippingBarState\n percent: number\n text: string\n valueText: string\n remaining: Money | null\n /** `false` for `always`: there is nothing to fill. */\n showBar: boolean\n}\n\nexport type PromoProgressView = { discount: DiscountBarView | null; shipping: ShippingBarView | null }\n\nconst fmt = (money: Money, locale?: string | null) => formatMoney(money, locale ?? undefined, { withoutTrailingZeros: true })\n\n/**\n * Bars of the cart and the pre-payment modal. Both read the same `Cart.promotions`,\n * so they can never disagree. `null`/absent promotions give `{ discount: null, shipping: null }`.\n */\nexport function promoProgressView(\n promotions: CartPromotions | null | undefined,\n locale?: string | null,\n overrides?: Partial<PromotionMessages> | null,\n): PromoProgressView {\n if (!promotions) return { discount: null, shipping: null }\n const m = promotionMessages(locale, overrides)\n const f = (tpl: string, vars: Record<string, string>) => formatAvailabilityMessage(tpl, vars)\n\n let discount: DiscountBarView | null = null\n const hasTiers = promotions.tiers.length > 0 || promotions.next_tier !== null || promotions.applied !== null\n if (hasTiers) {\n const next = promotions.next_tier\n const applied = promotions.applied\n const appliedReward = applied ? rewardLabel(applied.reward, locale, overrides) : null\n let state: DiscountBarState\n let text: string\n if (promotions.suppressed?.reason === 'code_better' && !applied) {\n state = 'suppressed'\n text = m['discount.suppressed']\n } else if (!next) {\n state = 'max'\n text = appliedReward ? f(m['discount.max'], { reward: appliedReward }) : m['discount.suppressed']\n } else if (applied) {\n state = 'upgrade'\n text = f(m['discount.next_upgrade'], { remaining: fmt(next.remaining, locale), reward: rewardLabel(next.reward, locale, overrides) })\n } else {\n state = 'next'\n text = f(m['discount.next'], { remaining: fmt(next.remaining, locale) })\n }\n discount = {\n state,\n percent: clampPercent(promotions.percent_of_max),\n text,\n valueText: text,\n remaining: next?.remaining ?? null,\n rewardText: next ? rewardLabel(next.reward, locale, overrides) : appliedReward,\n appliedText: appliedReward ? f(m['discount.applied'], { reward: appliedReward }) : null,\n nextText: next ? f(m['discount.unlocks'], { reward: rewardLabel(next.reward, locale, overrides) }) : null,\n tiers: promotions.tiers.map((t) => ({\n id: t.id,\n label: rewardLabel(t.reward, locale, overrides),\n threshold: fmt(t.threshold, locale),\n reached: t.reached,\n position: clampPercent(t.percent_of_max),\n })),\n }\n }\n\n let shipping: ShippingBarView | null = null\n const fs = promotions.free_shipping\n if (fs) {\n const noMinimum = Number.parseFloat(fs.threshold.amount) === 0\n if (noMinimum) {\n shipping = { state: 'always', percent: 100, text: m['shipping.always'], valueText: m['shipping.always'], remaining: null, showBar: false }\n } else if (fs.reached) {\n shipping = { state: 'reached', percent: 100, text: m['shipping.reached'], valueText: m['shipping.reached'], remaining: null, showBar: true }\n } else {\n const text = f(m['shipping.progress'], { remaining: fmt(fs.remaining, locale) })\n shipping = { state: 'progress', percent: clampPercent(fs.percent), text, valueText: text, remaining: fs.remaining, showBar: true }\n }\n }\n return { discount, shipping }\n}\n","/**\n * Detección de mercado por visita (país + idioma), pura y sin DOM: sirve en el servidor de cualquier tienda.\n *\n * Reglas (mejores prácticas de i18n para comercio):\n * - El mercado canónico lo fija el DOMINIO (OPS liga cada dominio verificado a un mercado: org_domains.market_code).\n * Esto no lo decide la geolocalización: así cada URL tiene un solo idioma/moneda (SEO, hreflang, caché de CDN).\n * - La geolocalización solo SUGIERE (banner \"¿Ver la tienda de Estados Unidos?\"); nunca redirige sola, nunca a rastreadores\n * y respeta la elección guardada del comprador.\n * - Precios, impuestos y envío NO dependen de la IP: dependen del mercado del dominio y de la dirección de entrega.\n * - El país sale de las cabeceras que pone el CDN/proxy (no se puede confiar en ellas si el servidor está expuesto\n * directo a internet: solo se leen con `trustProxy`).\n */\n\nexport type MarketInfo = {\n /** Código del mercado en OPS (\"mx\", \"us\"). */\n code: string\n /** ISO 3166-1 alfa-2 a los que vende. */\n countries: string[]\n /** BCP 47 por defecto (\"es-MX\", \"en-US\"). */\n locale: string\n /** ISO 4217 (\"MXN\", \"USD\"). */\n currency: string\n /** Dominio público del mercado, si es distinto del actual (\"godsnutrition.com\"). */\n host?: string\n}\n\n/** Cabeceras de país de los CDN/proxies más comunes, en orden de preferencia. */\nexport const COUNTRY_HEADERS = ['cf-ipcountry', 'cloudfront-viewer-country', 'x-vercel-ip-country', 'x-appengine-country', 'x-country-code'] as const\n\nconst BOT = /bot|crawl|spider|slurp|bing|facebookexternalhit|embedly|preview|lighthouse|headless|curl|wget/i\n\n/** País del visitante según el CDN. `null` si no viene, es desconocido (XX), Tor (T1) o no es ISO alfa-2. */\nexport function visitorCountry(headers: Headers, { trustProxy = true }: { trustProxy?: boolean } = {}): string | null {\n if (!trustProxy) return null\n for (const name of COUNTRY_HEADERS) {\n const value = headers.get(name)?.trim().toUpperCase()\n if (value && /^[A-Z]{2}$/.test(value) && value !== 'XX' && value !== 'T1') return value\n }\n return null\n}\n\n/** Idiomas de Accept-Language ordenados por q (mayor primero), en minúsculas. */\nexport function preferredLanguages(acceptLanguage: string | null | undefined): string[] {\n if (!acceptLanguage) return []\n return acceptLanguage\n .split(',')\n .map((part, index) => {\n const [tag = '', ...params] = part.trim().split(';')\n const q = Number(params.find((p) => p.trim().startsWith('q='))?.split('=')[1] ?? 1)\n return { tag: tag.trim().toLowerCase(), q: Number.isFinite(q) ? q : 0, index }\n })\n .filter((l) => l.tag && l.tag !== '*' && l.q > 0)\n .sort((a, b) => b.q - a.q || a.index - b.index)\n .map((l) => l.tag)\n}\n\n/** Mejor idioma entre los que ofrece la tienda: coincidencia exacta, luego por idioma base; si no, el de `fallback`. */\nexport function negotiateLocale(acceptLanguage: string | null | undefined, available: string[], fallback: string): string {\n const lowered = new Map(available.map((l) => [l.toLowerCase(), l]))\n for (const wanted of preferredLanguages(acceptLanguage)) {\n const exact = lowered.get(wanted)\n if (exact) return exact\n const base = wanted.split('-')[0]\n const sameBase = available.find((l) => l.toLowerCase().split('-')[0] === base)\n if (sameBase) return sameBase\n }\n return fallback\n}\n\nexport type MarketSuggestion = {\n market: MarketInfo\n /** Qué disparó la sugerencia. El país manda; el idioma solo si el CDN no dio país. */\n reason: 'country' | 'language'\n}\n\n/**\n * ¿Conviene sugerir otro mercado a esta visita? `null` si no (ya está en el correcto, rastreador, ya eligió, o no hay otro).\n * `chosen` es el código que el comprador guardó al elegir a mano (\"market\" en cookie): si existe, no se vuelve a sugerir.\n */\nexport function suggestMarket({\n headers,\n markets,\n current,\n chosen,\n trustProxy = true,\n}: {\n headers: Headers\n markets: MarketInfo[]\n current: string\n chosen?: string | null\n trustProxy?: boolean\n}): MarketSuggestion | null {\n if (chosen || markets.length < 2) return null\n if (BOT.test(headers.get('user-agent') ?? '')) return null\n\n const country = visitorCountry(headers, { trustProxy })\n if (country) {\n const target = markets.find((m) => m.countries.includes(country))\n return target && target.code !== current ? { market: target, reason: 'country' } : null\n }\n // Sin país del CDN: la región del idioma del navegador (\"en-US\" → US), solo como pista débil.\n for (const tag of preferredLanguages(headers.get('accept-language'))) {\n const region = tag.split('-')[1]?.toUpperCase()\n if (!region) continue\n const target = markets.find((m) => m.countries.includes(region))\n if (target) return target.code !== current ? { market: target, reason: 'language' } : null\n }\n return null\n}\n\n/**\n * Enlaces `hreflang` para <head>: un alterno por mercado con dominio propio, más x-default (el mercado por defecto).\n * `path` es la ruta con query actual (\"/productos/x\"). Es lo que permite a buscadores servir cada país en su idioma.\n */\nexport function hreflangLinks(markets: MarketInfo[], path: string, defaultMarket: string, protocol = 'https'): { hrefLang: string; href: string }[] {\n const links = markets\n .filter((m) => m.host)\n .map((m) => ({ hrefLang: m.locale, href: `${protocol}://${m.host}${path}` }))\n const fallback = markets.find((m) => m.code === defaultMarket && m.host)\n if (fallback) links.push({ hrefLang: 'x-default', href: `${protocol}://${fallback.host}${path}` })\n return links\n}\n","/** Invoices and credit notes of an order, and the bytes of a downloaded file. Pure; no URL of the PAC ever passes here. */\nimport type { InvoiceDoc, InvoiceFile } from './types.js'\n\nexport type InvoiceGroup = { invoice: InvoiceDoc; creditNotes: InvoiceDoc[] }\n\n/**\n * Groups credit notes under the invoice they correct (`related_to`), keeping the server's order. A credit note whose\n * invoice is not in the list (or has no `related_to`) is returned in `orphans`, never dropped.\n */\nexport function groupInvoiceDocs(docs: readonly InvoiceDoc[] | null | undefined): { groups: InvoiceGroup[]; orphans: InvoiceDoc[] } {\n const list = Array.isArray(docs) ? docs.filter((d): d is InvoiceDoc => !!d && typeof d === 'object') : []\n const groups: InvoiceGroup[] = list.filter((d) => d.kind !== 'credit_note').map((invoice) => ({ invoice, creditNotes: [] }))\n const orphans: InvoiceDoc[] = []\n for (const d of list) {\n if (d.kind !== 'credit_note') continue\n const group = d.related_to ? groups.find((g) => g.invoice.id === d.related_to) : undefined\n if (group) group.creditNotes.push(d)\n else orphans.push(d)\n }\n return { groups, orphans }\n}\n\n/** Decodes `content_base64` of a downloaded invoice file. Throws `TypeError` when it is not valid base64. */\nexport function invoiceFileBytes(file: Pick<InvoiceFile, 'content_base64'>): Uint8Array {\n const raw = typeof file.content_base64 === 'string' ? file.content_base64.replace(/\\s+/g, '') : ''\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(raw) || raw.length % 4 === 1) throw new TypeError('invoice file is not valid base64')\n const bin = atob(raw)\n const out = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\n/** A download filename that is safe in a `Content-Disposition` header: no path, quotes, control characters or spaces. */\nexport function safeInvoiceFilename(name: unknown, fallback = 'factura'): string {\n const base = typeof name === 'string' ? (name.split(/[\\\\/]/).pop() ?? '') : ''\n const clean = base.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^\\.+/, '').slice(0, 80)\n return clean || fallback\n}\n","import type { DeliveryInput, DeliveryMethod, DeliveryOptions, UnavailableRateProvider } from './types.js'\n\n/** Kind of a delivery radio: `ship` (address only, quote later), `rate` (a quoted rate) or `pickup` (a branch). */\nexport type DeliveryChoiceKind = 'ship' | 'rate' | 'pickup'\n\nexport type DeliveryChoice = {\n kind: DeliveryChoiceKind\n /** Everything after the first `:` — a rate id may contain more colons (`rate:skydropx:<id>`). */\n id: string\n method: DeliveryMethod\n /** `ship:` — only the address is saved; the rate is picked on the next pass. */\n addressOnly: boolean\n}\n\n/**\n * Parses the value of the single delivery radio group: `ship:`, `rate:<id>` or `pickup:<branch>`.\n * Splits on the FIRST colon only, so ids like `skydropx:<id>` survive intact (`split(':', 2)` would\n * silently drop everything after the second colon). Anything unknown is treated as `rate`.\n */\nexport function parseDelivery(value: string | null | undefined): DeliveryChoice {\n const raw = (value ?? '').trim()\n const i = raw.indexOf(':')\n const head = i === -1 ? raw : raw.slice(0, i)\n const id = i === -1 ? '' : raw.slice(i + 1)\n const kind: DeliveryChoiceKind = head === 'pickup' ? 'pickup' : head === 'ship' ? 'ship' : 'rate'\n return { kind, id, method: kind === 'pickup' ? 'pickup' : 'shipping', addressOnly: kind === 'ship' }\n}\n\n/** The `setDelivery` payload for a choice; `null` when it only saves the address (`ship:`). */\nexport function deliveryInput(choice: DeliveryChoice): DeliveryInput | null {\n if (choice.addressOnly) return null\n if (choice.kind === 'pickup') return { method: 'pickup', branch_id: choice.id }\n return { method: 'shipping', rate_id: choice.id || undefined }\n}\n\n/** Reason code a rate provider reports when the cart has items without weight. */\nexport const MISSING_WEIGHT = 'missing_weight'\n\nexport type DeliveryNotices = {\n /** Providers that could not quote because some item has no weight. */\n missingWeight: UnavailableRateProvider[]\n /** Providers that failed for any other reason (timeouts, errors). */\n unavailable: UnavailableRateProvider[]\n /** `true` when the shopper should be told something is off with the quote. */\n hasNotices: boolean\n}\n\n/** Splits `delivery.unavailable` into the `missing_weight` notice and the generic one. */\nexport function deliveryNotices(delivery: Pick<DeliveryOptions, 'unavailable' | 'partial'> | null | undefined): DeliveryNotices {\n const all = delivery?.unavailable ?? []\n const missingWeight = all.filter((u) => u.code === MISSING_WEIGHT)\n const unavailable = all.filter((u) => u.code !== MISSING_WEIGHT)\n return {\n missingWeight,\n unavailable,\n hasNotices: missingWeight.length > 0 || unavailable.length > 0 || delivery?.partial === true,\n }\n}\n"]}
|