@kotao/storefront 0.2.4 → 0.2.6

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.
Files changed (69) hide show
  1. package/README.md +50 -2
  2. package/dist/bridge-ZKbKqgFd.d.ts +239 -0
  3. package/dist/cart-documents-BLavRDiu.d.ts +89 -0
  4. package/dist/cart-documents.d.ts +1 -2
  5. package/dist/cart-documents.js +1 -1
  6. package/dist/{chunk-M7BPQ54D.js → chunk-2MRB6SMP.js} +4 -3
  7. package/dist/chunk-2MRB6SMP.js.map +1 -0
  8. package/dist/chunk-CKGI3Y7L.js +19 -0
  9. package/dist/chunk-CKGI3Y7L.js.map +1 -0
  10. package/dist/{chunk-4TEFGD42.js → chunk-EG34HLSX.js} +209 -162
  11. package/dist/chunk-EG34HLSX.js.map +1 -0
  12. package/dist/chunk-O6YZEY7X.js +1382 -0
  13. package/dist/chunk-O6YZEY7X.js.map +1 -0
  14. package/dist/{chunk-7MTCGXIG.js → chunk-R4N565GX.js} +8 -4
  15. package/dist/chunk-R4N565GX.js.map +1 -0
  16. package/dist/{chunk-XMTWFJCZ.js → chunk-RFM27BKZ.js} +31 -7
  17. package/dist/chunk-RFM27BKZ.js.map +1 -0
  18. package/dist/{chunk-MYDKIJRH.js → chunk-SVMYFYIA.js} +2 -2
  19. package/dist/{chunk-MYDKIJRH.js.map → chunk-SVMYFYIA.js.map} +1 -1
  20. package/dist/{chunk-H3D7BAOL.js → chunk-VOTBNOWH.js} +21 -3
  21. package/dist/chunk-VOTBNOWH.js.map +1 -0
  22. package/dist/{chunk-PXVDVUFX.js → chunk-W74FGUZH.js} +10 -3
  23. package/dist/chunk-W74FGUZH.js.map +1 -0
  24. package/dist/{chunk-2IWNUDSZ.js → chunk-WNXI3MPM.js} +2 -2
  25. package/dist/chunk-WNXI3MPM.js.map +1 -0
  26. package/dist/chunk-XXNCFWXT.js +2118 -0
  27. package/dist/chunk-XXNCFWXT.js.map +1 -0
  28. package/dist/{client-bsiNPHBi.d.ts → client-CwOPPpFF.d.ts} +11 -1
  29. package/dist/{createCartHandler-C4RrPwSG.d.ts → createCartHandler-7DdKB-GF.d.ts} +1 -1
  30. package/dist/custom-css-Bl7Ur3-H.d.ts +6 -0
  31. package/dist/editor.d.ts +57 -104
  32. package/dist/editor.js +270 -1
  33. package/dist/editor.js.map +1 -1
  34. package/dist/events-react.d.ts +1 -1
  35. package/dist/events-react.js +1 -1
  36. package/dist/events.d.ts +3 -3
  37. package/dist/events.js +1 -1
  38. package/dist/{fetch-M3Y-fQrW.d.ts → fetch-Bq_cc8_G.d.ts} +5 -0
  39. package/dist/hydrogen-Bu7k0kE4.d.ts +259 -0
  40. package/dist/index.d.ts +74 -51
  41. package/dist/index.js +19 -15
  42. package/dist/index.js.map +1 -1
  43. package/dist/react-router.d.ts +30 -9
  44. package/dist/react-router.js +16 -7
  45. package/dist/react-router.js.map +1 -1
  46. package/dist/react.d.ts +79 -11
  47. package/dist/react.js +279 -10
  48. package/dist/react.js.map +1 -1
  49. package/dist/{routing-sEonP93J.d.ts → routing-Bz3Cg0BW.d.ts} +36 -6
  50. package/dist/seo.d.ts +7 -4
  51. package/dist/seo.js +2 -2
  52. package/dist/settings.d.ts +14 -4
  53. package/dist/settings.js +2 -2
  54. package/dist/{shop-BJSvtmnV.d.ts → shop-CnrnSAJw.d.ts} +33 -6
  55. package/dist/{store-CtCWHI8H.d.ts → store-DO08fzJi.d.ts} +1 -1
  56. package/dist/storefront-api-types.d.ts +12 -0
  57. package/dist/{types-BDhHWZsP.d.ts → types-BkY0yET-.d.ts} +3 -3
  58. package/dist/{types-bcbQzx87.d.ts → types-DZX8ScsJ.d.ts} +2 -0
  59. package/package.json +4 -4
  60. package/dist/cart-documents-CwwRTvm8.d.ts +0 -21
  61. package/dist/chunk-2IWNUDSZ.js.map +0 -1
  62. package/dist/chunk-4TEFGD42.js.map +0 -1
  63. package/dist/chunk-7MTCGXIG.js.map +0 -1
  64. package/dist/chunk-H3D7BAOL.js.map +0 -1
  65. package/dist/chunk-M7BPQ54D.js.map +0 -1
  66. package/dist/chunk-PXVDVUFX.js.map +0 -1
  67. package/dist/chunk-PXZ737N3.js +0 -439
  68. package/dist/chunk-PXZ737N3.js.map +0 -1
  69. package/dist/chunk-XMTWFJCZ.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cart/useOptimisticCart.ts","../src/content-security-policy.ts","../src/localization/handler.ts","../src/analytics/events.ts","../src/analytics/shop.ts","../src/analytics/consent-encoding.ts","../src/hosted-surface/branding.ts","../src/hosted-surface/localization.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { CART_FORM_ACTIONS } from './actions'\nimport type { CartDispatchAction } from './createCartHandler'\nimport type { Cart, CartLine } from './types'\n\nconst recalculate = (cart: Cart, lines: readonly CartLine[]): Cart => ({\n ...cart,\n lines,\n totalQuantity: lines.reduce((sum, line) => sum + line.quantity, 0),\n})\n\nexport function applyOptimisticCartAction(cart: Cart, action: CartDispatchAction): Cart {\n switch (action.action) {\n case CART_FORM_ACTIONS.LinesAdd: {\n const inputLines = (action.inputs.lines ?? []) as Array<{\n merchandiseId: string\n quantity?: number | null\n }>\n const additions = inputLines.map<CartLine>((line) => ({\n id: `optimistic:${line.merchandiseId}`,\n quantity: line.quantity ?? 1,\n merchandise: { id: line.merchandiseId },\n attributes: [],\n }))\n return recalculate(cart, [...cart.lines, ...additions])\n }\n case CART_FORM_ACTIONS.LinesUpdate: {\n const updates = new Map(\n ((action.inputs.lines ?? []) as Array<{ id: string; quantity?: number | null }>).map(\n (line) => [line.id, line],\n ),\n )\n const lines = cart.lines\n .map((line) => {\n const update = updates.get(line.id)\n if (!update) return line\n if (update.quantity === 0) return null\n return {\n ...line,\n quantity: update.quantity ?? line.quantity,\n }\n })\n .filter((line): line is CartLine => line !== null)\n return recalculate(cart, lines)\n }\n case CART_FORM_ACTIONS.LinesRemove: {\n const remove = new Set((action.inputs.lineIds ?? []) as string[])\n return recalculate(\n cart,\n cart.lines.filter((line) => !remove.has(line.id)),\n )\n }\n default:\n return cart\n }\n}\n\n/**\n * Pure optimistic helper for React integrations. A React wrapper can call this from `useOptimistic`;\n * keeping the reducer pure lets non-React tests exercise the exact overlay behavior.\n */\nexport function useOptimisticCart(cart: Cart, action: CartDispatchAction | null): Cart {\n return action ? applyOptimisticCartAction(cart, action) : cart\n}\n","import { createNonceProvider, type BoundNonceProvider } from './react/nonce'\n\nexport interface ContentSecurityPolicyShop {\n readonly checkoutDomain?: string\n readonly storeDomain?: string\n}\n\nexport interface CreateContentSecurityPolicyOptions {\n readonly shop?: ContentSecurityPolicyShop\n readonly scriptSrc?: readonly string[]\n readonly connectSrc?: readonly string[]\n readonly imgSrc?: readonly string[]\n readonly styleSrc?: readonly string[]\n}\n\nexport interface ContentSecurityPolicyResult {\n readonly nonce: string\n readonly header: string\n readonly NonceProvider: BoundNonceProvider\n}\n\nconst QUOTED_TOKENS = new Set([\n 'self',\n 'none',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n 'strict-dynamic',\n 'wasm-unsafe-eval',\n])\n\nexport function createContentSecurityPolicy(\n options: CreateContentSecurityPolicyOptions = {},\n): ContentSecurityPolicyResult {\n const nonce = createNonce()\n const shopDomains = shopSources(options.shop)\n const scriptSrc = uniqueSources([\n ...normalizeSources(options.scriptSrc ?? ['self']),\n `'nonce-${nonce}'`,\n ])\n const connectSrc = uniqueSources([\n 'self',\n ...shopDomains,\n ...normalizeSources(options.connectSrc),\n ])\n const imgSrc = uniqueSources([\n 'self',\n 'data:',\n 'https:',\n ...shopDomains,\n ...normalizeSources(options.imgSrc),\n ])\n const styleSrc = uniqueSources(['self', 'unsafe-inline', ...normalizeSources(options.styleSrc)])\n const directives = [\n ['base-uri', [\"'self'\"]],\n ['default-src', [\"'self'\"]],\n ['connect-src', connectSrc],\n ['img-src', imgSrc],\n ['script-src', scriptSrc],\n ['style-src', styleSrc],\n ]\n return {\n nonce,\n header: directives\n .map(([name, values]) => `${name} ${(values as readonly string[]).join(' ')}`)\n .join('; '),\n NonceProvider: createNonceProvider(nonce),\n }\n}\n\nfunction createNonce(): string {\n const bytes = new Uint8Array(18)\n const runtimeCrypto = (globalThis as typeof globalThis & { crypto?: Crypto }).crypto\n if (runtimeCrypto?.getRandomValues !== undefined) {\n runtimeCrypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < bytes.length; i += 1) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n }\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n\nfunction shopSources(shop: ContentSecurityPolicyShop | undefined): readonly string[] {\n if (shop === undefined) return []\n return [shop.storeDomain, shop.checkoutDomain]\n .filter((domain): domain is string => domain !== undefined && domain.trim() !== '')\n .map((domain) => {\n const trimmed = domain.trim()\n return /^https?:\\/\\//i.test(trimmed) ? new URL(trimmed).origin : `https://${trimmed}`\n })\n}\n\nfunction normalizeSources(sources: readonly string[] | undefined): readonly string[] {\n return (sources ?? []).map((source) => {\n const trimmed = source.trim()\n return QUOTED_TOKENS.has(trimmed) ? `'${trimmed}'` : trimmed\n })\n}\n\nfunction uniqueSources(sources: readonly string[]): readonly string[] {\n return Array.from(new Set(sources.filter((source) => source.length > 0)))\n}\n","import { buildLocalizationCookie } from './cookie'\nimport { localizePath } from './routing'\n\n/** Same-origin path only: must start with a single '/', not '//' or '/\\'. */\nfunction safeReturnTo(raw: string | null): { path: string; safe: boolean } {\n if (raw === null || raw === '') return { path: '/', safe: true }\n return /^\\/(?![/\\\\])/.test(raw) ? { path: raw, safe: true } : { path: '/', safe: false }\n}\n\nexport async function handleLocalizationPost(request: Request): Promise<Response> {\n const form = await request.formData()\n const country = (form.get('country_code') ?? '').toString().trim().toUpperCase() || null\n const locale = (form.get('locale_code') ?? '').toString().trim() || null\n const primaryLocale = (form.get('primary_locale') ?? '').toString().trim() || null\n const returnTo = safeReturnTo((form.get('return_to') ?? '').toString())\n const location =\n returnTo.safe && primaryLocale !== null\n ? localizePath(returnTo.path, locale, { primaryLocale })\n : returnTo.path\n return new Response(null, {\n status: 302,\n headers: { location, 'set-cookie': buildLocalizationCookie({ country, locale }) },\n })\n}\n","/**\n * Coarse visitor geo attached to pixel events — structurally the SDK's `context.geo` (a `Geo` value is\n * assignable here). Declared locally so the analytics surface (and its DOM/React preset) need not pull\n * in the geo crypto module.\n */\nexport interface AnalyticsGeo {\n readonly country: string | null\n readonly city: string | null\n readonly colo: string | null\n readonly botScore: number | null\n readonly clientIp: string | null\n}\n\n/** The standard storefront analytics events (Hydrogen-shaped names). */\nexport const ANALYTICS_EVENTS = {\n pageViewed: 'page_viewed',\n productViewed: 'product_viewed',\n collectionViewed: 'collection_viewed',\n cartViewed: 'cart_viewed',\n searchViewed: 'search_viewed',\n productAddedToCart: 'product_added_to_cart',\n} as const\n\nexport type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS]\n\n/** Ambient context the provider attaches to every event before it reaches the pixel. */\nexport interface AnalyticsContext {\n readonly shopId?: string\n readonly url?: string\n readonly geo?: AnalyticsGeo\n}\n\nexport interface PageViewedPayload {\n readonly title?: string\n}\nexport interface ProductViewedPayload {\n readonly productId: string\n readonly handle?: string\n}\nexport interface CollectionViewedPayload {\n readonly collectionId: string\n readonly handle?: string\n}\nexport interface CartViewedPayload {\n readonly cartId?: string\n}\nexport interface SearchViewedPayload {\n readonly query: string\n readonly resultCount?: number\n}\nexport interface ProductAddedToCartPayload {\n readonly productId: string\n readonly variantId: string\n readonly quantity: number\n}\n\n/** Event name → payload (the typed pub/sub surface). */\nexport interface AnalyticsEventMap {\n page_viewed: PageViewedPayload\n product_viewed: ProductViewedPayload\n collection_viewed: CollectionViewedPayload\n cart_viewed: CartViewedPayload\n search_viewed: SearchViewedPayload\n product_added_to_cart: ProductAddedToCartPayload\n}\n\n/** A pixel-bound event: the name, its payload, the ambient context, a timestamp, and consent state. */\nexport interface PixelEvent<E extends AnalyticsEventName = AnalyticsEventName> {\n readonly event: E\n readonly payload: AnalyticsEventMap[E]\n readonly context: AnalyticsContext\n readonly timestamp: string\n /** Whether the analytics-consent bucket was granted when this event was recorded. */\n readonly consent: boolean\n}\n","export interface ShopAnalytics {\n readonly acceptedLanguage?: string\n readonly currency?: string\n readonly shopId?: string\n readonly storefrontId?: string\n}\n\nexport interface GetShopAnalyticsOptions {\n readonly publicStorefrontId?: string\n readonly storefront?: {\n readonly i18n?: {\n readonly country?: string | null\n readonly currency?: string | null\n readonly language?: string | null\n readonly pathPrefix?: string | null\n } | null\n } | null\n}\n\nexport function getShopAnalytics(options: GetShopAnalyticsOptions): ShopAnalytics {\n const language = options.storefront?.i18n?.language ?? null\n const country = options.storefront?.i18n?.country ?? null\n const currency = options.storefront?.i18n?.currency ?? null\n const acceptedLanguage =\n language != null && country != null ? `${language}-${country}` : (language ?? country)\n\n return {\n ...(acceptedLanguage != null ? { acceptedLanguage } : {}),\n ...(currency != null ? { currency } : {}),\n ...(options.publicStorefrontId != null ? { shopId: options.publicStorefrontId } : {}),\n ...(options.publicStorefrontId != null ? { storefrontId: options.publicStorefrontId } : {}),\n }\n}\n","import { CONSENT_BUCKETS, type ConsentBucket, type ConsentState } from './consent'\n\n/**\n * Encode/decode consent into the `cart.checkoutUrl` handoff (query params), mirroring Shopify's\n * server-set-consent direction (design §Checkout handoff). The handoff target is the Gateway-owned\n * same-origin `/checkout/*` path — `appendConsentToCheckoutUrl` preserves a relative URL as relative\n * so it never points at a separate subdomain.\n */\nconst PARAM_PREFIX = 'consent_'\nconst RELATIVE_BASE = 'https://kotao.invalid'\n\nexport function encodeConsent(state: ConsentState): URLSearchParams {\n const params = new URLSearchParams()\n for (const bucket of CONSENT_BUCKETS)\n params.set(`${PARAM_PREFIX}${bucket}`, state[bucket] ? '1' : '0')\n return params\n}\n\nexport function decodeConsent(params: URLSearchParams): ConsentState {\n const read = (bucket: ConsentBucket): boolean => params.get(`${PARAM_PREFIX}${bucket}`) === '1'\n return {\n analytics: read('analytics'),\n marketing: read('marketing'),\n preferences: read('preferences'),\n }\n}\n\nexport function appendConsentToCheckoutUrl(checkoutUrl: string, state: ConsentState): string {\n // The checkout handoff is the same-origin `/checkout/*` path (cart.checkoutUrl is relative). Reject\n // absolute or protocol-relative URLs so consent params never ride to another origin.\n if (!/^\\/(?!\\/)/.test(checkoutUrl)) {\n throw new Error(`checkoutUrl must be a same-origin path starting with '/'; got: ${checkoutUrl}`)\n }\n const url = new URL(checkoutUrl, RELATIVE_BASE)\n for (const [key, value] of encodeConsent(state)) url.searchParams.set(key, value)\n return `${url.pathname}${url.search}${url.hash}`\n}\n","import {\n CHECKOUT_DESIGN_TOKEN_INPUTS,\n extractCheckoutDesignTokens,\n type CheckoutDesignTokens,\n} from '../checkout/design-tokens'\nimport type { ResolvedSettings } from '../settings/types'\n\nconst CHECKOUT_TOKEN_DEFAULTS: Readonly<Record<string, string>> = Object.fromEntries(\n CHECKOUT_DESIGN_TOKEN_INPUTS.flatMap((input) =>\n 'defaultValue' in input && typeof input.defaultValue === 'string' && input.defaultValue !== ''\n ? [[input.name, input.defaultValue]]\n : [],\n ),\n)\n\n/** Resolve the token contract shared by trusted checkout and customer-account surfaces. */\nexport function resolveHostedBranding(global: ResolvedSettings): CheckoutDesignTokens {\n return extractCheckoutDesignTokens({ global: { ...CHECKOUT_TOKEN_DEFAULTS, ...global } })\n}\n\n/** Escape merchant-controlled text for an HTML text node or double-quoted attribute. */\nexport function escapeHostedHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/**\n * Strip characters that can terminate an inline CSS declaration, block, quote, or style element.\n * Trusted renderers must apply this at the CSS-value sink; the resolved token values themselves\n * remain byte-for-byte compatible with checkout's existing contract.\n */\nexport function sanitizeHostedCssValue(value: string): string {\n return value\n .replace(/[<>\"'`;{}\\\\]/g, '')\n .replace(/[\\r\\n\\t]+/g, ' ')\n .trim()\n}\n","import { readLocalizationCookie } from '../localization/cookie'\n\nexport interface HostedLocaleInput {\n readonly configuredLocales: readonly string[]\n readonly localizationCookie: string | null\n readonly customerLocale: string | null\n readonly primaryLocale: string\n}\n\n/**\n * Resolve display language within the verified shop's configured locale allowlist. Payment\n * jurisdiction and legal-copy decisions deliberately stay outside this display-only resolver.\n */\nexport function resolveHostedLocale(input: HostedLocaleInput): string {\n const configured = input.configuredLocales.map((locale) => locale.trim()).filter(Boolean)\n if (configured.length === 0) throw new Error('hosted surfaces require a configured locale')\n\n const configuredByKey = new Map(configured.map((locale) => [localeKey(locale), locale] as const))\n const cookieLocale = safelyReadCookieLocale(input.localizationCookie)\n\n for (const candidate of [cookieLocale, input.customerLocale, input.primaryLocale]) {\n if (candidate === null || candidate.trim() === '') continue\n const match = configuredByKey.get(localeKey(candidate))\n if (match !== undefined) return match\n }\n\n return configured[0]!\n}\n\nfunction localeKey(locale: string): string {\n return locale.trim().replace(/_/g, '-').toLowerCase()\n}\n\nfunction safelyReadCookieLocale(cookieHeader: string | null): string | null {\n if (cookieHeader === null) return null\n if (!cookieHeader.includes('=')) return cookieHeader.trim() || null\n try {\n return readLocalizationCookie(cookieHeader).locale\n } catch {\n return null\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/cart/useOptimisticCart.ts","../src/content-security-policy.ts","../src/localization/handler.ts","../src/analytics/events.ts","../src/analytics/shop.ts","../src/analytics/consent-encoding.ts","../src/hosted-surface/branding.ts","../src/hosted-surface/localization.ts"],"names":["MARKET_PATH_PREFIX_HEADER"],"mappings":"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","file":"index.js","sourcesContent":["import { CART_FORM_ACTIONS } from './actions'\nimport type { CartDispatchAction } from './createCartHandler'\nimport type { Cart, CartLine } from './types'\n\nconst recalculate = (cart: Cart, lines: readonly CartLine[]): Cart => ({\n ...cart,\n lines,\n totalQuantity: lines.reduce((sum, line) => sum + line.quantity, 0),\n})\n\nexport function applyOptimisticCartAction(cart: Cart, action: CartDispatchAction): Cart {\n switch (action.action) {\n case CART_FORM_ACTIONS.LinesAdd: {\n const inputLines = (action.inputs.lines ?? []) as Array<{\n merchandiseId: string\n quantity?: number | null\n }>\n const additions = inputLines.map<CartLine>((line) => ({\n id: `optimistic:${line.merchandiseId}`,\n quantity: line.quantity ?? 1,\n merchandise: { id: line.merchandiseId },\n attributes: [],\n }))\n return recalculate(cart, [...cart.lines, ...additions])\n }\n case CART_FORM_ACTIONS.LinesUpdate: {\n const updates = new Map(\n ((action.inputs.lines ?? []) as Array<{ id: string; quantity?: number | null }>).map(\n (line) => [line.id, line],\n ),\n )\n const lines = cart.lines\n .map((line) => {\n const update = updates.get(line.id)\n if (!update) return line\n if (update.quantity === 0) return null\n return {\n ...line,\n quantity: update.quantity ?? line.quantity,\n }\n })\n .filter((line): line is CartLine => line !== null)\n return recalculate(cart, lines)\n }\n case CART_FORM_ACTIONS.LinesRemove: {\n const remove = new Set((action.inputs.lineIds ?? []) as string[])\n return recalculate(\n cart,\n cart.lines.filter((line) => !remove.has(line.id)),\n )\n }\n default:\n return cart\n }\n}\n\n/**\n * Pure optimistic helper for React integrations. A React wrapper can call this from `useOptimistic`;\n * keeping the reducer pure lets non-React tests exercise the exact overlay behavior.\n */\nexport function useOptimisticCart(cart: Cart, action: CartDispatchAction | null): Cart {\n return action ? applyOptimisticCartAction(cart, action) : cart\n}\n","import { createNonceProvider, type BoundNonceProvider } from './react/nonce'\n\nexport interface ContentSecurityPolicyShop {\n readonly checkoutDomain?: string\n readonly storeDomain?: string\n}\n\nexport interface CreateContentSecurityPolicyOptions {\n readonly shop?: ContentSecurityPolicyShop\n readonly scriptSrc?: readonly string[]\n readonly connectSrc?: readonly string[]\n readonly imgSrc?: readonly string[]\n readonly styleSrc?: readonly string[]\n}\n\nexport interface ContentSecurityPolicyResult {\n readonly nonce: string\n readonly header: string\n readonly NonceProvider: BoundNonceProvider\n}\n\nconst QUOTED_TOKENS = new Set([\n 'self',\n 'none',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n 'strict-dynamic',\n 'wasm-unsafe-eval',\n])\n\nexport function createContentSecurityPolicy(\n options: CreateContentSecurityPolicyOptions = {},\n): ContentSecurityPolicyResult {\n const nonce = createNonce()\n const shopDomains = shopSources(options.shop)\n const scriptSrc = uniqueSources([\n ...normalizeSources(options.scriptSrc ?? ['self']),\n `'nonce-${nonce}'`,\n ])\n const connectSrc = uniqueSources([\n 'self',\n ...shopDomains,\n ...normalizeSources(options.connectSrc),\n ])\n const imgSrc = uniqueSources([\n 'self',\n 'data:',\n 'https:',\n ...shopDomains,\n ...normalizeSources(options.imgSrc),\n ])\n const styleSrc = uniqueSources(['self', 'unsafe-inline', ...normalizeSources(options.styleSrc)])\n const directives = [\n ['base-uri', [\"'self'\"]],\n ['default-src', [\"'self'\"]],\n ['connect-src', connectSrc],\n ['img-src', imgSrc],\n ['script-src', scriptSrc],\n ['style-src', styleSrc],\n ]\n return {\n nonce,\n header: directives\n .map(([name, values]) => `${name} ${(values as readonly string[]).join(' ')}`)\n .join('; '),\n NonceProvider: createNonceProvider(nonce),\n }\n}\n\nfunction createNonce(): string {\n const bytes = new Uint8Array(18)\n const runtimeCrypto = (globalThis as typeof globalThis & { crypto?: Crypto }).crypto\n if (runtimeCrypto?.getRandomValues !== undefined) {\n runtimeCrypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < bytes.length; i += 1) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n }\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n\nfunction shopSources(shop: ContentSecurityPolicyShop | undefined): readonly string[] {\n if (shop === undefined) return []\n return [shop.storeDomain, shop.checkoutDomain]\n .filter((domain): domain is string => domain !== undefined && domain.trim() !== '')\n .map((domain) => {\n const trimmed = domain.trim()\n return /^https?:\\/\\//i.test(trimmed) ? new URL(trimmed).origin : `https://${trimmed}`\n })\n}\n\nfunction normalizeSources(sources: readonly string[] | undefined): readonly string[] {\n return (sources ?? []).map((source) => {\n const trimmed = source.trim()\n return QUOTED_TOKENS.has(trimmed) ? `'${trimmed}'` : trimmed\n })\n}\n\nfunction uniqueSources(sources: readonly string[]): readonly string[] {\n return Array.from(new Set(sources.filter((source) => source.length > 0)))\n}\n","import { MARKET_PATH_PREFIX_HEADER } from '@kotao/storefront-contracts'\nimport { buildLocalizationCookie } from './cookie'\nimport { localizePath } from './routing'\n\n/** Same-origin path only: must start with a single '/', not '//' or '/\\'. */\nfunction safeReturnTo(raw: string | null): { path: string; safe: boolean } {\n if (raw === null || raw === '') return { path: '/', safe: true }\n return /^\\/(?![/\\\\])/.test(raw) ? { path: raw, safe: true } : { path: '/', safe: false }\n}\n\nexport async function handleLocalizationPost(request: Request): Promise<Response> {\n const form = await request.formData()\n // Shopify localization forms may include the current value as a hidden input before the clicked\n // submit button with the same name. FormData preserves DOM order, so the successful submitter is\n // the final value and must win over the stale hidden default.\n const country =\n (form.getAll('country_code').at(-1) ?? '').toString().trim().toUpperCase() || null\n const locale = (form.getAll('locale_code').at(-1) ?? '').toString().trim() || null\n const primaryLocale = (form.get('primary_locale') ?? '').toString().trim() || null\n const returnTo = safeReturnTo((form.get('return_to') ?? '').toString())\n const location =\n returnTo.safe && primaryLocale !== null\n ? localizePath(returnTo.path, locale, {\n primaryLocale,\n marketPathPrefix: request.headers.get(MARKET_PATH_PREFIX_HEADER),\n })\n : returnTo.path\n return new Response(null, {\n status: 302,\n headers: { location, 'set-cookie': buildLocalizationCookie({ country, locale }) },\n })\n}\n","/**\n * Coarse visitor geo attached to pixel events — structurally the SDK's `context.geo` (a `Geo` value is\n * assignable here). Declared locally so the analytics surface (and its DOM/React preset) need not pull\n * in the geo crypto module.\n */\nexport interface AnalyticsGeo {\n readonly country: string | null\n readonly city: string | null\n readonly colo: string | null\n readonly botScore: number | null\n readonly clientIp: string | null\n}\n\n/** The standard storefront analytics events (Hydrogen-shaped names). */\nexport const ANALYTICS_EVENTS = {\n pageViewed: 'page_viewed',\n productViewed: 'product_viewed',\n collectionViewed: 'collection_viewed',\n cartViewed: 'cart_viewed',\n searchViewed: 'search_viewed',\n productAddedToCart: 'product_added_to_cart',\n} as const\n\nexport type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS]\n\nexport type AnalyticsDeviceClass = 'mobile' | 'tablet' | 'desktop'\n\n/** Ambient context the provider attaches to every event before it reaches the pixel. */\nexport interface AnalyticsContext {\n readonly shopId?: string\n readonly url?: string\n readonly geo?: AnalyticsGeo\n readonly referrer?: string\n readonly utmSource?: string\n readonly utmMedium?: string\n readonly utmCampaign?: string\n readonly deviceClass?: AnalyticsDeviceClass\n}\n\nexport interface PageViewedPayload {\n readonly title?: string\n}\nexport interface ProductViewedPayload {\n readonly productId: string\n /** Stable offer id; Google Merchant Center and Google ecommerce events use this as item_id. */\n readonly variantId?: string\n readonly handle?: string\n readonly title?: string\n readonly variantTitle?: string\n readonly vendor?: string\n readonly sku?: string\n /** Major-unit price, e.g. 24.95. */\n readonly price?: number\n readonly currency?: string\n readonly quantity?: number\n}\nexport interface CollectionViewedPayload {\n readonly collectionId: string\n readonly handle?: string\n}\nexport interface CartViewedPayload {\n readonly cartId?: string\n}\nexport interface SearchViewedPayload {\n readonly query: string\n readonly resultCount?: number\n}\nexport interface ProductAddedToCartPayload {\n readonly productId: string\n readonly variantId: string\n readonly quantity: number\n readonly title?: string\n readonly variantTitle?: string\n readonly vendor?: string\n readonly sku?: string\n /** Major-unit price, e.g. 24.95. */\n readonly price?: number\n readonly currency?: string\n}\n\n/** Event name → payload (the typed pub/sub surface). */\nexport interface AnalyticsEventMap {\n page_viewed: PageViewedPayload\n product_viewed: ProductViewedPayload\n collection_viewed: CollectionViewedPayload\n cart_viewed: CartViewedPayload\n search_viewed: SearchViewedPayload\n product_added_to_cart: ProductAddedToCartPayload\n}\n\n/** A pixel-bound event: the name, its payload, the ambient context, a timestamp, and consent state. */\nexport interface PixelEvent<E extends AnalyticsEventName = AnalyticsEventName> {\n readonly event: E\n readonly payload: AnalyticsEventMap[E]\n readonly context: AnalyticsContext\n readonly timestamp: string\n /** Whether the analytics-consent bucket was granted when this event was recorded. */\n readonly consent: boolean\n}\n","export interface ShopAnalytics {\n readonly acceptedLanguage?: string\n readonly currency?: string\n readonly shopId?: string\n readonly storefrontId?: string\n}\n\nexport interface GetShopAnalyticsOptions {\n readonly publicStorefrontId?: string\n readonly storefront?: {\n readonly i18n?: {\n readonly country?: string | null\n readonly currency?: string | null\n readonly language?: string | null\n readonly pathPrefix?: string | null\n } | null\n } | null\n}\n\nexport function getShopAnalytics(options: GetShopAnalyticsOptions): ShopAnalytics {\n const language = options.storefront?.i18n?.language ?? null\n const country = options.storefront?.i18n?.country ?? null\n const currency = options.storefront?.i18n?.currency ?? null\n const acceptedLanguage =\n language != null && country != null ? `${language}-${country}` : (language ?? country)\n\n return {\n ...(acceptedLanguage != null ? { acceptedLanguage } : {}),\n ...(currency != null ? { currency } : {}),\n ...(options.publicStorefrontId != null ? { shopId: options.publicStorefrontId } : {}),\n ...(options.publicStorefrontId != null ? { storefrontId: options.publicStorefrontId } : {}),\n }\n}\n","import { CONSENT_BUCKETS, type ConsentBucket, type ConsentState } from './consent'\n\n/**\n * Encode/decode consent into the `cart.checkoutUrl` handoff (query params), mirroring Shopify's\n * server-set-consent direction (design §Checkout handoff). The handoff target is the Gateway-owned\n * same-origin `/checkout/*` path — `appendConsentToCheckoutUrl` preserves a relative URL as relative\n * so it never points at a separate subdomain.\n */\nconst PARAM_PREFIX = 'consent_'\nconst RELATIVE_BASE = 'https://kotao.invalid'\n\nexport function encodeConsent(state: ConsentState): URLSearchParams {\n const params = new URLSearchParams()\n for (const bucket of CONSENT_BUCKETS)\n params.set(`${PARAM_PREFIX}${bucket}`, state[bucket] ? '1' : '0')\n return params\n}\n\nexport function decodeConsent(params: URLSearchParams): ConsentState {\n const read = (bucket: ConsentBucket): boolean => params.get(`${PARAM_PREFIX}${bucket}`) === '1'\n return {\n analytics: read('analytics'),\n marketing: read('marketing'),\n preferences: read('preferences'),\n }\n}\n\nexport function appendConsentToCheckoutUrl(checkoutUrl: string, state: ConsentState): string {\n // The checkout handoff is the same-origin `/checkout/*` path (cart.checkoutUrl is relative). Reject\n // absolute or protocol-relative URLs so consent params never ride to another origin.\n if (!/^\\/(?!\\/)/.test(checkoutUrl)) {\n throw new Error(`checkoutUrl must be a same-origin path starting with '/'; got: ${checkoutUrl}`)\n }\n const url = new URL(checkoutUrl, RELATIVE_BASE)\n for (const [key, value] of encodeConsent(state)) url.searchParams.set(key, value)\n return `${url.pathname}${url.search}${url.hash}`\n}\n","import {\n CHECKOUT_DESIGN_TOKEN_INPUTS,\n extractCheckoutDesignTokens,\n type CheckoutDesignTokens,\n} from '../checkout/design-tokens'\nimport type { ResolvedSettings } from '../settings/types'\n\nconst CHECKOUT_TOKEN_DEFAULTS: Readonly<Record<string, string>> = Object.fromEntries(\n CHECKOUT_DESIGN_TOKEN_INPUTS.flatMap((input) =>\n 'defaultValue' in input && typeof input.defaultValue === 'string' && input.defaultValue !== ''\n ? [[input.name, input.defaultValue]]\n : [],\n ),\n)\n\n/** Resolve the token contract shared by trusted checkout and customer-account surfaces. */\nexport function resolveHostedBranding(global: ResolvedSettings): CheckoutDesignTokens {\n return extractCheckoutDesignTokens({ global: { ...CHECKOUT_TOKEN_DEFAULTS, ...global } })\n}\n\n/** Escape merchant-controlled text for an HTML text node or double-quoted attribute. */\nexport function escapeHostedHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/**\n * Strip characters that can terminate an inline CSS declaration, block, quote, or style element.\n * Trusted renderers must apply this at the CSS-value sink; the resolved token values themselves\n * remain byte-for-byte compatible with checkout's existing contract.\n */\nexport function sanitizeHostedCssValue(value: string): string {\n return value\n .replace(/[<>\"'`;{}\\\\]/g, '')\n .replace(/[\\r\\n\\t]+/g, ' ')\n .trim()\n}\n","import { readLocalizationCookie } from '../localization/cookie'\n\nexport interface HostedLocaleInput {\n readonly configuredLocales: readonly string[]\n readonly localizationCookie: string | null\n readonly customerLocale: string | null\n readonly primaryLocale: string\n}\n\n/**\n * Resolve display language within the verified shop's configured locale allowlist. Payment\n * jurisdiction and legal-copy decisions deliberately stay outside this display-only resolver.\n */\nexport function resolveHostedLocale(input: HostedLocaleInput): string {\n const configured = input.configuredLocales.map((locale) => locale.trim()).filter(Boolean)\n if (configured.length === 0) throw new Error('hosted surfaces require a configured locale')\n\n const configuredByKey = new Map(configured.map((locale) => [localeKey(locale), locale] as const))\n const cookieLocale = safelyReadCookieLocale(input.localizationCookie)\n\n for (const candidate of [cookieLocale, input.customerLocale, input.primaryLocale]) {\n if (candidate === null || candidate.trim() === '') continue\n const match = configuredByKey.get(localeKey(candidate))\n if (match !== undefined) return match\n }\n\n return configured[0]!\n}\n\nfunction localeKey(locale: string): string {\n return locale.trim().replace(/_/g, '-').toLowerCase()\n}\n\nfunction safelyReadCookieLocale(cookieHeader: string | null): string | null {\n if (cookieHeader === null) return null\n if (!cookieHeader.includes('=')) return cookieHeader.trim() || null\n try {\n return readLocalizationCookie(cookieHeader).locale\n } catch {\n return null\n }\n}\n"]}
@@ -1,11 +1,13 @@
1
- import { K as KotaoEnv, S as StorefrontExecutionContext, a as KotaoContext } from './routing-sEonP93J.js';
2
- export { b as KotaoSession, s as stripLocalePrefixFromRequest } from './routing-sEonP93J.js';
3
- import { H as HydrogenSession } from './types-bcbQzx87.js';
1
+ import { K as KotaoContext, a as KotaoEnv, S as StorefrontExecutionContext } from './routing-Bz3Cg0BW.js';
2
+ export { b as KotaoSession, s as stripLocalePrefixFromRequest } from './routing-Bz3Cg0BW.js';
3
+ import * as react_router from 'react-router';
4
+ import { RouterContextProvider } from 'react-router';
5
+ import { H as HydrogenSession } from './types-DZX8ScsJ.js';
4
6
  import { b as StorefrontCacheInput } from './client-D51WdvYR.js';
5
- import './fetch-M3Y-fQrW.js';
7
+ import './fetch-Bq_cc8_G.js';
6
8
  import '@kotao/storefront-contracts/theme';
7
- import './createCartHandler-C4RrPwSG.js';
8
- import './client-bsiNPHBi.js';
9
+ import './createCartHandler-7DdKB-GF.js';
10
+ import './client-CwOPPpFF.js';
9
11
  import './types-CSNXbGFW.js';
10
12
  import './http-types-CGh8WGHB.js';
11
13
 
@@ -25,11 +27,30 @@ interface KotaoLoadContextDeps {
25
27
  readonly openCache?: (name: string) => Promise<StorefrontCacheInput>;
26
28
  readonly session?: HydrogenSession;
27
29
  }
30
+ declare module 'react-router' {
31
+ /**
32
+ * Compatibility projection for Hydrogen routes that read `context.storefront` directly.
33
+ * React Router 8 requires the provider instance; the canonical typed value remains available
34
+ * through `context.get(kotaoContext)`.
35
+ */
36
+ interface RouterContextProvider extends KotaoContext {
37
+ }
38
+ /**
39
+ * Source-import compatibility for Hydrogen projects that still name their application context.
40
+ * React Router 8 itself receives `RouterContextProvider`; generated Kotao entries use that type.
41
+ */
42
+ interface AppLoadContext extends KotaoContext {
43
+ }
44
+ }
45
+ declare const kotaoContext: react_router.RouterContext<KotaoContext>;
46
+ declare function createKotaoRouterContext(context: KotaoContext): RouterContextProvider;
47
+ declare function getKotaoContext(context: Readonly<RouterContextProvider>): KotaoContext;
28
48
  /**
29
- * Build the React Router 7 load context for a storefront request. Call from the RR7 server
30
- * entry's `getLoadContext`. Isolated here so the SDK core stays framework-agnostic (a TanStack
49
+ * Build the Kotao storefront context for a React Router request. Wrap the result with
50
+ * `createKotaoRouterContext` before handing it to React Router 8. Isolated here so the SDK core
51
+ * stays framework-agnostic (a TanStack
31
52
  * Start binding can be added alongside without touching the core).
32
53
  */
33
54
  declare const getKotaoLoadContext: (request: Request, env: KotaoEnv, executionCtx: StorefrontExecutionContext, deps?: KotaoLoadContextDeps) => Promise<KotaoContext>;
34
55
 
35
- export { KotaoContext, KotaoEnv, defer, getKotaoLoadContext, json };
56
+ export { KotaoContext, KotaoEnv, createKotaoRouterContext, defer, getKotaoContext, getKotaoLoadContext, json, kotaoContext };
@@ -1,8 +1,10 @@
1
- import { createKotaoContext } from './chunk-4TEFGD42.js';
2
- export { stripLocalePrefixFromRequest } from './chunk-4TEFGD42.js';
1
+ import { createKotaoContext } from './chunk-EG34HLSX.js';
2
+ export { stripLocalePrefixFromRequest } from './chunk-EG34HLSX.js';
3
3
  import './chunk-OGWYTYYS.js';
4
- import './chunk-M7BPQ54D.js';
5
- import './chunk-7MTCGXIG.js';
4
+ import './chunk-2MRB6SMP.js';
5
+ import './chunk-CKGI3Y7L.js';
6
+ import './chunk-R4N565GX.js';
7
+ import { createContext, RouterContextProvider } from 'react-router';
6
8
 
7
9
  // src/react-router/compat.ts
8
10
  function normalizeJsonInit(init) {
@@ -26,10 +28,17 @@ async function defer(data, _init) {
26
28
  }
27
29
  return await data;
28
30
  }
29
-
30
- // src/react-router/binding.ts
31
+ var kotaoContext = createContext();
32
+ function createKotaoRouterContext(context) {
33
+ const provider = Object.assign(new RouterContextProvider(), context);
34
+ provider.set(kotaoContext, context);
35
+ return provider;
36
+ }
37
+ function getKotaoContext(context) {
38
+ return context.get(kotaoContext);
39
+ }
31
40
  var getKotaoLoadContext = (request, env, executionCtx, deps) => createKotaoContext(request, env, executionCtx, deps);
32
41
 
33
- export { defer, getKotaoLoadContext, json };
42
+ export { createKotaoRouterContext, defer, getKotaoContext, getKotaoLoadContext, json, kotaoContext };
34
43
  //# sourceMappingURL=react-router.js.map
35
44
  //# sourceMappingURL=react-router.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react-router/compat.ts","../src/react-router/binding.ts"],"names":[],"mappings":";;;;;;;AAUA,SAAS,kBAAkB,IAAA,EAA2C;AACpE,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,EAAE,MAAA,EAAQ,MAAK,GAAI,IAAA;AACvD;AAEA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,KAAA,KAAU,QAAQ,OAAO,KAAA,KAAU,YAAY,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAEA,SAAS,cAAc,KAAA,EAA+C;AACpE,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,IAAK,OAAO,MAAM,IAAA,KAAS,UAAA;AAClD;AAEO,SAAS,IAAA,CAAQ,MAAS,IAAA,EAAkC;AACjE,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,iBAAA,CAAkB,IAAI,CAAC,CAAA;AACpD;AAEA,eAAsB,KAAA,CAAS,MAAS,KAAA,EAA+C;AACrF,EAAA,IAAI,SAAS,IAAI,CAAA,IAAK,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG;AAC1C,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAA;AAAA,MAC5B,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAI,OAAO,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,CAAC,GAAA,EAAK,MAAM,KAAK,CAAU;AAAA,KAC9E;AACA,IAAA,OAAO,MAAA,CAAO,YAAY,OAAO,CAAA;AAAA,EACnC;AAEA,EAAA,OAAQ,MAAM,IAAA;AAChB;;;ACfO,IAAM,mBAAA,GAAsB,CACjC,OAAA,EACA,GAAA,EACA,YAAA,EACA,SAC0B,kBAAA,CAAmB,OAAA,EAAS,GAAA,EAAK,YAAA,EAAc,IAAI","file":"react-router.js","sourcesContent":["type JsonInit = ResponseInit | number\nexport interface JsonResponse<T> {\n readonly type: string\n readonly data: T\n readonly init: ResponseInit | null\n}\n\ntype AwaitedDeferred<T> =\n T extends Record<string, unknown> ? { [K in keyof T]: Awaited<T[K]> } : Awaited<T>\n\nfunction normalizeJsonInit(init?: JsonInit): ResponseInit | undefined {\n return typeof init === 'number' ? { status: init } : init\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return isRecord(value) && typeof value.then === 'function'\n}\n\nexport function json<T>(data: T, init?: JsonInit): JsonResponse<T> {\n return Response.json(data, normalizeJsonInit(init)) as unknown as JsonResponse<T>\n}\n\nexport async function defer<T>(data: T, _init?: JsonInit): Promise<AwaitedDeferred<T>> {\n if (isRecord(data) && !isPromiseLike(data)) {\n const entries = await Promise.all(\n Object.entries(data).map(async ([key, value]) => [key, await value] as const),\n )\n return Object.fromEntries(entries) as AwaitedDeferred<T>\n }\n\n return (await data) as AwaitedDeferred<T>\n}\n","import type { HydrogenSession } from '../cart/types'\nimport type { StorefrontCacheInput } from '../cache/cache'\nimport {\n createKotaoContext,\n type KotaoContext,\n type KotaoEnv,\n type StorefrontExecutionContext,\n} from '../context/context'\nexport { stripLocalePrefixFromRequest } from '../localization/routing'\n\nexport interface KotaoLoadContextDeps {\n readonly openCache?: (name: string) => Promise<StorefrontCacheInput>\n readonly session?: HydrogenSession\n}\n\n/**\n * Build the React Router 7 load context for a storefront request. Call from the RR7 server\n * entry's `getLoadContext`. Isolated here so the SDK core stays framework-agnostic (a TanStack\n * Start binding can be added alongside without touching the core).\n */\nexport const getKotaoLoadContext = (\n request: Request,\n env: KotaoEnv,\n executionCtx: StorefrontExecutionContext,\n deps?: KotaoLoadContextDeps,\n): Promise<KotaoContext> => createKotaoContext(request, env, executionCtx, deps)\n"]}
1
+ {"version":3,"sources":["../src/react-router/compat.ts","../src/react-router/binding.ts"],"names":[],"mappings":";;;;;;;;;AAUA,SAAS,kBAAkB,IAAA,EAA2C;AACpE,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,EAAE,MAAA,EAAQ,MAAK,GAAI,IAAA;AACvD;AAEA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,KAAA,KAAU,QAAQ,OAAO,KAAA,KAAU,YAAY,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAEA,SAAS,cAAc,KAAA,EAA+C;AACpE,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,IAAK,OAAO,MAAM,IAAA,KAAS,UAAA;AAClD;AAEO,SAAS,IAAA,CAAQ,MAAS,IAAA,EAAkC;AACjE,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,iBAAA,CAAkB,IAAI,CAAC,CAAA;AACpD;AAEA,eAAsB,KAAA,CAAS,MAAS,KAAA,EAA+C;AACrF,EAAA,IAAI,SAAS,IAAI,CAAA,IAAK,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG;AAC1C,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAA;AAAA,MAC5B,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAI,OAAO,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,CAAC,GAAA,EAAK,MAAM,KAAK,CAAU;AAAA,KAC9E;AACA,IAAA,OAAO,MAAA,CAAO,YAAY,OAAO,CAAA;AAAA,EACnC;AAEA,EAAA,OAAQ,MAAM,IAAA;AAChB;ACFO,IAAM,eAAe,aAAA;AAErB,SAAS,yBAAyB,OAAA,EAA8C;AACrF,EAAA,MAAM,WAAW,MAAA,CAAO,MAAA,CAAO,IAAI,qBAAA,IAAyB,OAAO,CAAA;AACnE,EAAA,QAAA,CAAS,GAAA,CAAI,cAAc,OAAO,CAAA;AAClC,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,gBAAgB,OAAA,EAAwD;AACtF,EAAA,OAAO,OAAA,CAAQ,IAAI,YAAY,CAAA;AACjC;AAQO,IAAM,mBAAA,GAAsB,CACjC,OAAA,EACA,GAAA,EACA,YAAA,EACA,SAC0B,kBAAA,CAAmB,OAAA,EAAS,GAAA,EAAK,YAAA,EAAc,IAAI","file":"react-router.js","sourcesContent":["type JsonInit = ResponseInit | number\nexport interface JsonResponse<T> {\n readonly type: string\n readonly data: T\n readonly init: ResponseInit | null\n}\n\ntype AwaitedDeferred<T> =\n T extends Record<string, unknown> ? { [K in keyof T]: Awaited<T[K]> } : Awaited<T>\n\nfunction normalizeJsonInit(init?: JsonInit): ResponseInit | undefined {\n return typeof init === 'number' ? { status: init } : init\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return isRecord(value) && typeof value.then === 'function'\n}\n\nexport function json<T>(data: T, init?: JsonInit): JsonResponse<T> {\n return Response.json(data, normalizeJsonInit(init)) as unknown as JsonResponse<T>\n}\n\nexport async function defer<T>(data: T, _init?: JsonInit): Promise<AwaitedDeferred<T>> {\n if (isRecord(data) && !isPromiseLike(data)) {\n const entries = await Promise.all(\n Object.entries(data).map(async ([key, value]) => [key, await value] as const),\n )\n return Object.fromEntries(entries) as AwaitedDeferred<T>\n }\n\n return (await data) as AwaitedDeferred<T>\n}\n","import type { HydrogenSession } from '../cart/types'\nimport type { StorefrontCacheInput } from '../cache/cache'\nimport { createContext, RouterContextProvider } from 'react-router'\nimport {\n createKotaoContext,\n type KotaoContext,\n type KotaoEnv,\n type StorefrontExecutionContext,\n} from '../context/context'\nexport { stripLocalePrefixFromRequest } from '../localization/routing'\n\nexport interface KotaoLoadContextDeps {\n readonly openCache?: (name: string) => Promise<StorefrontCacheInput>\n readonly session?: HydrogenSession\n}\n\ndeclare module 'react-router' {\n /**\n * Compatibility projection for Hydrogen routes that read `context.storefront` directly.\n * React Router 8 requires the provider instance; the canonical typed value remains available\n * through `context.get(kotaoContext)`.\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface RouterContextProvider extends KotaoContext {}\n\n /**\n * Source-import compatibility for Hydrogen projects that still name their application context.\n * React Router 8 itself receives `RouterContextProvider`; generated Kotao entries use that type.\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface AppLoadContext extends KotaoContext {}\n}\n\nexport const kotaoContext = createContext<KotaoContext>()\n\nexport function createKotaoRouterContext(context: KotaoContext): RouterContextProvider {\n const provider = Object.assign(new RouterContextProvider(), context)\n provider.set(kotaoContext, context)\n return provider\n}\n\nexport function getKotaoContext(context: Readonly<RouterContextProvider>): KotaoContext {\n return context.get(kotaoContext)\n}\n\n/**\n * Build the Kotao storefront context for a React Router request. Wrap the result with\n * `createKotaoRouterContext` before handing it to React Router 8. Isolated here so the SDK core\n * stays framework-agnostic (a TanStack\n * Start binding can be added alongside without touching the core).\n */\nexport const getKotaoLoadContext = (\n request: Request,\n env: KotaoEnv,\n executionCtx: StorefrontExecutionContext,\n deps?: KotaoLoadContextDeps,\n): Promise<KotaoContext> => createKotaoContext(request, env, executionCtx, deps)\n"]}
package/dist/react.d.ts CHANGED
@@ -1,16 +1,19 @@
1
- import react__default, { ReactNode, ReactElement, ImgHTMLAttributes, VideoHTMLAttributes, ElementType, AnchorHTMLAttributes, CSSProperties, ComponentPropsWithoutRef } from 'react';
1
+ import react__default, { ReactNode, ReactElement, ImgHTMLAttributes, VideoHTMLAttributes, ElementType, AnchorHTMLAttributes, CSSProperties, ComponentPropsWithoutRef, ComponentType } from 'react';
2
2
  import { FetcherWithComponents } from 'react-router';
3
- import { j as CartFormAction, a as CartLineInput } from './types-bcbQzx87.js';
4
- import { g as getCartFormInput, S as ShopAnalytics, A as AnalyticsContext, C as ConsentState, a as AnalyticsEmitter, b as AnalyticsBus } from './shop-BJSvtmnV.js';
5
- export { u as useNonce } from './shop-BJSvtmnV.js';
3
+ import { j as CartFormAction, a as CartLineInput } from './types-DZX8ScsJ.js';
4
+ import { g as getCartFormInput, S as ShopAnalytics, A as AnalyticsContext, C as ConsentState, a as AnalyticsEmitter, b as AnalyticsBus } from './shop-CnrnSAJw.js';
5
+ export { u as useNonce } from './shop-CnrnSAJw.js';
6
6
  import { Cart } from './storefront-api-types.js';
7
7
  import { ImageAttrsOptions, ImageData, ImageCrop, ImageFormat } from './image.js';
8
8
  import { C as Connection, P as PaginationInfo } from './pagination-DCrQk02Q.js';
9
- import { S as SeoConfig } from './types-BDhHWZsP.js';
10
- import { T as ThemeSettingsStore, R as ResolvedSettings, a as ThemeSettingsSnapshot } from './store-CtCWHI8H.js';
11
- import { SmartCartMountConfig, CartAdapter } from '@kotao/smart-cart';
12
- export { R as REACT_SEAM_CART_DOCUMENTS, c as createStorefrontApiCartAdapter } from './cart-documents-CwwRTvm8.js';
9
+ import { S as SeoConfig } from './types-BkY0yET-.js';
10
+ import { T as ThemeSettingsStore, R as ResolvedSettings, c as ThemeSettingsSnapshot } from './store-DO08fzJi.js';
11
+ import { S as SmartCartMountConfig, C as CartAdapter } from './cart-documents-BLavRDiu.js';
12
+ export { R as REACT_SEAM_CART_DOCUMENTS, a as SmartCartBranding, b as SmartCartLine, c as SmartCartLineDiscount, d as SmartCartLineOption, e as SmartCartMoney, f as SmartCartState, g as createStorefrontApiCartAdapter } from './cart-documents-BLavRDiu.js';
13
13
  import { P as PublicForm, a as FormAnswers, b as FormFieldErrors } from './types-CSNXbGFW.js';
14
+ import { a as HydrogenEditorPreviewRuntime, x as HydrogenEditorReconciliationReason, l as HydrogenEditorInstanceSnapshot } from './hydrogen-Bu7k0kE4.js';
15
+ import '@kotao/storefront-contracts';
16
+ import './bridge-ZKbKqgFd.js';
14
17
 
15
18
  type CartFormInputValue = unknown;
16
19
  type CartFormFetcher = FetcherWithComponents<unknown>;
@@ -71,7 +74,7 @@ interface AnalyticsProviderProps {
71
74
  readonly shopId?: string;
72
75
  readonly shop?: ShopAnalytics;
73
76
  readonly geo?: AnalyticsContext['geo'];
74
- /** Current page URL; changing it auto-emits `page_viewed` (themes pass it from RR7 navigation). */
77
+ /** Current page URL; changing it auto-emits `page_viewed` (themes pass it from RR8 navigation). */
75
78
  readonly url?: string;
76
79
  /** Same-origin pixel endpoint (default '/api/storefront/pixel'). */
77
80
  readonly pixelEndpoint?: string;
@@ -111,9 +114,11 @@ interface AnalyticsProductViewProps {
111
114
  readonly products?: readonly {
112
115
  readonly handle?: string | null;
113
116
  readonly id?: string | null;
114
- readonly price?: string | null;
117
+ readonly price?: number | string | null;
115
118
  readonly productId?: string | null;
116
119
  readonly quantity?: number | null;
120
+ readonly sku?: string | null;
121
+ readonly currency?: string | null;
117
122
  readonly title?: string | null;
118
123
  readonly variantId?: string | null;
119
124
  readonly variantTitle?: string | null;
@@ -319,4 +324,67 @@ interface StorefrontFormFieldsProps {
319
324
  declare function StorefrontFormFields({ form, locale, fallbackLocale, answers: initialAnswers, errors, onAnswersChange, idPrefix, }: StorefrontFormFieldsProps): react__default.JSX.Element;
320
325
  declare function StorefrontForm({ form, locale, fallbackLocale, answers, errors, submitted, submitLabel, onAnswersChange, action, method, ...props }: StorefrontFormProps): react__default.JSX.Element;
321
326
 
322
- export { Analytics, AnalyticsCartView, type AnalyticsCartViewProps, AnalyticsCollectionView, type AnalyticsCollectionViewProps, AnalyticsProductView, type AnalyticsProductViewProps, AnalyticsProvider, type AnalyticsProviderProps, AnalyticsSearchView, type AnalyticsSearchViewProps, CartDrawerOverlay, type CartDrawerOverlayProps, CartForm, type CartFormFetcher, type CartFormProps, type CartQueryDataReturn, type CartReturn, ConsentBanner, type ConsentBannerProps, type ConsentBannerRenderProps, Image, type ImageProps, MediaFile, type MediaFileImageOptions, type MediaFileProps, type MediaFileVideoOptions, Money, type MoneyData, type MoneyProps, type OptimisticCartLineInput, OptimisticInput, type OptimisticInputData, type OptimisticInputProps, Pagination, type PaginationProps, Seo, type SeoProps, ShopPayButton, type ShopPayButtonProps, StorefrontForm, StorefrontFormFields, type StorefrontFormFieldsProps, type StorefrontFormProps, ThemeSettingsProvider, type ThemeSettingsProviderProps, type UseMoneyValue, openSmartCart, useAnalytics, useGlobalThemeTokens, useMoney, useOptimisticData, useSectionSettings, useThemeSettings };
327
+ interface HydrogenEditorRegisteredComponentProps {
328
+ readonly instanceId: string;
329
+ readonly props: Readonly<Record<string, unknown>>;
330
+ readonly styles: Readonly<Record<string, string | number>>;
331
+ readonly slots: Readonly<Record<string, readonly string[]>>;
332
+ readonly variantId?: string;
333
+ }
334
+ type HydrogenEditorRegisteredComponent = ComponentType<HydrogenEditorRegisteredComponentProps>;
335
+ interface HydrogenEditorProviderProps {
336
+ readonly preview: HydrogenEditorPreviewRuntime;
337
+ readonly documentId: string;
338
+ readonly route?: string;
339
+ readonly reconciliationReason?: HydrogenEditorReconciliationReason;
340
+ /**
341
+ * Changes when same-route loader data or an HMR generation reconciles. It is deliberately not
342
+ * interpreted as authority and is never sent across the bridge.
343
+ */
344
+ readonly reconciliationKey?: string | number;
345
+ readonly components?: Readonly<Record<string, HydrogenEditorRegisteredComponent>>;
346
+ readonly viewportWidth?: number;
347
+ readonly children: ReactNode;
348
+ }
349
+ /**
350
+ * Activates the editor runtime for a route. Route/loader/HMR changes reconcile the existing
351
+ * preview store instead of replacing it, so source-backed draft operations and selection remain
352
+ * visible. The provider is editor-only and must not be mounted in ordinary public responses.
353
+ */
354
+ declare function HydrogenEditorProvider({ children, components, documentId, preview, reconciliationKey, reconciliationReason, route, viewportWidth, }: HydrogenEditorProviderProps): ReactElement;
355
+ interface HydrogenEditorReactInstance {
356
+ readonly snapshot: HydrogenEditorInstanceSnapshot;
357
+ readonly props: Readonly<Record<string, unknown>>;
358
+ readonly styles: Readonly<Record<string, string | number>>;
359
+ }
360
+ /**
361
+ * Subscribes to exactly one component instance. A prop/style operation invalidates only this
362
+ * subscription; structural operations additionally invalidate the affected parent/slot.
363
+ */
364
+ declare function useHydrogenEditorInstance(instanceId: string, sourceProps?: Readonly<Record<string, unknown>>): HydrogenEditorReactInstance | null;
365
+ declare function useHydrogenEditorSlot(parentInstanceId: string, slotId: string): readonly string[];
366
+ interface HydrogenEditorBoundaryProps {
367
+ readonly instanceId: string;
368
+ readonly children: ReactElement;
369
+ readonly applyPreviewProps?: boolean;
370
+ readonly viewportWidth?: number;
371
+ }
372
+ /**
373
+ * A reconciliation and interaction boundary for one extracted JSX instance. It uses a
374
+ * `display: contents` marker only in editor mode, preserving the component's layout while clicks
375
+ * and pointer transitions remain attributable to the stable instance ID.
376
+ */
377
+ declare function HydrogenEditorBoundary({ applyPreviewProps, children, instanceId, viewportWidth, }: HydrogenEditorBoundaryProps): ReactElement | null;
378
+ interface HydrogenEditorSlotProps {
379
+ readonly parentInstanceId: string;
380
+ readonly slotId: string;
381
+ /**
382
+ * Source-rendered children keyed by stable instance ID. Newly inserted instances fall through to
383
+ * the registered component library without replacing or regenerating existing route source.
384
+ */
385
+ readonly existingChildren?: Readonly<Record<string, ReactElement>>;
386
+ readonly empty?: ReactNode;
387
+ }
388
+ declare function HydrogenEditorSlot({ empty, existingChildren, parentInstanceId, slotId, }: HydrogenEditorSlotProps): ReactElement;
389
+
390
+ export { Analytics, AnalyticsCartView, type AnalyticsCartViewProps, AnalyticsCollectionView, type AnalyticsCollectionViewProps, AnalyticsProductView, type AnalyticsProductViewProps, AnalyticsProvider, type AnalyticsProviderProps, AnalyticsSearchView, type AnalyticsSearchViewProps, CartAdapter, CartDrawerOverlay, type CartDrawerOverlayProps, CartForm, type CartFormFetcher, type CartFormProps, type CartQueryDataReturn, type CartReturn, ConsentBanner, type ConsentBannerProps, type ConsentBannerRenderProps, HydrogenEditorBoundary, type HydrogenEditorBoundaryProps, HydrogenEditorProvider, type HydrogenEditorProviderProps, type HydrogenEditorReactInstance, type HydrogenEditorRegisteredComponent, type HydrogenEditorRegisteredComponentProps, HydrogenEditorSlot, type HydrogenEditorSlotProps, Image, type ImageProps, MediaFile, type MediaFileImageOptions, type MediaFileProps, type MediaFileVideoOptions, Money, type MoneyData, type MoneyProps, type OptimisticCartLineInput, OptimisticInput, type OptimisticInputData, type OptimisticInputProps, Pagination, type PaginationProps, Seo, type SeoProps, ShopPayButton, type ShopPayButtonProps, SmartCartMountConfig, StorefrontForm, StorefrontFormFields, type StorefrontFormFieldsProps, type StorefrontFormProps, ThemeSettingsProvider, type ThemeSettingsProviderProps, type UseMoneyValue, openSmartCart, useAnalytics, useGlobalThemeTokens, useHydrogenEditorInstance, useHydrogenEditorSlot, useMoney, useOptimisticData, useSectionSettings, useThemeSettings };