@kotao/storefront 0.2.5 → 0.2.7

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 (70) hide show
  1. package/README.md +57 -2
  2. package/dist/bridge-CfNBWu0H.d.ts +260 -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-GGOZELAA.js → chunk-DTKLAOKR.js} +231 -165
  11. package/dist/chunk-DTKLAOKR.js.map +1 -0
  12. package/dist/{chunk-MCIFKJQK.js → chunk-R4N565GX.js} +5 -2
  13. package/dist/chunk-R4N565GX.js.map +1 -0
  14. package/dist/chunk-RFKLO6TD.js +1594 -0
  15. package/dist/chunk-RFKLO6TD.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 +4 -2
  35. package/dist/events-react.js +6 -4
  36. package/dist/events-react.js.map +1 -1
  37. package/dist/events.d.ts +3 -3
  38. package/dist/events.js +1 -1
  39. package/dist/{fetch-M3Y-fQrW.d.ts → fetch-Bq_cc8_G.d.ts} +5 -0
  40. package/dist/hydrogen-CqDMW3YC.d.ts +259 -0
  41. package/dist/index.d.ts +75 -51
  42. package/dist/index.js +19 -15
  43. package/dist/index.js.map +1 -1
  44. package/dist/react-router.d.ts +40 -9
  45. package/dist/react-router.js +16 -7
  46. package/dist/react-router.js.map +1 -1
  47. package/dist/react.d.ts +79 -11
  48. package/dist/react.js +279 -10
  49. package/dist/react.js.map +1 -1
  50. package/dist/{routing-sEonP93J.d.ts → routing-Bz3Cg0BW.d.ts} +36 -6
  51. package/dist/seo.d.ts +7 -4
  52. package/dist/seo.js +2 -2
  53. package/dist/settings.d.ts +14 -4
  54. package/dist/settings.js +2 -2
  55. package/dist/{shop-BJSvtmnV.d.ts → shop-CnrnSAJw.d.ts} +33 -6
  56. package/dist/{store-CtCWHI8H.d.ts → store-ZzoBbWir.d.ts} +1 -1
  57. package/dist/storefront-api-types.d.ts +12 -0
  58. package/dist/{types-BDhHWZsP.d.ts → types-BkY0yET-.d.ts} +3 -3
  59. package/dist/{types-bcbQzx87.d.ts → types-DZX8ScsJ.d.ts} +2 -0
  60. package/package.json +4 -4
  61. package/dist/cart-documents-CwwRTvm8.d.ts +0 -21
  62. package/dist/chunk-2IWNUDSZ.js.map +0 -1
  63. package/dist/chunk-GGOZELAA.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-MCIFKJQK.js.map +0 -1
  67. package/dist/chunk-PXVDVUFX.js.map +0 -1
  68. package/dist/chunk-PXZ737N3.js +0 -439
  69. package/dist/chunk-PXZ737N3.js.map +0 -1
  70. package/dist/chunk-XMTWFJCZ.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,27 +1,29 @@
1
1
  export { c as CacheCustom, d as CacheLong, e as CacheNone, f as CacheShort, C as CacheStrategy, H as HydrogenStorefrontClientOptions, K as KotaoCache, g as StaleIfErrorFallback, h as Storefront, a as StorefrontAuthHeader, i as StorefrontCache, b as StorefrontCacheInput, j as StorefrontCacheQueryOptions, k as StorefrontCacheRequest, S as StorefrontClient, l as StorefrontClientOptions, m as StorefrontClientResult, n as StorefrontDefaultCache, o as StorefrontQueryOptions, p as StorefrontQueryTimeoutError, q as StorefrontUpstreamError, r as createCache, s as createStorefrontClient, t as generateCacheControlHeader } from './client-D51WdvYR.js';
2
- import { C as Cart } from './types-bcbQzx87.js';
3
- export { k as CART_FORM_ACTIONS, b as CartAttribute, l as CartBuyerIdentity, c as CartBuyerIdentityInput, h as CartDeliveryAddress, j as CartFormAction, m as CartLine, a as CartLineInput, e as CartLineUpdateInput, f as CartMetafield, g as CartMetafieldIdentifier, d as CartMutationResult, i as CartSelectedDeliveryOption, n as CartUserError, o as HydrogenCart, p as HydrogenCartCreateInput, q as HydrogenCartMutationResult, H as HydrogenSession, r as HydrogenSessionData } from './types-bcbQzx87.js';
4
- import { c as ConsentBucket, C as ConsentState, B as BoundNonceProvider } from './shop-BJSvtmnV.js';
5
- export { d as ANALYTICS_EVENTS, b as AnalyticsBus, e as AnalyticsBusOptions, A as AnalyticsContext, a as AnalyticsEmitter, f as AnalyticsEventMap, h as AnalyticsEventName, i as AnalyticsGeo, j as CONSENT_BUCKETS, k as CONSENT_COOKIE, l as CartForm, m as CartFormProps, n as CartViewedPayload, o as CollectionViewedPayload, D as DENIED_CONSENT, E as EventHandler, G as GRANTED_CONSENT, p as GetShopAnalyticsOptions, P as PageViewedPayload, q as PixelEvent, r as PixelSend, s as PixelTransport, t as PixelTransportOptions, v as ProductAddedToCartPayload, w as ProductViewedPayload, x as SearchViewedPayload, S as ShopAnalytics, y as buildConsentCookie, z as createAnalyticsBus, F as createAnalyticsEmitter, H as createPixelTransport, I as getShopAnalytics, J as isGranted, K as mergeConsent, L as parseConsent, M as readConsentCookie, N as serializeConsent } from './shop-BJSvtmnV.js';
6
- import { a as CartDispatchAction } from './createCartHandler-C4RrPwSG.js';
7
- export { b as CartGetId, C as CartHandler, c as CartSetId, d as CreateCartHandlerOptions, H as HydrogenCartHandlerOptions, R as RequestCartHandlerOptions, e as cartGetIdDefault, f as cartSetIdDefault, g as createCartHandler } from './createCartHandler-C4RrPwSG.js';
8
- import { a as ThemeSettingsSnapshot, R as ResolvedSettings } from './store-CtCWHI8H.js';
9
- export { b as ResolvedBlock, c as ResolvedSection, T as ThemeSettingsStore, d as createThemeSettingsStore } from './store-CtCWHI8H.js';
10
- import { C as CustomerAccountClient } from './routing-sEonP93J.js';
11
- export { A as Address, c as AddressConnection, d as CustomerAccount, e as CustomerAccountError, f as CustomerAccountErrorCode, G as GEO_HEADER, g as GEO_SIGNATURE_HEADER, h as Geo, a as KotaoContext, K as KotaoEnv, b as KotaoSession, L as LocalizePathOptions, M as Money, O as Order, i as OrderConnection, j as OrderPageInfo, k as OrdersOptions, R as ROUTING_LOCALE_HEADER, l as ROUTING_ORIGINAL_PATHNAME_HEADER, m as RequestLoginCodeInput, n as RequestLoginCodeResult, S as StorefrontExecutionContext, o as StrippedLocalePath, V as VerifyLoginCodeInput, W as WithCache, p as createKotaoContext, q as createWithCache, r as isLocalePathSegment, t as localeFromAcceptLanguage, u as localeFromPathname, v as localeFromRequest, w as localizePath, x as originalPathnameFromRequest, y as signGeo, z as stripLocalePrefixFromPathname, s as stripLocalePrefixFromRequest, B as trustedShopOriginFromHeaders, D as verifyGeo } from './routing-sEonP93J.js';
2
+ import { C as Cart } from './types-DZX8ScsJ.js';
3
+ export { k as CART_FORM_ACTIONS, b as CartAttribute, l as CartBuyerIdentity, c as CartBuyerIdentityInput, h as CartDeliveryAddress, j as CartFormAction, m as CartLine, a as CartLineInput, e as CartLineUpdateInput, f as CartMetafield, g as CartMetafieldIdentifier, d as CartMutationResult, i as CartSelectedDeliveryOption, n as CartUserError, o as HydrogenCart, p as HydrogenCartCreateInput, q as HydrogenCartMutationResult, H as HydrogenSession, r as HydrogenSessionData } from './types-DZX8ScsJ.js';
4
+ import { c as ConsentBucket, C as ConsentState, B as BoundNonceProvider, A as AnalyticsContext } from './shop-CnrnSAJw.js';
5
+ export { d as ANALYTICS_EVENTS, b as AnalyticsBus, e as AnalyticsBusOptions, f as AnalyticsDeviceClass, a as AnalyticsEmitter, h as AnalyticsEventMap, i as AnalyticsEventName, j as AnalyticsGeo, k as CONSENT_BUCKETS, l as CONSENT_COOKIE, m as CartForm, n as CartFormProps, o as CartViewedPayload, p as CollectionViewedPayload, D as DENIED_CONSENT, E as EventHandler, G as GRANTED_CONSENT, q as GetShopAnalyticsOptions, P as PageViewedPayload, r as PixelEvent, s as PixelSend, t as PixelTransport, v as PixelTransportOptions, w as ProductAddedToCartPayload, x as ProductViewedPayload, y as SearchViewedPayload, S as ShopAnalytics, z as buildConsentCookie, F as createAnalyticsBus, H as createAnalyticsEmitter, I as createPixelTransport, J as getShopAnalytics, K as isGranted, L as mergeConsent, M as parseConsent, N as readConsentCookie, O as serializeConsent } from './shop-CnrnSAJw.js';
6
+ import { a as CartDispatchAction } from './createCartHandler-7DdKB-GF.js';
7
+ export { b as CartGetId, C as CartHandler, c as CartSetId, d as CreateCartHandlerOptions, H as HydrogenCartHandlerOptions, R as RequestCartHandlerOptions, e as cartGetIdDefault, f as cartSetIdDefault, g as createCartHandler } from './createCartHandler-7DdKB-GF.js';
8
+ import { c as ThemeSettingsSnapshot, R as ResolvedSettings } from './store-ZzoBbWir.js';
9
+ export { b as ResolvedBlock, a as ResolvedSection, d as ResolvedValuesDocument, T as ThemeSettingsStore, e as createThemeSettingsStore } from './store-ZzoBbWir.js';
10
+ import { C as CustomerAccountClient } from './routing-Bz3Cg0BW.js';
11
+ export { A as Address, c as AddressConnection, d as CustomerAccount, e as CustomerAccountError, f as CustomerAccountErrorCode, G as GEO_HEADER, g as GEO_SIGNATURE_HEADER, h as Geo, K as KotaoContext, a as KotaoEnv, b as KotaoSession, L as LocalizePathOptions, M as Money, O as Order, i as OrderConnection, j as OrderPageInfo, k as OrdersOptions, R as ROUTING_LOCALE_HEADER, l as ROUTING_ORIGINAL_PATHNAME_HEADER, m as RequestLoginCodeInput, n as RequestLoginCodeResult, S as StorefrontExecutionContext, o as StorefrontMarketContext, p as StrippedLocalePath, V as VerifyLoginCodeInput, W as WithCache, q as createKotaoContext, r as createWithCache, t as isLocalePathSegment, u as localeFromAcceptLanguage, v as localeFromPathname, w as localeFromRequest, x as localizePath, y as marketContextFromHeaders, z as originalPathnameFromRequest, B as signGeo, D as stripLocalePrefixFromPathname, s as stripLocalePrefixFromRequest, E as trustedShopOriginFromHeaders, F as verifyGeo } from './routing-Bz3Cg0BW.js';
12
+ export { AUTO_REDIRECT_LANGUAGE_HEADER, MARKET_ALTERNATE_LOCALES_HEADER, MARKET_CANONICAL_URL_HEADER, MARKET_DEFAULT_LOCALE_HEADER, MARKET_ID_HEADER, MARKET_PATH_PREFIX_HEADER, MARKET_ROOT_URLS_HEADER, MARKET_SETTINGS_ENVIRONMENT_HEADER, MARKET_THEME_ID_HEADER, autoRedirectEnabled } from '@kotao/storefront-contracts';
12
13
  export { ImageAttrs, ImageAttrsOptions, ImageCrop, ImageData, ImageFit, ImageFormat, ImageSrcSetOptions, ImageUrlOptions, buildImageAttrs, imageSrcSet, imageUrl } from './image.js';
13
14
  export { C as Connection, a as ConnectionEdge, F as FlattenableConnection, b as PageInfo, P as PaginationInfo, c as PaginationOptions, d as PaginationVariables, f as flattenConnection, g as getPaginationInfo, e as getPaginationVariables } from './pagination-DCrQk02Q.js';
14
15
  export { MappedProductOptions, ProductLike, ProductOptionDef, ProductOptionState, ProductOptionValueState, SelectedOption, SelectedOptionsMap, VariantLike, VariantSelectionLike, getAdjacentAndFirstAvailableVariants, getProductOptions, getSelectedProductOptions, getSelectedVariant, mapSelectedProductOptionToObject, useOptimisticVariant, useSelectedOptionInUrlParam } from './product.js';
15
- export { ResolveThemeSettingsArgs, mergeSection, mergeSettings, resolveThemeSettings } from './settings.js';
16
- export { F as FetchThemeSettingsOptions, S as StoredThemeSettings, f as fetchThemeSettings } from './fetch-M3Y-fQrW.js';
16
+ export { ResolveThemeSettingsArgs, mergeSection, mergeSettings, reconcileSyntheticSectionGroup, resolveThemeSettings } from './settings.js';
17
+ export { F as FetchThemeSettingsOptions, S as StoredThemeSettings, f as fetchThemeSettings } from './fetch-Bq_cc8_G.js';
17
18
  export { AddressInput, BreadcrumbItem, ChangeFreq, GeoInput, LocalBusinessInput, OfferInput, OrganizationInput, ProductJsonLdInput, RedirectLookup, RedirectOptions, RobotsOptions, SitemapEntry, SitemapIndexEntry, StorefrontRedirectOptions, URL_REDIRECT_QUERY, WebSiteInput, breadcrumbListJsonLd, buildRobotsTxt, buildSitemapIndexXml, buildSitemapXml, getSeoMeta, localBusinessJsonLd, organizationJsonLd, productJsonLd, resolveRedirect, resolveStorefrontRedirect, restaurantJsonLd, robotsResponse, serializeJsonLd, sitemapIndexResponse, sitemapResponse, storefrontRedirect, websiteJsonLd } from './seo.js';
18
- export { A as Alternate, J as JsonLd, O as OpenGraph, a as OpenGraphImage, S as SeoConfig, b as SeoDescriptor, T as TwitterCard } from './types-BDhHWZsP.js';
19
+ export { A as Alternate, J as JsonLd, O as OpenGraph, a as OpenGraphImage, S as SeoConfig, b as SeoDescriptor, T as TwitterCard } from './types-BkY0yET-.js';
19
20
  export { c as FormAnswer, a as FormAnswers, d as FormBlock, e as FormField, b as FormFieldErrors, f as FormLocalizedText, g as FormRenderState, h as FormSubmission, F as FormVersionSchema, i as FormVisibilityRule, P as PublicForm, j as PublicFormDefinition, k as PublicFormVersion } from './types-CSNXbGFW.js';
20
21
  export { ADDRESS_PROPERTIES, FORM_ANSWER_PREFIX, FormFetchOptions, RenderFormHtmlOptions, ShopifyContactCompatibility, ShopifyContactInput, StorefrontFormRequestError, SubmitFormInput, adaptShopifyContactForm, evaluateFormRule, formAnswerName, formFields, isFormFieldVisible, loadPublishedForm, parseFormAnswers, renderFormHtml, resolveFormText, submitPublishedForm } from './forms.js';
21
22
  export { EventCartPreparationError, eventCartToken, prepareEventCart } from './events.js';
22
- export { C as ClaimEventApprovalOffer, d as CreateEventApprovalRequest, e as CreateEventCheckoutSession, f as CreateEventWaitlistEntry, b as EventApprovalOfferResolution, g as EventApprovalRequestReceipt, a as EventCheckoutSession, h as EventFormAnswer, i as EventFormSubmissionInput, j as EventRegistrationMode, k as EventRegistrationResult, c as EventRegistrationSubmission, l as EventWaitlistReceipt, E as EventsClient, P as PublicEvent, m as PublicEventForm, n as PublicEventOccurrence, o as PublicEventTicketType, p as PublicEventVenue, S as StorefrontEventsRequestError, q as createEventsClient } from './client-bsiNPHBi.js';
23
+ export { C as ClaimEventApprovalOffer, d as CreateEventApprovalRequest, e as CreateEventCheckoutSession, f as CreateEventWaitlistEntry, b as EventApprovalOfferResolution, g as EventApprovalRequestReceipt, a as EventCheckoutSession, h as EventFormAnswer, i as EventFormSubmissionInput, j as EventRegistrationMode, k as EventRegistrationResult, c as EventRegistrationSubmission, l as EventWaitlistReceipt, E as EventsClient, P as PublicEvent, m as PublicEventForm, n as PublicEventOccurrence, o as PublicEventSummary, p as PublicEventTicketType, q as PublicEventVenue, S as StorefrontEventsRequestError, r as createEventsClient } from './client-CwOPPpFF.js';
23
24
  export { a as OfferTokenHistory, O as OfferTokenLocation, c as consumeOfferTokenFragment, o as offerTokenHrefMarker } from './offer-token-C-nk_nj8.js';
24
- export { CreateStorefrontEditorBridgeArgs, CreateStorefrontEditorHostBridgeArgs, StorefrontEditorBlockSchema, StorefrontEditorBridge, StorefrontEditorHostBridge, StorefrontEditorMessageEvent, StorefrontEditorMessageSource, StorefrontEditorMessageTarget, StorefrontEditorReady, StorefrontEditorSectionPreset, StorefrontEditorSectionPresetBlock, StorefrontEditorSectionSchema, StorefrontEditorSelection, StorefrontEditorSettingInput, StorefrontEditorSettingOption, createStorefrontEditorBridge, createStorefrontEditorHostBridge } from './editor.js';
25
+ export { C as CreateStorefrontEditorBridgeArgs, b as CreateStorefrontEditorHostBridgeArgs, c as StorefrontEditorAppExtensionPreview, d as StorefrontEditorBlockSchema, e as StorefrontEditorBridge, f as StorefrontEditorCanvasAction, g as StorefrontEditorCanvasBlockAction, h as StorefrontEditorCanvasPosition, i as StorefrontEditorCanvasSectionAction, j as StorefrontEditorDocument, k as StorefrontEditorHostBridge, l as StorefrontEditorMessageEvent, S as StorefrontEditorMessageSource, a as StorefrontEditorMessageTarget, m as StorefrontEditorNavigationRequest, n as StorefrontEditorReady, o as StorefrontEditorRect, p as StorefrontEditorSectionPreset, q as StorefrontEditorSectionPresetBlock, r as StorefrontEditorSectionSchema, s as StorefrontEditorSelection, t as StorefrontEditorSelectionScope, u as StorefrontEditorSettingInput, v as StorefrontEditorSettingOption, w as StorefrontEditorThemeStyle, y as createStorefrontEditorBridge, z as createStorefrontEditorHostBridge, A as positionStorefrontEditorCanvasToolbar } from './bridge-CfNBWu0H.js';
26
+ export { S as STOREFRONT_SECTION_CUSTOM_CSS_SETTING, s as scopeStorefrontSectionCss } from './custom-css-Bl7Ur3-H.js';
25
27
  import './http-types-CGh8WGHB.js';
26
28
  import 'react';
27
29
  import './storefront-api-types.js';
@@ -30,6 +32,7 @@ import '@kotao/storefront-contracts/theme';
30
32
  declare const CART_ID_COOKIE = "kotao_cart";
31
33
  declare function readCartIdCookie(cookieHeader: string | null | undefined): string | null;
32
34
  declare function buildCartIdCookie(cartId: string): string;
35
+ declare function clearCartIdCookie(): string;
33
36
 
34
37
  declare function applyOptimisticCartAction(cart: Cart, action: CartDispatchAction): Cart;
35
38
  /**
@@ -66,41 +69,50 @@ interface CheckoutDesignTokens {
66
69
  readonly heading: string;
67
70
  };
68
71
  }
69
- declare const CHECKOUT_DESIGN_TOKEN_INPUTS: readonly [{
70
- readonly type: "url";
71
- readonly name: "checkoutLogoUrl";
72
- readonly label: "Checkout logo URL";
73
- }, {
74
- readonly type: "text";
75
- readonly name: "checkoutLogoAlt";
76
- readonly label: "Checkout logo alt text";
77
- readonly defaultValue: "";
78
- }, {
79
- readonly type: "color";
80
- readonly name: "checkoutColorAccent";
81
- readonly label: "Checkout accent color";
82
- readonly defaultValue: "#005bd3";
83
- }, {
84
- readonly type: "color";
85
- readonly name: "checkoutColorBackground";
86
- readonly label: "Checkout background color";
87
- readonly defaultValue: "#ffffff";
88
- }, {
89
- readonly type: "color";
90
- readonly name: "checkoutColorForeground";
91
- readonly label: "Checkout foreground color";
92
- readonly defaultValue: "#111827";
93
- }, {
94
- readonly type: "font";
95
- readonly name: "checkoutFontBody";
96
- readonly label: "Checkout body font";
97
- readonly defaultValue: "Inter";
98
- }, {
99
- readonly type: "font";
100
- readonly name: "checkoutFontHeading";
101
- readonly label: "Checkout heading font";
102
- readonly defaultValue: "Inter";
103
- }];
72
+ declare const CHECKOUT_DESIGN_TOKEN_INPUTS: ({
73
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
74
+ type: "url";
75
+ name: "checkoutLogoUrl";
76
+ label: "Logo URL";
77
+ group: "Account & checkout";
78
+ helpText: "Overrides the storefront logo on customer account and checkout pages.";
79
+ } | {
80
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
81
+ type: "text";
82
+ name: "checkoutLogoAlt";
83
+ label: "Logo alternative text";
84
+ group: "Account & checkout";
85
+ } | {
86
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
87
+ type: "color";
88
+ name: "checkoutColorAccent";
89
+ label: "Primary color";
90
+ group: "Account & checkout";
91
+ } | {
92
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
93
+ type: "color";
94
+ name: "checkoutColorBackground";
95
+ label: "Background color";
96
+ group: "Account & checkout";
97
+ } | {
98
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
99
+ type: "color";
100
+ name: "checkoutColorForeground";
101
+ label: "Text color";
102
+ group: "Account & checkout";
103
+ } | {
104
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
105
+ type: "font";
106
+ name: "checkoutFontBody";
107
+ label: "Body font";
108
+ group: "Account & checkout";
109
+ } | {
110
+ defaultValue?: "" | "#005bd3" | "#ffffff" | "#111827" | "Inter";
111
+ type: "font";
112
+ name: "checkoutFontHeading";
113
+ label: "Heading font";
114
+ group: "Account & checkout";
115
+ })[];
104
116
  declare function extractCheckoutDesignTokens(snapshot: Pick<ThemeSettingsSnapshot, 'global'>): CheckoutDesignTokens;
105
117
 
106
118
  interface ContentSecurityPolicyShop {
@@ -133,6 +145,18 @@ declare function buildLocalizationCookie(sel: {
133
145
 
134
146
  declare function handleLocalizationPost(request: Request): Promise<Response>;
135
147
 
148
+ interface AnalyticsAttributionEnvironment {
149
+ readonly referrer?: string;
150
+ readonly search?: string;
151
+ readonly matchMedia?: (query: string) => {
152
+ readonly matches: boolean;
153
+ };
154
+ }
155
+ type AttributionContext = Pick<AnalyticsContext, 'referrer' | 'utmSource' | 'utmMedium' | 'utmCampaign' | 'deviceClass'>;
156
+ /** Read static landing attribution plus the current responsive device class without retaining state
157
+ * or identifiers. All values stay optional so non-DOM/SSR emitters keep their existing payload. */
158
+ declare function collectAnalyticsAttribution(environment: AnalyticsAttributionEnvironment | null): AttributionContext;
159
+
136
160
  declare function encodeConsent(state: ConsentState): URLSearchParams;
137
161
  declare function decodeConsent(params: URLSearchParams): ConsentState;
138
162
  declare function appendConsentToCheckoutUrl(checkoutUrl: string, state: ConsentState): string;
@@ -243,4 +267,4 @@ interface HostedLocaleInput {
243
267
  */
244
268
  declare function resolveHostedLocale(input: HostedLocaleInput): string;
245
269
 
246
- export { CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, Cart, CartDispatchAction, type CheckoutDesignTokens, ConsentBucket, ConsentState, type ContentSecurityPolicyResult, type ContentSecurityPolicyShop, type CreateContentSecurityPolicyOptions, CustomerAccountClient, type CustomerAccountClientOptions, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, type HostedLocaleInput, type HostedSessionCookieAttrs, LOCALIZATION_COOKIE, type LegacySessionReadOptions, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, type ResolveCheckoutUrlOptions, ResolvedSettings, type SessionCookieAttrs, ThemeSettingsSnapshot, appendConsentToCheckoutUrl, applyOptimisticCartAction, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, createContentSecurityPolicy, createCustomerAccountClient, decodeCheckoutConsent, decodeConsent, encodeCheckoutConsent, encodeConsent, escapeHostedHtml, extractCheckoutDesignTokens, handleLocalizationPost, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, resolveHostedBranding, resolveHostedLocale, sanitizeHostedCssValue, shopHostname, useOptimisticCart };
270
+ export { type AnalyticsAttributionEnvironment, AnalyticsContext, CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, Cart, CartDispatchAction, type CheckoutDesignTokens, ConsentBucket, ConsentState, type ContentSecurityPolicyResult, type ContentSecurityPolicyShop, type CreateContentSecurityPolicyOptions, CustomerAccountClient, type CustomerAccountClientOptions, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, type HostedLocaleInput, type HostedSessionCookieAttrs, LOCALIZATION_COOKIE, type LegacySessionReadOptions, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, type ResolveCheckoutUrlOptions, ResolvedSettings, type SessionCookieAttrs, ThemeSettingsSnapshot, appendConsentToCheckoutUrl, applyOptimisticCartAction, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, clearCartIdCookie, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, collectAnalyticsAttribution, createContentSecurityPolicy, createCustomerAccountClient, decodeCheckoutConsent, decodeConsent, encodeCheckoutConsent, encodeConsent, escapeHostedHtml, extractCheckoutDesignTokens, handleLocalizationPost, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, resolveHostedBranding, resolveHostedLocale, sanitizeHostedCssValue, shopHostname, useOptimisticCart };
package/dist/index.js CHANGED
@@ -1,21 +1,24 @@
1
1
  export { getAdjacentAndFirstAvailableVariants, getProductOptions, getSelectedProductOptions, getSelectedVariant, mapSelectedProductOptionToObject, useOptimisticVariant, useSelectedOptionInUrlParam } from './chunk-QOEEUTHQ.js';
2
- import { createNonceProvider } from './chunk-XMTWFJCZ.js';
3
- export { CartForm, createAnalyticsBus, createAnalyticsEmitter, createPixelTransport } from './chunk-XMTWFJCZ.js';
2
+ import { createNonceProvider } from './chunk-RFM27BKZ.js';
3
+ export { CartForm, collectAnalyticsAttribution, createAnalyticsBus, createAnalyticsEmitter, createPixelTransport } from './chunk-RFM27BKZ.js';
4
4
  export { flattenConnection, getPaginationInfo, getPaginationVariables } from './chunk-5QOFKGKD.js';
5
- import { CHECKOUT_DESIGN_TOKEN_INPUTS, localizePath, buildLocalizationCookie, extractCheckoutDesignTokens, readLocalizationCookie } from './chunk-GGOZELAA.js';
6
- export { CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, CacheCustom, CacheLong, CacheNone, CacheShort, CustomerAccountError, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, GEO_HEADER, GEO_SIGNATURE_HEADER, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, LOCALIZATION_COOKIE, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, ROUTING_LOCALE_HEADER, ROUTING_ORIGINAL_PATHNAME_HEADER, StorefrontDefaultCache, StorefrontQueryTimeoutError, StorefrontUpstreamError, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, cartGetIdDefault, cartSetIdDefault, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, createCache, createCartHandler, createCustomerAccountClient, createKotaoContext, createStorefrontClient, createWithCache, decodeCheckoutConsent, encodeCheckoutConsent, extractCheckoutDesignTokens, generateCacheControlHeader, isLocalePathSegment, localeFromAcceptLanguage, localeFromPathname, localeFromRequest, localizePath, originalPathnameFromRequest, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, shopHostname, signGeo, stripLocalePrefixFromPathname, stripLocalePrefixFromRequest, trustedShopOriginFromHeaders, verifyGeo } from './chunk-GGOZELAA.js';
5
+ import { CHECKOUT_DESIGN_TOKEN_INPUTS, localizePath, buildLocalizationCookie, extractCheckoutDesignTokens, readLocalizationCookie } from './chunk-DTKLAOKR.js';
6
+ export { CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, CacheCustom, CacheLong, CacheNone, CacheShort, CustomerAccountError, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, GEO_HEADER, GEO_SIGNATURE_HEADER, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, LOCALIZATION_COOKIE, MARKET_ALTERNATE_LOCALES_HEADER, MARKET_CANONICAL_URL_HEADER, MARKET_DEFAULT_LOCALE_HEADER, MARKET_ID_HEADER, MARKET_PATH_PREFIX_HEADER, MARKET_ROOT_URLS_HEADER, MARKET_SETTINGS_ENVIRONMENT_HEADER, MARKET_THEME_ID_HEADER, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, ROUTING_LOCALE_HEADER, ROUTING_ORIGINAL_PATHNAME_HEADER, StorefrontDefaultCache, StorefrontQueryTimeoutError, StorefrontUpstreamError, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, cartGetIdDefault, cartSetIdDefault, clearCartIdCookie, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, createCache, createCartHandler, createCustomerAccountClient, createKotaoContext, createStorefrontClient, createWithCache, decodeCheckoutConsent, encodeCheckoutConsent, extractCheckoutDesignTokens, generateCacheControlHeader, isLocalePathSegment, localeFromAcceptLanguage, localeFromPathname, localeFromRequest, localizePath, marketContextFromHeaders, originalPathnameFromRequest, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, shopHostname, signGeo, stripLocalePrefixFromPathname, stripLocalePrefixFromRequest, trustedShopOriginFromHeaders, verifyGeo } from './chunk-DTKLAOKR.js';
7
7
  import { CART_FORM_ACTIONS, CONSENT_BUCKETS } from './chunk-OGWYTYYS.js';
8
8
  export { CART_FORM_ACTIONS, CONSENT_BUCKETS, CONSENT_COOKIE, DENIED_CONSENT, GRANTED_CONSENT, buildConsentCookie, isGranted, mergeConsent, parseConsent, readConsentCookie, serializeConsent } from './chunk-OGWYTYYS.js';
9
- export { URL_REDIRECT_QUERY, breadcrumbListJsonLd, buildRobotsTxt, buildSitemapIndexXml, buildSitemapXml, localBusinessJsonLd, organizationJsonLd, productJsonLd, resolveRedirect, resolveStorefrontRedirect, restaurantJsonLd, robotsResponse, sitemapIndexResponse, sitemapResponse, storefrontRedirect, websiteJsonLd } from './chunk-PXVDVUFX.js';
10
- export { getSeoMeta, serializeJsonLd } from './chunk-MYDKIJRH.js';
11
- export { createThemeSettingsStore, mergeSection, mergeSettings, resolveThemeSettings } from './chunk-H3D7BAOL.js';
12
- export { fetchThemeSettings } from './chunk-M7BPQ54D.js';
13
- export { createStorefrontEditorBridge, createStorefrontEditorHostBridge } from './chunk-PXZ737N3.js';
9
+ export { URL_REDIRECT_QUERY, breadcrumbListJsonLd, buildRobotsTxt, buildSitemapIndexXml, buildSitemapXml, localBusinessJsonLd, organizationJsonLd, productJsonLd, resolveRedirect, resolveStorefrontRedirect, restaurantJsonLd, robotsResponse, sitemapIndexResponse, sitemapResponse, storefrontRedirect, websiteJsonLd } from './chunk-W74FGUZH.js';
10
+ export { getSeoMeta, serializeJsonLd } from './chunk-SVMYFYIA.js';
11
+ export { createThemeSettingsStore, mergeSection, mergeSettings, reconcileSyntheticSectionGroup, resolveThemeSettings } from './chunk-VOTBNOWH.js';
12
+ export { fetchThemeSettings } from './chunk-2MRB6SMP.js';
13
+ export { STOREFRONT_SECTION_CUSTOM_CSS_SETTING, createStorefrontEditorBridge, createStorefrontEditorHostBridge, positionStorefrontEditorCanvasToolbar, scopeStorefrontSectionCss } from './chunk-RFKLO6TD.js';
14
+ import './chunk-CKGI3Y7L.js';
14
15
  export { EventCartPreparationError, eventCartToken, prepareEventCart } from './chunk-4OQYNUGM.js';
15
16
  export { consumeOfferTokenFragment, offerTokenHrefMarker } from './chunk-WG7HYVHJ.js';
16
- export { StorefrontEventsRequestError, createEventsClient } from './chunk-MCIFKJQK.js';
17
+ export { StorefrontEventsRequestError, createEventsClient } from './chunk-R4N565GX.js';
17
18
  export { ADDRESS_PROPERTIES, FORM_ANSWER_PREFIX, StorefrontFormRequestError, adaptShopifyContactForm, evaluateFormRule, formAnswerName, formFields, isFormFieldVisible, loadPublishedForm, parseFormAnswers, renderFormHtml, resolveFormText, submitPublishedForm } from './chunk-IIOHENCG.js';
18
19
  export { buildImageAttrs, imageSrcSet, imageUrl } from './chunk-3YQXJNR7.js';
20
+ import { MARKET_PATH_PREFIX_HEADER } from '@kotao/storefront-contracts';
21
+ export { AUTO_REDIRECT_LANGUAGE_HEADER, autoRedirectEnabled } from '@kotao/storefront-contracts';
19
22
 
20
23
  // src/cart/useOptimisticCart.ts
21
24
  var recalculate = (cart, lines) => ({
@@ -139,19 +142,20 @@ function normalizeSources(sources) {
139
142
  function uniqueSources(sources) {
140
143
  return Array.from(new Set(sources.filter((source) => source.length > 0)));
141
144
  }
142
-
143
- // src/localization/handler.ts
144
145
  function safeReturnTo(raw) {
145
146
  if (raw === null || raw === "") return { path: "/", safe: true };
146
147
  return /^\/(?![/\\])/.test(raw) ? { path: raw, safe: true } : { path: "/", safe: false };
147
148
  }
148
149
  async function handleLocalizationPost(request) {
149
150
  const form = await request.formData();
150
- const country = (form.get("country_code") ?? "").toString().trim().toUpperCase() || null;
151
- const locale = (form.get("locale_code") ?? "").toString().trim() || null;
151
+ const country = (form.getAll("country_code").at(-1) ?? "").toString().trim().toUpperCase() || null;
152
+ const locale = (form.getAll("locale_code").at(-1) ?? "").toString().trim() || null;
152
153
  const primaryLocale = (form.get("primary_locale") ?? "").toString().trim() || null;
153
154
  const returnTo = safeReturnTo((form.get("return_to") ?? "").toString());
154
- const location = returnTo.safe && primaryLocale !== null ? localizePath(returnTo.path, locale, { primaryLocale }) : returnTo.path;
155
+ const location = returnTo.safe && primaryLocale !== null ? localizePath(returnTo.path, locale, {
156
+ primaryLocale,
157
+ marketPathPrefix: request.headers.get(MARKET_PATH_PREFIX_HEADER)
158
+ }) : returnTo.path;
155
159
  return new Response(null, {
156
160
  status: 302,
157
161
  headers: { location, "set-cookie": buildLocalizationCookie({ country, locale }) }
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":";;;;;;;;;;;;;;;;;;;;AAIA,IAAM,WAAA,GAAc,CAAC,IAAA,EAAY,KAAA,MAAsC;AAAA,EACrE,GAAG,IAAA;AAAA,EACH,KAAA;AAAA,EACA,aAAA,EAAe,MAAM,MAAA,CAAO,CAAC,KAAK,IAAA,KAAS,GAAA,GAAM,IAAA,CAAK,QAAA,EAAU,CAAC;AACnE,CAAA,CAAA;AAEO,SAAS,yBAAA,CAA0B,MAAY,MAAA,EAAkC;AACtF,EAAA,QAAQ,OAAO,MAAA;AAAQ,IACrB,KAAK,kBAAkB,QAAA,EAAU;AAC/B,MAAA,MAAM,UAAA,GAAc,MAAA,CAAO,MAAA,CAAO,KAAA,IAAS,EAAC;AAI5C,MAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAc,CAAC,IAAA,MAAU;AAAA,QACpD,EAAA,EAAI,CAAA,WAAA,EAAc,IAAA,CAAK,aAAa,CAAA,CAAA;AAAA,QACpC,QAAA,EAAU,KAAK,QAAA,IAAY,CAAA;AAAA,QAC3B,WAAA,EAAa,EAAE,EAAA,EAAI,IAAA,CAAK,aAAA,EAAc;AAAA,QACtC,YAAY;AAAC,OACf,CAAE,CAAA;AACF,MAAA,OAAO,WAAA,CAAY,MAAM,CAAC,GAAG,KAAK,KAAA,EAAO,GAAG,SAAS,CAAC,CAAA;AAAA,IACxD;AAAA,IACA,KAAK,kBAAkB,WAAA,EAAa;AAClC,MAAA,MAAM,UAAU,IAAI,GAAA;AAAA,QAAA,CAChB,MAAA,CAAO,MAAA,CAAO,KAAA,IAAS,EAAC,EAAuD,GAAA;AAAA,UAC/E,CAAC,IAAA,KAAS,CAAC,IAAA,CAAK,IAAI,IAAI;AAAA;AAC1B,OACF;AACA,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAChB,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAClC,QAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,QAAA,IAAI,MAAA,CAAO,QAAA,KAAa,CAAA,EAAG,OAAO,IAAA;AAClC,QAAA,OAAO;AAAA,UACL,GAAG,IAAA;AAAA,UACH,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,IAAA,CAAK;AAAA,SACpC;AAAA,MACF,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,IAAA,KAA2B,SAAS,IAAI,CAAA;AACnD,MAAA,OAAO,WAAA,CAAY,MAAM,KAAK,CAAA;AAAA,IAChC;AAAA,IACA,KAAK,kBAAkB,WAAA,EAAa;AAClC,MAAA,MAAM,SAAS,IAAI,GAAA,CAAK,OAAO,MAAA,CAAO,OAAA,IAAW,EAAe,CAAA;AAChE,MAAA,OAAO,WAAA;AAAA,QACL,IAAA;AAAA,QACA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC;AAAA,OAClD;AAAA,IACF;AAAA,IACA;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAMO,SAAS,iBAAA,CAAkB,MAAY,MAAA,EAAyC;AACrF,EAAA,OAAO,MAAA,GAAS,yBAAA,CAA0B,IAAA,EAAM,MAAM,CAAA,GAAI,IAAA;AAC5D;;;ACzCA,IAAM,aAAA,uBAAoB,GAAA,CAAI;AAAA,EAC5B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEM,SAAS,2BAAA,CACd,OAAA,GAA8C,EAAC,EAClB;AAC7B,EAAA,MAAM,QAAQ,WAAA,EAAY;AAC1B,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAA;AAC5C,EAAA,MAAM,YAAY,aAAA,CAAc;AAAA,IAC9B,GAAG,gBAAA,CAAiB,OAAA,CAAQ,SAAA,IAAa,CAAC,MAAM,CAAC,CAAA;AAAA,IACjD,UAAU,KAAK,CAAA,CAAA;AAAA,GAChB,CAAA;AACD,EAAA,MAAM,aAAa,aAAA,CAAc;AAAA,IAC/B,MAAA;AAAA,IACA,GAAG,WAAA;AAAA,IACH,GAAG,gBAAA,CAAiB,OAAA,CAAQ,UAAU;AAAA,GACvC,CAAA;AACD,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,MAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG,WAAA;AAAA,IACH,GAAG,gBAAA,CAAiB,OAAA,CAAQ,MAAM;AAAA,GACnC,CAAA;AACD,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,CAAC,MAAA,EAAQ,eAAA,EAAiB,GAAG,gBAAA,CAAiB,OAAA,CAAQ,QAAQ,CAAC,CAAC,CAAA;AAC/F,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,CAAC,UAAA,EAAY,CAAC,QAAQ,CAAC,CAAA;AAAA,IACvB,CAAC,aAAA,EAAe,CAAC,QAAQ,CAAC,CAAA;AAAA,IAC1B,CAAC,eAAe,UAAU,CAAA;AAAA,IAC1B,CAAC,WAAW,MAAM,CAAA;AAAA,IAClB,CAAC,cAAc,SAAS,CAAA;AAAA,IACxB,CAAC,aAAa,QAAQ;AAAA,GACxB;AACA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,QAAQ,UAAA,CACL,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,MAAM,CAAA,KAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAK,OAA6B,IAAA,CAAK,GAAG,CAAC,CAAA,CAAE,CAAA,CAC5E,KAAK,IAAI,CAAA;AAAA,IACZ,aAAA,EAAe,oBAAoB,KAAK;AAAA,GAC1C;AACF;AAEA,SAAS,WAAA,GAAsB;AAC7B,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAM,gBAAiB,UAAA,CAAuD,MAAA;AAC9E,EAAA,IAAI,aAAA,EAAe,oBAAoB,MAAA,EAAW;AAChD,IAAA,aAAA,CAAc,gBAAgB,KAAK,CAAA;AAAA,EACrC,CAAA,MAAO;AACL,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA,EAAG;AACxC,MAAA,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,KAAW,GAAG,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,CAAC,SAAS,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAChF;AAEA,SAAS,YAAY,IAAA,EAAgE;AACnF,EAAA,IAAI,IAAA,KAAS,MAAA,EAAW,OAAO,EAAC;AAChC,EAAA,OAAO,CAAC,IAAA,CAAK,WAAA,EAAa,KAAK,cAAc,CAAA,CAC1C,OAAO,CAAC,MAAA,KAA6B,MAAA,KAAW,MAAA,IAAa,OAAO,IAAA,EAAK,KAAM,EAAE,CAAA,CACjF,GAAA,CAAI,CAAC,MAAA,KAAW;AACf,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,IAAA,OAAO,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA,GAAI,IAAI,IAAI,OAAO,CAAA,CAAE,MAAA,GAAS,CAAA,QAAA,EAAW,OAAO,CAAA,CAAA;AAAA,EACrF,CAAC,CAAA;AACL;AAEA,SAAS,iBAAiB,OAAA,EAA2D;AACnF,EAAA,OAAA,CAAQ,OAAA,IAAW,EAAC,EAAG,GAAA,CAAI,CAAC,MAAA,KAAW;AACrC,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,IAAA,OAAO,cAAc,GAAA,CAAI,OAAO,CAAA,GAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAA,GAAM,OAAA;AAAA,EACvD,CAAC,CAAA;AACH;AAEA,SAAS,cAAc,OAAA,EAA+C;AACpE,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,MAAA,CAAO,MAAA,GAAS,CAAC,CAAC,CAAC,CAAA;AAC1E;;;AClGA,SAAS,aAAa,GAAA,EAAqD;AACzE,EAAA,IAAI,GAAA,KAAQ,QAAQ,GAAA,KAAQ,EAAA,SAAW,EAAE,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,IAAA,EAAK;AAC/D,EAAA,OAAO,cAAA,CAAe,IAAA,CAAK,GAAG,CAAA,GAAI,EAAE,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,IAAA,EAAK,GAAI,EAAE,IAAA,EAAM,GAAA,EAAK,MAAM,KAAA,EAAM;AACzF;AAEA,eAAsB,uBAAuB,OAAA,EAAqC;AAChF,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,QAAA,EAAS;AACpC,EAAA,MAAM,OAAA,GAAA,CAAW,IAAA,CAAK,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,CAAE,WAAA,EAAY,IAAK,IAAA;AACpF,EAAA,MAAM,MAAA,GAAA,CAAU,KAAK,GAAA,CAAI,aAAa,KAAK,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,IAAA;AACpE,EAAA,MAAM,aAAA,GAAA,CAAiB,KAAK,GAAA,CAAI,gBAAgB,KAAK,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,IAAA;AAC9E,EAAA,MAAM,QAAA,GAAW,cAAc,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA,IAAK,EAAA,EAAI,UAAU,CAAA;AACtE,EAAA,MAAM,QAAA,GACJ,QAAA,CAAS,IAAA,IAAQ,aAAA,KAAkB,IAAA,GAC/B,YAAA,CAAa,QAAA,CAAS,IAAA,EAAM,MAAA,EAAQ,EAAE,aAAA,EAAe,IACrD,QAAA,CAAS,IAAA;AACf,EAAA,OAAO,IAAI,SAAS,IAAA,EAAM;AAAA,IACxB,MAAA,EAAQ,GAAA;AAAA,IACR,OAAA,EAAS,EAAE,QAAA,EAAU,YAAA,EAAc,wBAAwB,EAAE,OAAA,EAAS,MAAA,EAAQ,CAAA;AAAE,GACjF,CAAA;AACH;;;ACTO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,UAAA,EAAY,aAAA;AAAA,EACZ,aAAA,EAAe,gBAAA;AAAA,EACf,gBAAA,EAAkB,mBAAA;AAAA,EAClB,UAAA,EAAY,aAAA;AAAA,EACZ,YAAA,EAAc,eAAA;AAAA,EACd,kBAAA,EAAoB;AACtB;;;ACFO,SAAS,iBAAiB,OAAA,EAAiD;AAChF,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,QAAA,IAAY,IAAA;AACvD,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,OAAA,IAAW,IAAA;AACrD,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,QAAA,IAAY,IAAA;AACvD,EAAA,MAAM,gBAAA,GACJ,QAAA,IAAY,IAAA,IAAQ,OAAA,IAAW,IAAA,GAAO,GAAG,QAAQ,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAM,QAAA,IAAY,OAAA;AAEhF,EAAA,OAAO;AAAA,IACL,GAAI,gBAAA,IAAoB,IAAA,GAAO,EAAE,gBAAA,KAAqB,EAAC;AAAA,IACvD,GAAI,QAAA,IAAY,IAAA,GAAO,EAAE,QAAA,KAAa,EAAC;AAAA,IACvC,GAAI,QAAQ,kBAAA,IAAsB,IAAA,GAAO,EAAE,MAAA,EAAQ,OAAA,CAAQ,kBAAA,EAAmB,GAAI,EAAC;AAAA,IACnF,GAAI,QAAQ,kBAAA,IAAsB,IAAA,GAAO,EAAE,YAAA,EAAc,OAAA,CAAQ,kBAAA,EAAmB,GAAI;AAAC,GAC3F;AACF;;;ACxBA,IAAM,YAAA,GAAe,UAAA;AACrB,IAAM,aAAA,GAAgB,uBAAA;AAEf,SAAS,cAAc,KAAA,EAAsC;AAClE,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,EAAA,KAAA,MAAW,MAAA,IAAU,eAAA;AACnB,IAAA,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,YAAY,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,MAAM,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA;AAClE,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,cAAc,MAAA,EAAuC;AACnE,EAAA,MAAM,IAAA,GAAO,CAAC,MAAA,KAAmC,MAAA,CAAO,GAAA,CAAI,GAAG,YAAY,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA,KAAM,GAAA;AAC5F,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,IAC3B,SAAA,EAAW,KAAK,WAAW,CAAA;AAAA,IAC3B,WAAA,EAAa,KAAK,aAAa;AAAA,GACjC;AACF;AAEO,SAAS,0BAAA,CAA2B,aAAqB,KAAA,EAA6B;AAG3F,EAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,WAAW,CAAA,EAAG;AAClC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+DAAA,EAAkE,WAAW,CAAA,CAAE,CAAA;AAAA,EACjG;AACA,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,WAAA,EAAa,aAAa,CAAA;AAC9C,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAChF,EAAA,OAAO,CAAA,EAAG,IAAI,QAAQ,CAAA,EAAG,IAAI,MAAM,CAAA,EAAG,IAAI,IAAI,CAAA,CAAA;AAChD;;;AC7BA,IAAM,0BAA4D,MAAA,CAAO,WAAA;AAAA,EACvE,4BAAA,CAA6B,OAAA;AAAA,IAAQ,CAAC,KAAA,KACpC,cAAA,IAAkB,SAAS,OAAO,KAAA,CAAM,iBAAiB,QAAA,IAAY,KAAA,CAAM,iBAAiB,EAAA,GACxF,CAAC,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,YAAY,CAAC,IACjC;AAAC;AAET,CAAA;AAGO,SAAS,sBAAsB,MAAA,EAAgD;AACpF,EAAA,OAAO,2BAAA,CAA4B,EAAE,MAAA,EAAQ,EAAE,GAAG,uBAAA,EAAyB,GAAG,MAAA,EAAO,EAAG,CAAA;AAC1F;AAGO,SAAS,iBAAiB,KAAA,EAAuB;AACtD,EAAA,OAAO,MACJ,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CACrB,OAAA,CAAQ,MAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,EACpB,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,MAAM,OAAO,CAAA;AAC1B;AAOO,SAAS,uBAAuB,KAAA,EAAuB;AAC5D,EAAA,OAAO,KAAA,CACJ,QAAQ,eAAA,EAAiB,EAAE,EAC3B,OAAA,CAAQ,YAAA,EAAc,GAAG,CAAA,CACzB,IAAA,EAAK;AACV;;;AC3BO,SAAS,oBAAoB,KAAA,EAAkC;AACpE,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,iBAAA,CAAkB,GAAA,CAAI,CAAC,MAAA,KAAW,MAAA,CAAO,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AACxF,EAAA,IAAI,WAAW,MAAA,KAAW,CAAA,EAAG,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAE1F,EAAA,MAAM,eAAA,GAAkB,IAAI,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAC,MAAA,KAAW,CAAC,SAAA,CAAU,MAAM,CAAA,EAAG,MAAM,CAAU,CAAC,CAAA;AAChG,EAAA,MAAM,YAAA,GAAe,sBAAA,CAAuB,KAAA,CAAM,kBAAkB,CAAA;AAEpE,EAAA,KAAA,MAAW,aAAa,CAAC,YAAA,EAAc,MAAM,cAAA,EAAgB,KAAA,CAAM,aAAa,CAAA,EAAG;AACjF,IAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,CAAU,IAAA,OAAW,EAAA,EAAI;AACnD,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,GAAA,CAAI,SAAA,CAAU,SAAS,CAAC,CAAA;AACtD,IAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAAA,EAClC;AAEA,EAAA,OAAO,WAAW,CAAC,CAAA;AACrB;AAEA,SAAS,UAAU,MAAA,EAAwB;AACzC,EAAA,OAAO,OAAO,IAAA,EAAK,CAAE,QAAQ,IAAA,EAAM,GAAG,EAAE,WAAA,EAAY;AACtD;AAEA,SAAS,uBAAuB,YAAA,EAA4C;AAC1E,EAAA,IAAI,YAAA,KAAiB,MAAM,OAAO,IAAA;AAClC,EAAA,IAAI,CAAC,aAAa,QAAA,CAAS,GAAG,GAAG,OAAO,YAAA,CAAa,MAAK,IAAK,IAAA;AAC/D,EAAA,IAAI;AACF,IAAA,OAAO,sBAAA,CAAuB,YAAY,CAAA,CAAE,MAAA;AAAA,EAC9C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","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,40 @@ 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
+ /**
47
+ * Structural reader shared by React Router's development and production declaration trees.
48
+ * React Router 8 publishes the provider class from both conditional entry points; their private
49
+ * fields make the two class types nominally incompatible even though the runtime API is identical.
50
+ */
51
+ interface KotaoRouterContextReader {
52
+ get<T>(context: {
53
+ readonly defaultValue?: T;
54
+ }): T;
55
+ }
56
+ declare function createKotaoRouterContext(context: KotaoContext): RouterContextProvider;
57
+ declare function getKotaoContext(context: KotaoRouterContextReader): KotaoContext;
28
58
  /**
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
59
+ * Build the Kotao storefront context for a React Router request. Wrap the result with
60
+ * `createKotaoRouterContext` before handing it to React Router 8. Isolated here so the SDK core
61
+ * stays framework-agnostic (a TanStack
31
62
  * Start binding can be added alongside without touching the core).
32
63
  */
33
64
  declare const getKotaoLoadContext: (request: Request, env: KotaoEnv, executionCtx: StorefrontExecutionContext, deps?: KotaoLoadContextDeps) => Promise<KotaoContext>;
34
65
 
35
- export { KotaoContext, KotaoEnv, defer, getKotaoLoadContext, json };
66
+ export { KotaoContext, KotaoEnv, createKotaoRouterContext, defer, getKotaoContext, getKotaoLoadContext, json, kotaoContext };
@@ -1,8 +1,10 @@
1
- import { createKotaoContext } from './chunk-GGOZELAA.js';
2
- export { stripLocalePrefixFromRequest } from './chunk-GGOZELAA.js';
1
+ import { createKotaoContext } from './chunk-DTKLAOKR.js';
2
+ export { stripLocalePrefixFromRequest } from './chunk-DTKLAOKR.js';
3
3
  import './chunk-OGWYTYYS.js';
4
- import './chunk-M7BPQ54D.js';
5
- import './chunk-MCIFKJQK.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;AAWrB,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,EAAiD;AAC/E,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\n/**\n * Structural reader shared by React Router's development and production declaration trees.\n * React Router 8 publishes the provider class from both conditional entry points; their private\n * fields make the two class types nominally incompatible even though the runtime API is identical.\n */\nexport interface KotaoRouterContextReader {\n get<T>(context: { readonly defaultValue?: T }): T\n}\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: KotaoRouterContextReader): 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"]}