@shopify/hydrogen 2025.10.0 → 2026.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/customer-account-api-types.d.ts +643 -8
- package/dist/customer-account.schema.json +1 -1
- package/dist/dev/{get-virtual-routes-ZEUPNZWL.js → get-virtual-routes-H72465VB.js} +8 -3
- package/dist/dev/hydrogen-routes.js +1 -1
- package/dist/development/{get-virtual-routes-XE7G57DS.js → get-virtual-routes-ACFZHU42.js} +10 -6
- package/dist/development/get-virtual-routes-ACFZHU42.js.map +1 -0
- package/dist/development/index.cjs +14 -9
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +7 -7
- package/dist/development/index.js.map +1 -1
- package/dist/production/get-virtual-routes-ZZEGQQDV.js +3 -0
- package/dist/production/get-virtual-routes-ZZEGQQDV.js.map +1 -0
- package/dist/production/index.cjs +47 -47
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.d.cts +7 -7
- package/dist/production/index.d.ts +7 -7
- package/dist/production/index.js +6 -6
- package/dist/production/index.js.map +1 -1
- package/dist/storefront-api-types.d.ts +48 -4
- package/dist/storefront.schema.json +1 -1
- package/dist/vite/get-virtual-routes.d.ts +6 -1
- package/dist/vite/get-virtual-routes.js +8 -3
- package/package.json +2 -2
- package/dist/development/get-virtual-routes-XE7G57DS.js.map +0 -1
- package/dist/production/get-virtual-routes-MYYLGSAS.js +0 -3
- package/dist/production/get-virtual-routes-MYYLGSAS.js.map +0 -1
|
@@ -1278,7 +1278,7 @@ type StorefrontQueryOptions = StorefrontCommonExtraParams & {
|
|
|
1278
1278
|
cache?: CachingStrategy;
|
|
1279
1279
|
};
|
|
1280
1280
|
/**
|
|
1281
|
-
* This function extends `createStorefrontClient` from [Hydrogen React](/docs/api/hydrogen-react/
|
|
1281
|
+
* This function extends `createStorefrontClient` from [Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient). The additional arguments enable internationalization (i18n), caching, and other features particular to Remix and Oxygen.
|
|
1282
1282
|
*
|
|
1283
1283
|
* Learn more about [data fetching in Hydrogen](/docs/custom-storefronts/hydrogen/data-fetching/fetch-data).
|
|
1284
1284
|
*/
|
|
@@ -1304,13 +1304,13 @@ type StorefrontForDoc<TI18n extends I18nBase = I18nBase> = {
|
|
|
1304
1304
|
CacheCustom?: typeof CacheCustom;
|
|
1305
1305
|
/** Re-export of [`generateCacheControlHeader`](/docs/api/hydrogen/utilities/generatecachecontrolheader). */
|
|
1306
1306
|
generateCacheControlHeader?: typeof generateCacheControlHeader;
|
|
1307
|
-
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1307
|
+
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=%27graphql%27.-,getPublicTokenHeaders,-(props%3F%3A) for more details. */
|
|
1308
1308
|
getPublicTokenHeaders?: ReturnType<typeof createStorefrontClient$1>['getPublicTokenHeaders'];
|
|
1309
|
-
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1309
|
+
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=storefrontApiVersion-,getPrivateTokenHeaders,-(props%3F%3A) for more details.*/
|
|
1310
1310
|
getPrivateTokenHeaders?: ReturnType<typeof createStorefrontClient$1>['getPrivateTokenHeaders'];
|
|
1311
|
-
/** Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1311
|
+
/** Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=StorefrontClientReturn-,getShopifyDomain,-(props%3F%3A) for more details. */
|
|
1312
1312
|
getShopifyDomain?: ReturnType<typeof createStorefrontClient$1>['getShopifyDomain'];
|
|
1313
|
-
/** Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1313
|
+
/** Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=storeDomain-,getStorefrontApiUrl,-(props%3F%3A) for more details.*/
|
|
1314
1314
|
getApiUrl?: ReturnType<typeof createStorefrontClient$1>['getStorefrontApiUrl'];
|
|
1315
1315
|
/** The `i18n` object passed in from the `createStorefrontClient` argument. */
|
|
1316
1316
|
i18n?: TI18n;
|
|
@@ -2439,9 +2439,9 @@ type VariantOptionValue = {
|
|
|
2439
2439
|
type VariantSelectorProps = {
|
|
2440
2440
|
/** The product handle for all of the variants */
|
|
2441
2441
|
handle: string;
|
|
2442
|
-
/** Product options from the [Storefront API](/docs/api/storefront/
|
|
2442
|
+
/** Product options from the [Storefront API](/docs/api/storefront/2026-01/objects/ProductOption). Make sure both `name` and `values` are a part of your query. */
|
|
2443
2443
|
options: Array<PartialProductOption> | undefined;
|
|
2444
|
-
/** Product variants from the [Storefront API](/docs/api/storefront/
|
|
2444
|
+
/** Product variants from the [Storefront API](/docs/api/storefront/2026-01/objects/ProductVariant). You only need to pass this prop if you want to show product availability. If a product option combination is not found within `variants`, it is assumed to be available. Make sure to include `availableForSale` and `selectedOptions.name` and `selectedOptions.value`. */
|
|
2445
2445
|
variants?: PartialDeep<ProductVariantConnection> | Array<PartialDeep<ProductVariant>>;
|
|
2446
2446
|
/** By default all products are under /products. Use this prop to provide a custom path. */
|
|
2447
2447
|
productPath?: string;
|
|
@@ -1278,7 +1278,7 @@ type StorefrontQueryOptions = StorefrontCommonExtraParams & {
|
|
|
1278
1278
|
cache?: CachingStrategy;
|
|
1279
1279
|
};
|
|
1280
1280
|
/**
|
|
1281
|
-
* This function extends `createStorefrontClient` from [Hydrogen React](/docs/api/hydrogen-react/
|
|
1281
|
+
* This function extends `createStorefrontClient` from [Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient). The additional arguments enable internationalization (i18n), caching, and other features particular to Remix and Oxygen.
|
|
1282
1282
|
*
|
|
1283
1283
|
* Learn more about [data fetching in Hydrogen](/docs/custom-storefronts/hydrogen/data-fetching/fetch-data).
|
|
1284
1284
|
*/
|
|
@@ -1304,13 +1304,13 @@ type StorefrontForDoc<TI18n extends I18nBase = I18nBase> = {
|
|
|
1304
1304
|
CacheCustom?: typeof CacheCustom;
|
|
1305
1305
|
/** Re-export of [`generateCacheControlHeader`](/docs/api/hydrogen/utilities/generatecachecontrolheader). */
|
|
1306
1306
|
generateCacheControlHeader?: typeof generateCacheControlHeader;
|
|
1307
|
-
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1307
|
+
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=%27graphql%27.-,getPublicTokenHeaders,-(props%3F%3A) for more details. */
|
|
1308
1308
|
getPublicTokenHeaders?: ReturnType<typeof createStorefrontClient$1>['getPublicTokenHeaders'];
|
|
1309
|
-
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1309
|
+
/** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=storefrontApiVersion-,getPrivateTokenHeaders,-(props%3F%3A) for more details.*/
|
|
1310
1310
|
getPrivateTokenHeaders?: ReturnType<typeof createStorefrontClient$1>['getPrivateTokenHeaders'];
|
|
1311
|
-
/** Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1311
|
+
/** Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=StorefrontClientReturn-,getShopifyDomain,-(props%3F%3A) for more details. */
|
|
1312
1312
|
getShopifyDomain?: ReturnType<typeof createStorefrontClient$1>['getShopifyDomain'];
|
|
1313
|
-
/** Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in Hydrogen React](/docs/api/hydrogen-react/
|
|
1313
|
+
/** Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in Hydrogen React](/docs/api/hydrogen-react/2026-01/utilities/createstorefrontclient#:~:text=storeDomain-,getStorefrontApiUrl,-(props%3F%3A) for more details.*/
|
|
1314
1314
|
getApiUrl?: ReturnType<typeof createStorefrontClient$1>['getStorefrontApiUrl'];
|
|
1315
1315
|
/** The `i18n` object passed in from the `createStorefrontClient` argument. */
|
|
1316
1316
|
i18n?: TI18n;
|
|
@@ -2439,9 +2439,9 @@ type VariantOptionValue = {
|
|
|
2439
2439
|
type VariantSelectorProps = {
|
|
2440
2440
|
/** The product handle for all of the variants */
|
|
2441
2441
|
handle: string;
|
|
2442
|
-
/** Product options from the [Storefront API](/docs/api/storefront/
|
|
2442
|
+
/** Product options from the [Storefront API](/docs/api/storefront/2026-01/objects/ProductOption). Make sure both `name` and `values` are a part of your query. */
|
|
2443
2443
|
options: Array<PartialProductOption> | undefined;
|
|
2444
|
-
/** Product variants from the [Storefront API](/docs/api/storefront/
|
|
2444
|
+
/** Product variants from the [Storefront API](/docs/api/storefront/2026-01/objects/ProductVariant). You only need to pass this prop if you want to show product availability. If a product option combination is not found within `variants`, it is assumed to be available. Make sure to include `availableForSale` and `selectedOptions.name` and `selectedOptions.value`. */
|
|
2445
2445
|
variants?: PartialDeep<ProductVariantConnection> | Array<PartialDeep<ProductVariant>>;
|
|
2446
2446
|
/** By default all products are under /products. Use this prop to provide a custom path. */
|
|
2447
2447
|
productPath?: string;
|
package/dist/production/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {createContext,forwardRef,useContext,lazy,useMemo,useEffect,useRef,useState,createElement,Fragment as Fragment$1,Suspense}from'react';import {createContext as createContext$1,useRevalidator,useFetcher,useFetchers,RouterContextProvider,createRequestHandler,useNavigation,useLocation,useNavigate,Link,useMatches}from'react-router';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useLoadScript,useShopifyCookies,getTrackingValues,createStorefrontClient,SHOPIFY_STOREFRONT_ID_HEADER,SHOPIFY_STOREFRONT_Y_HEADER,SHOPIFY_STOREFRONT_S_HEADER,SHOPIFY_UNIQUE_TOKEN_HEADER,SHOPIFY_VISIT_TOKEN_HEADER,flattenConnection,RichText,ShopPayButton,parseGid,sendShopifyAnalytics,AnalyticsEventName,AnalyticsPageType,getClientBrowserParameters}from'@shopify/hydrogen-react';export{AnalyticsEventName,AnalyticsPageType,ExternalVideo,IMAGE_FRAGMENT,Image,MediaFile,ModelViewer,Money,ShopifySalesChannel,Video,customerAccountApiCustomScalars,decodeEncodedVariant,flattenConnection,getAdjacentAndFirstAvailableVariants,getClientBrowserParameters,getProductOptions,getShopifyCookies,getTrackingValues,isOptionValueCombinationInEncodedVariant,mapSelectedProductOptionToObject,parseGid,parseMetafield,sendShopifyAnalytics,storefrontApiCustomScalars,useLoadScript,useMoney,useSelectedOptionInUrlParam,useShopifyCookies}from'@shopify/hydrogen-react';import {useLoadScript as useLoadScript$1}from'@shopify/hydrogen-react/load-script';import {createGraphQLClient}from'@shopify/graphql-client';import {parse,stringify}from'worktop/cookie';import ja from'content-security-policy-builder';function le(e){let{type:t,data:r={},customData:o}=e,n=useLocation(),{publish:a,cart:s,prevCart:c,shop:i,customData:u}=Y(),d=n.pathname+n.search,y={...r,customData:{...u,...o},cart:s,prevCart:c,shop:i};return useEffect(()=>{i?.shopId&&(y={...y,url:window.location.href},a(t,y));},[a,d,i?.shopId]),null}function Cr(e){return jsx(le,{...e,type:"page_viewed"})}function hr(e){return jsx(le,{...e,type:"product_viewed"})}function Ar(e){return jsx(le,{...e,type:"collection_viewed"})}function Pr(e){return jsx(le,{...e,type:"cart_viewed"})}function Sr(e){return jsx(le,{...e,type:"search_viewed"})}function vr(e){return jsx(le,{...e})}var F={PAGE_VIEWED:"page_viewed",PRODUCT_VIEWED:"product_viewed",COLLECTION_VIEWED:"collection_viewed",CART_VIEWED:"cart_viewed",SEARCH_VIEWED:"search_viewed",CART_UPDATED:"cart_updated",PRODUCT_ADD_TO_CART:"product_added_to_cart",PRODUCT_REMOVED_FROM_CART:"product_removed_from_cart",CUSTOM_EVENT:"custom_"};var qe="Custom-Storefront-Request-Group-ID",Ge="X-Shopify-Storefront-Access-Token",ft="X-SDK-Variant",mt="X-SDK-Variant-Source",gt="X-SDK-Version",Ct="X-Shopify-Client-IP",Re="X-Shopify-Client-IP-Sig",Be="_sfapi_proxy",Qe="_server_tracking";function jo(e){return Object.entries(e).map(([t,r])=>r?`${t};desc=${r}`:void 0).filter(Boolean).join(", ")}function Ie(e,t){let r=typeof t=="string"?t:jo(t);r&&e.headers.append("Server-Timing",r);}var Ko=["_y","_s","_cmp"];function Rr(e){let t={};if(!e)return t;let r=new RegExp(`\\b(${Ko.join("|")});desc="?([^",]+)"?`,"g"),o;for(;(o=r.exec(e))!==null;)t[o[1]]=o[2];return t}function Ir(e){if(typeof window>"u")return false;try{return !!window.performance.getEntriesByType("navigation")[0]?.serverTiming?.some(r=>r.name===e)}catch{return false}}function Tr(){return Ir(Be)}function Er(){return Ir(Qe)}var en="https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js",tn="https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js";function At(e){console.error(`[h2:error:useCustomerPrivacy] Unable to setup Customer Privacy API: Missing consent.${e} configuration.`);}function Pt(e){let{withPrivacyBanner:t=false,onVisitorConsentCollected:r,onReady:o,checkoutDomain:n,storefrontAccessToken:a,country:s,locale:c,sameDomainForStorefrontApi:i}=e,u=useMemo(()=>i??Tr(),[i]),d=useMemo(()=>u&&!Er(),[u]),y=useShopifyCookies({fetchTrackingValues:d,storefrontAccessToken:a,ignoreDeprecatedCookies:true}),g=useMemo(getTrackingValues,[y]),{revalidate:m}=useRevalidator();useLoadScript$1(t?tn:en,{attributes:{id:"customer-privacy-api"}});let{observing:p,setLoaded:l,apisLoaded:S}=on({withPrivacyBanner:t}),f=useMemo(()=>{n||At("checkoutDomain"),a||At("storefrontAccessToken"),(a.startsWith("shpat_")||a.length!==32)&&console.error("[h2:error:useCustomerPrivacy] It looks like you passed a private access token, make sure to use the public token");let h=nn(n);return {checkoutRootDomain:u&&typeof window<"u"?window.location.host:n,storefrontRootDomain:h?"."+h:void 0,storefrontAccessToken:a,country:s,locale:c}},[At,n,a,s,c]);useEffect(()=>{let h=A=>{let C=getTrackingValues();if((g.visitToken!==C.visitToken||g.uniqueToken!==C.uniqueToken)&&m().catch(()=>{console.warn("[h2:warn:useCustomerPrivacy] Revalidation failed after consent change.");}),r){let R=re();if(R?.shouldShowBanner()){let I=R.currentVisitorConsent();if(I&&I.marketing===""&&I.analytics===""&&I.preferences==="")return}r(A.detail);}};return document.addEventListener("visitorConsentCollected",h),()=>{document.removeEventListener("visitorConsentCollected",h);}},[r]),useEffect(()=>{if(!t||p.current.privacyBanner)return;p.current.privacyBanner=true;let h=window.privacyBanner||void 0;Object.defineProperty(window,"privacyBanner",{configurable:true,get(){return h},set(C){typeof C=="object"&&C!==null&&"showPreferences"in C&&"loadBanner"in C&&(h=Dr({privacyBanner:C,config:f}),l.privacyBanner());}});},[t,f,Dr,l.privacyBanner]),useEffect(()=>{if(p.current.customerPrivacy)return;p.current.customerPrivacy=true;let h=null,A=window.Shopify||void 0;Object.defineProperty(window,"Shopify",{configurable:true,get(){return A},set(C){typeof C=="object"&&C!==null&&Object.keys(C).length===0&&(A=C,Object.defineProperty(window.Shopify,"customerPrivacy",{configurable:true,get(){return h},set(R){if(typeof R=="object"&&R!==null&&"setTrackingConsent"in R){let I=R;h={...I,setTrackingConsent:wr({customerPrivacy:I,config:f})},A={...A,customerPrivacy:h},l.customerPrivacy();}}}));}});},[f,wr,l.customerPrivacy]),useEffect(()=>{if(!S||!y)return;let h=re();if(h&&!h.cachedConsent){let A=getTrackingValues();A.consent&&(h.cachedConsent=A.consent);}if(t){let A=Te();A&&A.loadBanner(f);}rn(),o?.();},[S,y]);let v={customerPrivacy:re()};return t&&(v.privacyBanner=Te()),v}var br=false;function rn(){if(br)return;br=true;let e=new CustomEvent("shopifyCustomerPrivacyApiLoaded");document.dispatchEvent(e);}function on({withPrivacyBanner:e}){let t=useRef({customerPrivacy:false,privacyBanner:false}),[r,o]=useState(e?[false,false]:[false]),n=r.every(Boolean);return {observing:t,setLoaded:{customerPrivacy:()=>{o(e?s=>[true,s[1]]:()=>[true]);},privacyBanner:()=>{e&&o(s=>[s[0],true]);}},apisLoaded:n}}function nn(e){if(typeof window>"u")return;let t=window.location.host,r=e.split(".").reverse(),o=t.split(".").reverse(),n=[];return r.forEach((a,s)=>{a===o[s]&&n.push(a);}),n.reverse().join(".")||void 0}function wr({customerPrivacy:e,config:t}){let r=e.setTrackingConsent,{locale:o,country:n,...a}=t;function s(c,i){r({...a,headlessStorefront:true,...c},i);}return s}function Dr({privacyBanner:e,config:t}){let r=e.loadBanner,o=e.showPreferences;function n(s){if(typeof s=="object"){r({...t,...s});return}r(t);}function a(s){if(typeof s=="object"){o({...t,...s});return}o(t);}return {loadBanner:n,showPreferences:a}}function re(){try{return window.Shopify&&window.Shopify.customerPrivacy?window.Shopify?.customerPrivacy:null}catch{return null}}function Te(){try{return window&&window?.privacyBanner?window.privacyBanner:null}catch{return null}}var xr="2025.10.0";function pn(){let e=re();if(!e)throw new Error("Shopify Customer Privacy API not available. Must be used within a useEffect. Make sure to load the Shopify Customer Privacy API with useCustomerPrivacy() or <AnalyticsProvider>.");return e}function _r({consent:e,onReady:t,domain:r}){let{subscribe:o,register:n,canTrack:a}=Y(),[s,c]=useState(false),[i,u]=useState(false),[d,y]=useState(""),g=useRef(false),{checkoutDomain:m,storefrontAccessToken:p,language:l}=e,{ready:S}=n("Internal_Shopify_Analytics");Pt({...e,locale:l,checkoutDomain:m||"mock.shop",storefrontAccessToken:p||"abcdefghijklmnopqrstuvwxyz123456",onReady:()=>!e.withPrivacyBanner&&u(true),onVisitorConsentCollected:v=>{try{y(JSON.stringify(v));}catch{}u(true);}});let f=useMemo(()=>i?a():true,[i,a,d]);return useShopifyCookies({hasUserConsent:f,domain:r,checkoutDomain:m,fetchTrackingValues:false,ignoreDeprecatedCookies:!i}),useEffect(()=>{g.current||(g.current=true,o(F.PAGE_VIEWED,yn),o(F.PRODUCT_VIEWED,fn),o(F.COLLECTION_VIEWED,mn),o(F.SEARCH_VIEWED,gn),o(F.PRODUCT_ADD_TO_CART,Cn),c(true));},[o]),useEffect(()=>{s&&i&&(S(),t());},[s,i,t]),null}function Ke(e){console.error(`[h2:error:ShopifyAnalytics] Unable to send Shopify analytics: Missing shop.${e} configuration.`);}function we(e){let t=pn(),r=t.analyticsProcessingAllowed();if(!e?.shop?.shopId){Ke("shopId");return}if(!e?.shop?.acceptedLanguage){Ke("acceptedLanguage");return}if(!e?.shop?.currency){Ke("currency");return}if(!e?.shop?.hydrogenSubchannelId){Ke("hydrogenSubchannelId");return}return {shopifySalesChannel:"hydrogen",assetVersionId:xr,...e.shop,hasUserConsent:r,...getClientBrowserParameters(),analyticsAllowed:t.analyticsProcessingAllowed(),marketingAllowed:t.marketingAllowed(),saleOfDataAllowed:t.saleOfDataAllowed(),ccpaEnforced:!t.saleOfDataAllowed(),gdprEnforced:!(t.marketingAllowed()&&t.analyticsProcessingAllowed())}}function ln(e,t){if(t===null)return;let r=we(e);return r?{...r,cartId:t.id}:void 0}var oe={};function yn(e){let t=we(e);t&&(sendShopifyAnalytics({eventName:AnalyticsEventName.PAGE_VIEW_2,payload:{...t,...oe}}),oe={});}function fn(e){let t=we(e);if(t&&Lr({type:"product",products:e.products})){let r=vt(e.products);oe={pageType:AnalyticsPageType.product,resourceId:r[0].productGid},t={...t,...oe,products:vt(e.products)},sendShopifyAnalytics({eventName:AnalyticsEventName.PRODUCT_VIEW,payload:t});}}function mn(e){let t=we(e);t&&(oe={pageType:AnalyticsPageType.collection,resourceId:e.collection.id},t={...t,...oe,collectionHandle:e.collection.handle,collectionId:e.collection.id},sendShopifyAnalytics({eventName:AnalyticsEventName.COLLECTION_VIEW,payload:t}));}function gn(e){let t=we(e);t&&(oe={pageType:AnalyticsPageType.search},t={...t,...oe,searchString:e.searchTerm},sendShopifyAnalytics({eventName:AnalyticsEventName.SEARCH_VIEW,payload:t}));}function Cn(e){let{cart:t,currentLine:r}=e,o=ln(e,t);!o||!r?.id||hn({matchedLine:r,eventPayload:o});}function hn({matchedLine:e,eventPayload:t}){let r={id:e.merchandise.product.id,variantId:e.merchandise.id,title:e.merchandise.product.title,variantTitle:e.merchandise.title,vendor:e.merchandise.product.vendor,price:e.merchandise.price.amount,quantity:e.quantity,productType:e.merchandise.product.productType,sku:e.merchandise.sku};Lr({type:"cart",products:[r]})&&sendShopifyAnalytics({eventName:AnalyticsEventName.ADD_TO_CART,payload:{...t,products:vt([r])}});}function ce(e,t,r,o){if(e==="cart"){let n=`${r?"merchandise":"merchandise.product"}.${t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up cart analytics events because the \`cart.lines[].${n}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartLine on CartLine\` is defined and make sure \`${n}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L25-L56.`);}else {let n=`${o||t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up product view analytics events because the \`${n}\` is missing from your \`<Analytics.ProductView>\`. Make sure \`${n}\` is part of your products data prop. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/routes/products.%24handle.tsx#L159-L165.`);}}function Lr({type:e,products:t}){return !t||t.length===0?(ce(e,"",false,"data.products"),false):(t.forEach(r=>{if(!r.id)return ce(e,"id",false),false;if(!r.title)return ce(e,"title",false),false;if(!r.price)return ce(e,"price.amount",true,"price"),false;if(!r.vendor)return ce(e,"vendor",false),false;if(!r.variantId)return ce(e,"id",true,"variantId"),false;if(!r.variantTitle)return ce(e,"title",true,"variantTitle"),false}),true)}function vt(e){return e.map(t=>{let r={productGid:t.id,variantGid:t.variantId,name:t.title,variantName:t.variantTitle,brand:t.vendor,price:t.price,quantity:t.quantity||1,category:t.productType};return t.sku&&(r.sku=t.sku),t.productType&&(r.category=t.productType),r})}function Nr(e){console.error(`[h2:error:CartAnalytics] Can't set up cart analytics events because the \`cart.${e}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartApiQuery on Cart\` is defined and make sure \`${e}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L59.`);}function Mr({cart:e,setCarts:t}){let{publish:r,shop:o,customData:n,canTrack:a,cart:s,prevCart:c}=Y(),i=useRef(null);return useEffect(()=>{if(e)return Promise.resolve(e).then(u=>{if(u&&u.lines){if(!u.id){Nr("id");return}if(!u.updatedAt){Nr("updatedAt");return}}t(({cart:d,prevCart:y})=>u?.updatedAt!==d?.updatedAt?{cart:u,prevCart:d}:{cart:d,prevCart:y});}),()=>{}},[t,e]),useEffect(()=>{if(!s||!s?.updatedAt||s?.updatedAt===c?.updatedAt)return;let u;try{u=JSON.parse(localStorage.getItem("cartLastUpdatedAt")||"");}catch{u=null;}if(s.id===u?.id&&s.updatedAt===u?.updatedAt)return;let d={eventTimestamp:Date.now(),cart:s,prevCart:c,shop:o,customData:n};if(s.updatedAt===i.current)return;i.current=s.updatedAt,r("cart_updated",d),localStorage.setItem("cartLastUpdatedAt",JSON.stringify({id:s.id,updatedAt:s.updatedAt}));let y=c?.lines?flattenConnection(c?.lines):[],g=s.lines?flattenConnection(s.lines):[];y?.forEach(m=>{let p=g.filter(l=>m.id===l.id);if(p?.length===1){let l=p[0];m.quantity<l.quantity?r("product_added_to_cart",{...d,prevLine:m,currentLine:l}):m.quantity>l.quantity&&r("product_removed_from_cart",{...d,prevLine:m,currentLine:l});}else r("product_removed_from_cart",{...d,prevLine:m});}),g?.forEach(m=>{let p=y.filter(l=>m.id===l.id);(!p||p.length===0)&&r("product_added_to_cart",{...d,currentLine:m});});},[s,c,r,o,n,a]),null}var In="https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-spa.min.js";function Vr({shop:e}){let t=useRef(false),{subscribe:r,register:o}=Y(),{ready:n}=o("Internal_Shopify_Perf_Kit"),a=useLoadScript(In,{attributes:{id:"perfkit","data-application":"hydrogen","data-shop-id":parseGid(e.shopId).id.toString(),"data-storefront-id":e.hydrogenSubchannelId,"data-monorail-region":"global","data-spa-mode":"true","data-resource-timing-sampling-rate":"100"}});return useEffect(()=>{a!=="done"||t.current||(t.current=true,r(F.PAGE_VIEWED,()=>{window.PerfKit?.navigate();}),r(F.PRODUCT_VIEWED,()=>{window.PerfKit?.setPageType("product");}),r(F.COLLECTION_VIEWED,()=>{window.PerfKit?.setPageType("collection");}),r(F.SEARCH_VIEWED,()=>{window.PerfKit?.setPageType("search");}),r(F.CART_VIEWED,()=>{window.PerfKit?.setPageType("cart");}),n());},[r,n,a]),null}var $r=new Set,B=e=>{$r.has(e)||(console.warn(e),$r.add(e));},Fr=new Set,It=e=>{Fr.has(e)||(console.error(new Error(e)),Fr.add(e));};var Dn={canTrack:()=>false,cart:null,customData:{},prevCart:null,publish:()=>{},shop:null,subscribe:()=>{},register:()=>({ready:()=>{}}),customerPrivacy:null,privacyBanner:null},Wr=createContext(Dn),ze=new Map,xe={};function jr(){return Object.values(xe).every(Boolean)}function Hr(e,t){ze.has(e)||ze.set(e,new Map),ze.get(e)?.set(t.toString(),t);}var Je=new Map;function qr(e,t){if(!jr()){Je.set(e,t);return}Kr(e,t);}function Kr(e,t){(ze.get(e)??new Map).forEach((r,o)=>{try{r(t);}catch(n){typeof n=="object"&&n instanceof Error?console.error("Analytics publish error",n.message,o,n.stack):console.error("Analytics publish error",n,o);}});}function Gr(e){return xe.hasOwnProperty(e)||(xe[e]=false),{ready:()=>{xe[e]=true,jr()&&Je.size>0&&(Je.forEach((t,r)=>{Kr(r,t);}),Je.clear());}}}function Br(){try{return window.Shopify.customerPrivacy.analyticsProcessingAllowed()}catch{}return false}function Qr(e,t){return `[h2:error:Analytics.Provider] - ${e} is required. Make sure ${t} is defined in your environment variables. See https://h2o.fyi/analytics/consent to learn how to setup environment variables in the Shopify admin.`}function xn({canTrack:e,cart:t,children:r,consent:o,customData:n={},shop:a=null,cookieDomain:s}){let{shop:c}=On(a),[i,u]=useState(!!e),[d,y]=useState(false),[g,m]=useState({cart:null,prevCart:null}),[p,l]=useState(e?()=>e:()=>Br);if(c)if(/\/68817551382$/.test(c.shopId))B("[h2:error:Analytics.Provider] - Mock shop is used. Analytics will not work properly.");else {if(!o.checkoutDomain){let f=Qr("consent.checkoutDomain","PUBLIC_CHECKOUT_DOMAIN");It(f);}if(!o.storefrontAccessToken){let f=Qr("consent.storefrontAccessToken","PUBLIC_STOREFRONT_API_TOKEN");It(f);}o?.country||(o.country="US"),o?.language||(o.language="EN"),o.withPrivacyBanner===void 0&&(o.withPrivacyBanner=false);}let S=useMemo(()=>({canTrack:p,...g,customData:n,publish:p()?qr:()=>{},shop:c,subscribe:Hr,register:Gr,customerPrivacy:re(),privacyBanner:Te()}),[i,p,g,g.cart?.updatedAt,g.prevCart,qr,Hr,n,c,Gr,JSON.stringify(xe),re,Te]);return jsxs(Wr.Provider,{value:S,children:[r,!!c&&jsx(Cr,{}),!!c&&!!t&&jsx(Mr,{cart:t,setCarts:m}),!!c&&jsx(_r,{consent:o,onReady:()=>{u(true),l(e?()=>e:()=>Br),y(true);},domain:s}),!!c&&d&&jsx(Vr,{shop:c})]})}function Y(){let e=useContext(Wr);if(!e)throw new Error("[h2:error:useAnalytics] 'useAnalytics()' must be a descendent of <AnalyticsProvider/>");return e}function On(e){let[t,r]=useState(null);return useEffect(()=>(Promise.resolve(e).then(r),()=>{}),[r,e]),{shop:t}}async function _n({storefront:e,publicStorefrontId:t="0"}){return e.query(Ln,{cache:e.CacheLong()}).then(({shop:r,localization:o})=>({shopId:r.id,acceptedLanguage:o.language.isoCode,currency:o.country.currency.isoCode,hydrogenSubchannelId:t}))}var Ln=`#graphql
|
|
1
|
+
import {createContext,forwardRef,useContext,lazy,useMemo,useEffect,useRef,useState,createElement,Fragment as Fragment$1,Suspense}from'react';import {createContext as createContext$1,useRevalidator,useFetcher,useFetchers,RouterContextProvider,createRequestHandler,useNavigation,useLocation,useNavigate,Link,useMatches}from'react-router';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useLoadScript,useShopifyCookies,getTrackingValues,createStorefrontClient,SHOPIFY_STOREFRONT_ID_HEADER,SHOPIFY_STOREFRONT_Y_HEADER,SHOPIFY_STOREFRONT_S_HEADER,SHOPIFY_UNIQUE_TOKEN_HEADER,SHOPIFY_VISIT_TOKEN_HEADER,flattenConnection,RichText,ShopPayButton,parseGid,sendShopifyAnalytics,AnalyticsEventName,AnalyticsPageType,getClientBrowserParameters}from'@shopify/hydrogen-react';export{AnalyticsEventName,AnalyticsPageType,ExternalVideo,IMAGE_FRAGMENT,Image,MediaFile,ModelViewer,Money,ShopifySalesChannel,Video,customerAccountApiCustomScalars,decodeEncodedVariant,flattenConnection,getAdjacentAndFirstAvailableVariants,getClientBrowserParameters,getProductOptions,getShopifyCookies,getTrackingValues,isOptionValueCombinationInEncodedVariant,mapSelectedProductOptionToObject,parseGid,parseMetafield,sendShopifyAnalytics,storefrontApiCustomScalars,useLoadScript,useMoney,useSelectedOptionInUrlParam,useShopifyCookies}from'@shopify/hydrogen-react';import {useLoadScript as useLoadScript$1}from'@shopify/hydrogen-react/load-script';import {createGraphQLClient}from'@shopify/graphql-client';import {parse,stringify}from'worktop/cookie';import ja from'content-security-policy-builder';function le(e){let{type:t,data:r={},customData:o}=e,n=useLocation(),{publish:a,cart:s,prevCart:c,shop:i,customData:u}=Y(),d=n.pathname+n.search,y={...r,customData:{...u,...o},cart:s,prevCart:c,shop:i};return useEffect(()=>{i?.shopId&&(y={...y,url:window.location.href},a(t,y));},[a,d,i?.shopId]),null}function Cr(e){return jsx(le,{...e,type:"page_viewed"})}function hr(e){return jsx(le,{...e,type:"product_viewed"})}function Ar(e){return jsx(le,{...e,type:"collection_viewed"})}function Pr(e){return jsx(le,{...e,type:"cart_viewed"})}function Sr(e){return jsx(le,{...e,type:"search_viewed"})}function vr(e){return jsx(le,{...e})}var F={PAGE_VIEWED:"page_viewed",PRODUCT_VIEWED:"product_viewed",COLLECTION_VIEWED:"collection_viewed",CART_VIEWED:"cart_viewed",SEARCH_VIEWED:"search_viewed",CART_UPDATED:"cart_updated",PRODUCT_ADD_TO_CART:"product_added_to_cart",PRODUCT_REMOVED_FROM_CART:"product_removed_from_cart",CUSTOM_EVENT:"custom_"};var qe="Custom-Storefront-Request-Group-ID",Ge="X-Shopify-Storefront-Access-Token",ft="X-SDK-Variant",mt="X-SDK-Variant-Source",gt="X-SDK-Version",Ct="X-Shopify-Client-IP",Re="X-Shopify-Client-IP-Sig",Be="_sfapi_proxy",Qe="_server_tracking";function jo(e){return Object.entries(e).map(([t,r])=>r?`${t};desc=${r}`:void 0).filter(Boolean).join(", ")}function Ie(e,t){let r=typeof t=="string"?t:jo(t);r&&e.headers.append("Server-Timing",r);}var Ko=["_y","_s","_cmp"];function Rr(e){let t={};if(!e)return t;let r=new RegExp(`\\b(${Ko.join("|")});desc="?([^",]+)"?`,"g"),o;for(;(o=r.exec(e))!==null;)t[o[1]]=o[2];return t}function Ir(e){if(typeof window>"u")return false;try{return !!window.performance.getEntriesByType("navigation")[0]?.serverTiming?.some(r=>r.name===e)}catch{return false}}function Tr(){return Ir(Be)}function Er(){return Ir(Qe)}var en="https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js",tn="https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js";function At(e){console.error(`[h2:error:useCustomerPrivacy] Unable to setup Customer Privacy API: Missing consent.${e} configuration.`);}function Pt(e){let{withPrivacyBanner:t=false,onVisitorConsentCollected:r,onReady:o,checkoutDomain:n,storefrontAccessToken:a,country:s,locale:c,sameDomainForStorefrontApi:i}=e,u=useMemo(()=>i??Tr(),[i]),d=useMemo(()=>u&&!Er(),[u]),y=useShopifyCookies({fetchTrackingValues:d,storefrontAccessToken:a,ignoreDeprecatedCookies:true}),g=useMemo(getTrackingValues,[y]),{revalidate:m}=useRevalidator();useLoadScript$1(t?tn:en,{attributes:{id:"customer-privacy-api"}});let{observing:p,setLoaded:l,apisLoaded:S}=on({withPrivacyBanner:t}),f=useMemo(()=>{n||At("checkoutDomain"),a||At("storefrontAccessToken"),(a.startsWith("shpat_")||a.length!==32)&&console.error("[h2:error:useCustomerPrivacy] It looks like you passed a private access token, make sure to use the public token");let h=nn(n);return {checkoutRootDomain:u&&typeof window<"u"?window.location.host:n,storefrontRootDomain:h?"."+h:void 0,storefrontAccessToken:a,country:s,locale:c}},[At,n,a,s,c]);useEffect(()=>{let h=A=>{let C=getTrackingValues();if((g.visitToken!==C.visitToken||g.uniqueToken!==C.uniqueToken)&&m().catch(()=>{console.warn("[h2:warn:useCustomerPrivacy] Revalidation failed after consent change.");}),r){let R=re();if(R?.shouldShowBanner()){let I=R.currentVisitorConsent();if(I&&I.marketing===""&&I.analytics===""&&I.preferences==="")return}r(A.detail);}};return document.addEventListener("visitorConsentCollected",h),()=>{document.removeEventListener("visitorConsentCollected",h);}},[r]),useEffect(()=>{if(!t||p.current.privacyBanner)return;p.current.privacyBanner=true;let h=window.privacyBanner||void 0;Object.defineProperty(window,"privacyBanner",{configurable:true,get(){return h},set(C){typeof C=="object"&&C!==null&&"showPreferences"in C&&"loadBanner"in C&&(h=Dr({privacyBanner:C,config:f}),l.privacyBanner());}});},[t,f,Dr,l.privacyBanner]),useEffect(()=>{if(p.current.customerPrivacy)return;p.current.customerPrivacy=true;let h=null,A=window.Shopify||void 0;Object.defineProperty(window,"Shopify",{configurable:true,get(){return A},set(C){typeof C=="object"&&C!==null&&Object.keys(C).length===0&&(A=C,Object.defineProperty(window.Shopify,"customerPrivacy",{configurable:true,get(){return h},set(R){if(typeof R=="object"&&R!==null&&"setTrackingConsent"in R){let I=R;h={...I,setTrackingConsent:wr({customerPrivacy:I,config:f})},A={...A,customerPrivacy:h},l.customerPrivacy();}}}));}});},[f,wr,l.customerPrivacy]),useEffect(()=>{if(!S||!y)return;let h=re();if(h&&!h.cachedConsent){let A=getTrackingValues();A.consent&&(h.cachedConsent=A.consent);}if(t){let A=Te();A&&A.loadBanner(f);}rn(),o?.();},[S,y]);let v={customerPrivacy:re()};return t&&(v.privacyBanner=Te()),v}var br=false;function rn(){if(br)return;br=true;let e=new CustomEvent("shopifyCustomerPrivacyApiLoaded");document.dispatchEvent(e);}function on({withPrivacyBanner:e}){let t=useRef({customerPrivacy:false,privacyBanner:false}),[r,o]=useState(e?[false,false]:[false]),n=r.every(Boolean);return {observing:t,setLoaded:{customerPrivacy:()=>{o(e?s=>[true,s[1]]:()=>[true]);},privacyBanner:()=>{e&&o(s=>[s[0],true]);}},apisLoaded:n}}function nn(e){if(typeof window>"u")return;let t=window.location.host,r=e.split(".").reverse(),o=t.split(".").reverse(),n=[];return r.forEach((a,s)=>{a===o[s]&&n.push(a);}),n.reverse().join(".")||void 0}function wr({customerPrivacy:e,config:t}){let r=e.setTrackingConsent,{locale:o,country:n,...a}=t;function s(c,i){r({...a,headlessStorefront:true,...c},i);}return s}function Dr({privacyBanner:e,config:t}){let r=e.loadBanner,o=e.showPreferences;function n(s){if(typeof s=="object"){r({...t,...s});return}r(t);}function a(s){if(typeof s=="object"){o({...t,...s});return}o(t);}return {loadBanner:n,showPreferences:a}}function re(){try{return window.Shopify&&window.Shopify.customerPrivacy?window.Shopify?.customerPrivacy:null}catch{return null}}function Te(){try{return window&&window?.privacyBanner?window.privacyBanner:null}catch{return null}}var xr="2026.1.0";function pn(){let e=re();if(!e)throw new Error("Shopify Customer Privacy API not available. Must be used within a useEffect. Make sure to load the Shopify Customer Privacy API with useCustomerPrivacy() or <AnalyticsProvider>.");return e}function _r({consent:e,onReady:t,domain:r}){let{subscribe:o,register:n,canTrack:a}=Y(),[s,c]=useState(false),[i,u]=useState(false),[d,y]=useState(""),g=useRef(false),{checkoutDomain:m,storefrontAccessToken:p,language:l}=e,{ready:S}=n("Internal_Shopify_Analytics");Pt({...e,locale:l,checkoutDomain:m||"mock.shop",storefrontAccessToken:p||"abcdefghijklmnopqrstuvwxyz123456",onReady:()=>!e.withPrivacyBanner&&u(true),onVisitorConsentCollected:v=>{try{y(JSON.stringify(v));}catch{}u(true);}});let f=useMemo(()=>i?a():true,[i,a,d]);return useShopifyCookies({hasUserConsent:f,domain:r,checkoutDomain:m,fetchTrackingValues:false,ignoreDeprecatedCookies:!i}),useEffect(()=>{g.current||(g.current=true,o(F.PAGE_VIEWED,yn),o(F.PRODUCT_VIEWED,fn),o(F.COLLECTION_VIEWED,mn),o(F.SEARCH_VIEWED,gn),o(F.PRODUCT_ADD_TO_CART,Cn),c(true));},[o]),useEffect(()=>{s&&i&&(S(),t());},[s,i,t]),null}function Ke(e){console.error(`[h2:error:ShopifyAnalytics] Unable to send Shopify analytics: Missing shop.${e} configuration.`);}function we(e){let t=pn(),r=t.analyticsProcessingAllowed();if(!e?.shop?.shopId){Ke("shopId");return}if(!e?.shop?.acceptedLanguage){Ke("acceptedLanguage");return}if(!e?.shop?.currency){Ke("currency");return}if(!e?.shop?.hydrogenSubchannelId){Ke("hydrogenSubchannelId");return}return {shopifySalesChannel:"hydrogen",assetVersionId:xr,...e.shop,hasUserConsent:r,...getClientBrowserParameters(),analyticsAllowed:t.analyticsProcessingAllowed(),marketingAllowed:t.marketingAllowed(),saleOfDataAllowed:t.saleOfDataAllowed(),ccpaEnforced:!t.saleOfDataAllowed(),gdprEnforced:!(t.marketingAllowed()&&t.analyticsProcessingAllowed())}}function ln(e,t){if(t===null)return;let r=we(e);return r?{...r,cartId:t.id}:void 0}var oe={};function yn(e){let t=we(e);t&&(sendShopifyAnalytics({eventName:AnalyticsEventName.PAGE_VIEW_2,payload:{...t,...oe}}),oe={});}function fn(e){let t=we(e);if(t&&Lr({type:"product",products:e.products})){let r=vt(e.products);oe={pageType:AnalyticsPageType.product,resourceId:r[0].productGid},t={...t,...oe,products:vt(e.products)},sendShopifyAnalytics({eventName:AnalyticsEventName.PRODUCT_VIEW,payload:t});}}function mn(e){let t=we(e);t&&(oe={pageType:AnalyticsPageType.collection,resourceId:e.collection.id},t={...t,...oe,collectionHandle:e.collection.handle,collectionId:e.collection.id},sendShopifyAnalytics({eventName:AnalyticsEventName.COLLECTION_VIEW,payload:t}));}function gn(e){let t=we(e);t&&(oe={pageType:AnalyticsPageType.search},t={...t,...oe,searchString:e.searchTerm},sendShopifyAnalytics({eventName:AnalyticsEventName.SEARCH_VIEW,payload:t}));}function Cn(e){let{cart:t,currentLine:r}=e,o=ln(e,t);!o||!r?.id||hn({matchedLine:r,eventPayload:o});}function hn({matchedLine:e,eventPayload:t}){let r={id:e.merchandise.product.id,variantId:e.merchandise.id,title:e.merchandise.product.title,variantTitle:e.merchandise.title,vendor:e.merchandise.product.vendor,price:e.merchandise.price.amount,quantity:e.quantity,productType:e.merchandise.product.productType,sku:e.merchandise.sku};Lr({type:"cart",products:[r]})&&sendShopifyAnalytics({eventName:AnalyticsEventName.ADD_TO_CART,payload:{...t,products:vt([r])}});}function ce(e,t,r,o){if(e==="cart"){let n=`${r?"merchandise":"merchandise.product"}.${t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up cart analytics events because the \`cart.lines[].${n}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartLine on CartLine\` is defined and make sure \`${n}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L25-L56.`);}else {let n=`${o||t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up product view analytics events because the \`${n}\` is missing from your \`<Analytics.ProductView>\`. Make sure \`${n}\` is part of your products data prop. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/routes/products.%24handle.tsx#L159-L165.`);}}function Lr({type:e,products:t}){return !t||t.length===0?(ce(e,"",false,"data.products"),false):(t.forEach(r=>{if(!r.id)return ce(e,"id",false),false;if(!r.title)return ce(e,"title",false),false;if(!r.price)return ce(e,"price.amount",true,"price"),false;if(!r.vendor)return ce(e,"vendor",false),false;if(!r.variantId)return ce(e,"id",true,"variantId"),false;if(!r.variantTitle)return ce(e,"title",true,"variantTitle"),false}),true)}function vt(e){return e.map(t=>{let r={productGid:t.id,variantGid:t.variantId,name:t.title,variantName:t.variantTitle,brand:t.vendor,price:t.price,quantity:t.quantity||1,category:t.productType};return t.sku&&(r.sku=t.sku),t.productType&&(r.category=t.productType),r})}function Nr(e){console.error(`[h2:error:CartAnalytics] Can't set up cart analytics events because the \`cart.${e}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartApiQuery on Cart\` is defined and make sure \`${e}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L59.`);}function Mr({cart:e,setCarts:t}){let{publish:r,shop:o,customData:n,canTrack:a,cart:s,prevCart:c}=Y(),i=useRef(null);return useEffect(()=>{if(e)return Promise.resolve(e).then(u=>{if(u&&u.lines){if(!u.id){Nr("id");return}if(!u.updatedAt){Nr("updatedAt");return}}t(({cart:d,prevCart:y})=>u?.updatedAt!==d?.updatedAt?{cart:u,prevCart:d}:{cart:d,prevCart:y});}),()=>{}},[t,e]),useEffect(()=>{if(!s||!s?.updatedAt||s?.updatedAt===c?.updatedAt)return;let u;try{u=JSON.parse(localStorage.getItem("cartLastUpdatedAt")||"");}catch{u=null;}if(s.id===u?.id&&s.updatedAt===u?.updatedAt)return;let d={eventTimestamp:Date.now(),cart:s,prevCart:c,shop:o,customData:n};if(s.updatedAt===i.current)return;i.current=s.updatedAt,r("cart_updated",d),localStorage.setItem("cartLastUpdatedAt",JSON.stringify({id:s.id,updatedAt:s.updatedAt}));let y=c?.lines?flattenConnection(c?.lines):[],g=s.lines?flattenConnection(s.lines):[];y?.forEach(m=>{let p=g.filter(l=>m.id===l.id);if(p?.length===1){let l=p[0];m.quantity<l.quantity?r("product_added_to_cart",{...d,prevLine:m,currentLine:l}):m.quantity>l.quantity&&r("product_removed_from_cart",{...d,prevLine:m,currentLine:l});}else r("product_removed_from_cart",{...d,prevLine:m});}),g?.forEach(m=>{let p=y.filter(l=>m.id===l.id);(!p||p.length===0)&&r("product_added_to_cart",{...d,currentLine:m});});},[s,c,r,o,n,a]),null}var In="https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-spa.min.js";function Vr({shop:e}){let t=useRef(false),{subscribe:r,register:o}=Y(),{ready:n}=o("Internal_Shopify_Perf_Kit"),a=useLoadScript(In,{attributes:{id:"perfkit","data-application":"hydrogen","data-shop-id":parseGid(e.shopId).id.toString(),"data-storefront-id":e.hydrogenSubchannelId,"data-monorail-region":"global","data-spa-mode":"true","data-resource-timing-sampling-rate":"100"}});return useEffect(()=>{a!=="done"||t.current||(t.current=true,r(F.PAGE_VIEWED,()=>{window.PerfKit?.navigate();}),r(F.PRODUCT_VIEWED,()=>{window.PerfKit?.setPageType("product");}),r(F.COLLECTION_VIEWED,()=>{window.PerfKit?.setPageType("collection");}),r(F.SEARCH_VIEWED,()=>{window.PerfKit?.setPageType("search");}),r(F.CART_VIEWED,()=>{window.PerfKit?.setPageType("cart");}),n());},[r,n,a]),null}var $r=new Set,B=e=>{$r.has(e)||(console.warn(e),$r.add(e));},Fr=new Set,It=e=>{Fr.has(e)||(console.error(new Error(e)),Fr.add(e));};var Dn={canTrack:()=>false,cart:null,customData:{},prevCart:null,publish:()=>{},shop:null,subscribe:()=>{},register:()=>({ready:()=>{}}),customerPrivacy:null,privacyBanner:null},Wr=createContext(Dn),ze=new Map,xe={};function jr(){return Object.values(xe).every(Boolean)}function Hr(e,t){ze.has(e)||ze.set(e,new Map),ze.get(e)?.set(t.toString(),t);}var Je=new Map;function qr(e,t){if(!jr()){Je.set(e,t);return}Kr(e,t);}function Kr(e,t){(ze.get(e)??new Map).forEach((r,o)=>{try{r(t);}catch(n){typeof n=="object"&&n instanceof Error?console.error("Analytics publish error",n.message,o,n.stack):console.error("Analytics publish error",n,o);}});}function Gr(e){return xe.hasOwnProperty(e)||(xe[e]=false),{ready:()=>{xe[e]=true,jr()&&Je.size>0&&(Je.forEach((t,r)=>{Kr(r,t);}),Je.clear());}}}function Br(){try{return window.Shopify.customerPrivacy.analyticsProcessingAllowed()}catch{}return false}function Qr(e,t){return `[h2:error:Analytics.Provider] - ${e} is required. Make sure ${t} is defined in your environment variables. See https://h2o.fyi/analytics/consent to learn how to setup environment variables in the Shopify admin.`}function xn({canTrack:e,cart:t,children:r,consent:o,customData:n={},shop:a=null,cookieDomain:s}){let{shop:c}=On(a),[i,u]=useState(!!e),[d,y]=useState(false),[g,m]=useState({cart:null,prevCart:null}),[p,l]=useState(e?()=>e:()=>Br);if(c)if(/\/68817551382$/.test(c.shopId))B("[h2:error:Analytics.Provider] - Mock shop is used. Analytics will not work properly.");else {if(!o.checkoutDomain){let f=Qr("consent.checkoutDomain","PUBLIC_CHECKOUT_DOMAIN");It(f);}if(!o.storefrontAccessToken){let f=Qr("consent.storefrontAccessToken","PUBLIC_STOREFRONT_API_TOKEN");It(f);}o?.country||(o.country="US"),o?.language||(o.language="EN"),o.withPrivacyBanner===void 0&&(o.withPrivacyBanner=false);}let S=useMemo(()=>({canTrack:p,...g,customData:n,publish:p()?qr:()=>{},shop:c,subscribe:Hr,register:Gr,customerPrivacy:re(),privacyBanner:Te()}),[i,p,g,g.cart?.updatedAt,g.prevCart,qr,Hr,n,c,Gr,JSON.stringify(xe),re,Te]);return jsxs(Wr.Provider,{value:S,children:[r,!!c&&jsx(Cr,{}),!!c&&!!t&&jsx(Mr,{cart:t,setCarts:m}),!!c&&jsx(_r,{consent:o,onReady:()=>{u(true),l(e?()=>e:()=>Br),y(true);},domain:s}),!!c&&d&&jsx(Vr,{shop:c})]})}function Y(){let e=useContext(Wr);if(!e)throw new Error("[h2:error:useAnalytics] 'useAnalytics()' must be a descendent of <AnalyticsProvider/>");return e}function On(e){let[t,r]=useState(null);return useEffect(()=>(Promise.resolve(e).then(r),()=>{}),[r,e]),{shop:t}}async function _n({storefront:e,publicStorefrontId:t="0"}){return e.query(Ln,{cache:e.CacheLong()}).then(({shop:r,localization:o})=>({shopId:r.id,acceptedLanguage:o.language.isoCode,currency:o.country.currency.isoCode,hydrogenSubchannelId:t}))}var Ln=`#graphql
|
|
2
2
|
query ShopData(
|
|
3
3
|
$country: CountryCode
|
|
4
4
|
$language: LanguageCode
|
|
@@ -20,7 +20,7 @@ import {createContext,forwardRef,useContext,lazy,useMemo,useEffect,useRef,useSta
|
|
|
20
20
|
`,Un={CartView:Pr,CollectionView:Ar,CustomView:vr,ProductView:hr,Provider:xn,SearchView:Sr};function W(e,t){return Tt(e.headers,t)}function Tt(e,t){let r=e?.get?.(t)??e?.[t];return typeof r=="string"?r:null}function ne(e){return {requestId:e?W(e,"request-id"):void 0,purpose:e?W(e,"purpose"):void 0}}function Yr(e){return {requestGroupId:W(e,"request-id"),buyerIp:W(e,"oxygen-buyer-ip"),buyerIpSig:W(e,Re),cookie:W(e,"cookie"),purpose:W(e,"sec-purpose")||W(e,"purpose")}}var Et=/^\/api\/(unstable|2\d{3}-\d{2})\/graphql\.json$/,bt=e=>{try{return new URL(e,"http://e.c").pathname}catch{return "/"}};function wt(e,t){return t.reduce((r,o)=>{let n=e(o);return n&&r.push([o,n]),r},[])}function fe(e,t={}){let r=new Error,o=(n,a="Error")=>{let s=(r.stack??"").split(`
|
|
21
21
|
`).slice(3+(t.stackOffset??0)).join(`
|
|
22
22
|
`).replace(/ at loader(\d+) \(/,(c,i)=>c.replace(i,""));return `${a}: ${n}
|
|
23
|
-
`+s};return e.then(n=>{if(n?.errors&&Array.isArray(n.errors)){let a=typeof t.logErrors=="function"?t.logErrors:()=>t.logErrors??false;n.errors.forEach(s=>{s&&(s.stack=o(s.message,s.name),a(s)&&console.error(s));});}return n}).catch(n=>{throw n&&(n.stack=o(n.message,n.name)),n})}var j=void 0;var Xe="public",Nn="private",Dt="no-store",zr={maxAge:"max-age",staleWhileRevalidate:"stale-while-revalidate",sMaxAge:"s-maxage",staleIfError:"stale-if-error"};function Oe(e){let t=[];return Object.keys(e).forEach(r=>{r==="mode"?t.push(e[r]):zr[r]&&t.push(`${zr[r]}=${e[r]}`);}),t.join(", ")}function xt(){return {mode:Dt}}function Ot(e){if(e?.mode&&e?.mode!==Xe&&e?.mode!==Nn)throw Error("'mode' must be either 'public' or 'private'")}function ue(e){return Ot(e),{mode:Xe,maxAge:1,staleWhileRevalidate:9,...e}}function _t(e){return Ot(e),{mode:Xe,maxAge:3600,staleWhileRevalidate:82800,...e}}function me(e){return Ot(e),{mode:Xe,maxAge:1,staleWhileRevalidate:86399,...e}}function Lt(e){return e}function z(e){return String(e).includes("__proto__")?JSON.parse(e,Mn):JSON.parse(e)}function Mn(e,t){if(e!=="__proto__")return t}function Ze(e,t){return e&&t?{...e,...t}:e||me()}function Ut(e){return Oe(Ze(e))}async function Vn(e,t){if(!e)return;let r=await e.match(t);if(!r){return}return r}async function $n(e,t,r,o){if(!e)return;let n=Ze(o),a=Ut(Ze(n,{maxAge:(n.maxAge||0)+(n.staleWhileRevalidate||0)})),s=Ut(Ze(n));r.headers.set("cache-control",a),r.headers.set("real-cache-control",s),r.headers.set("cache-put-date",String(Date.now())),await e.put(t,r);}async function Fn(e,t){e&&await e.delete(t);}function Hn(e,t){let r=e.headers.get("real-cache-control"),o=0;if(r){let a=r.match(/max-age=(\d*)/);a&&a.length>1&&(o=parseFloat(a[1]));}return [(Date.now()-Number(t))/1e3,o]}function qn(e,t){let r=t.headers.get("cache-put-date");if(!r)return false;let[o,n]=Hn(t,r),a=o>n;return a}var et={get:Vn,set:$n,delete:Fn,generateDefaultCacheControlHeader:Ut,isStale:qn};function _e(e){return `https://shopify.dev/?${e}`}function Gn(e){return e||me()}async function Jr(e,t){if(!e)return;let r=_e(t),o=new Request(r),n=await et.get(e,o);if(!n)return;let a=await n.text();try{return [z(a),n]}catch{return [a,n]}}async function Xr(e,t,r,o){if(!e)return;let n=_e(t),a=new Request(n),s=new Response(JSON.stringify(r));await et.set(e,a,s,Gn(o));}function Zr(e,t){return et.isStale(new Request(_e(e)),t)}function eo(e){let t=Array.isArray(e)?e:[e],r="";for(let o of t)o!=null&&(typeof o=="object"?r+=JSON.stringify(o):r+=o.toString());return encodeURIComponent(r)}var kt=new Set;async function tt(e,t,{strategy:r=ue(),cacheInstance:o,shouldCacheResult:n=()=>true,waitUntil:a,debugInfo:s}){let i=eo([...typeof e=="string"?[e]:e]),y=f=>{({displayName:f.displayName,url:f.response?.url,responseInit:{status:f.response?.status||0,statusText:f.response?.statusText||"",headers:Array.from(f.response?.headers.entries()||[])}});},m=void 0;if(!o||!r||r.mode===Dt){let f=await t({addDebugData:y});return f}let p=f=>Xr(o,i,{value:f,debugInfo:void 0},r),l=await Jr(o,i);if(l&&typeof l[0]!="string"){let[{value:f,debugInfo:v},h]=l;let A=Zr(i,h)?"STALE":"HIT";if(!kt.has(i)&&A==="STALE"){kt.add(i);let C=Promise.resolve().then(async()=>{let R=Date.now();try{let I=await t({addDebugData:y});n(I)&&(await p(I),m?.({result:I,cacheStatus:"PUT",overrideStartTime:R}));}catch(I){I.message&&(I.message="SWR in sub-request failed: "+I.message),console.error(I);}finally{kt.delete(i);}});a?.(C);}return f}let S=await t({addDebugData:y});if(n(S)){let f=Promise.resolve().then(async()=>{await p(S);});a?.(f);}return S}var Qn=["set-cookie","server-timing"];function to(e,t){return [e,{status:t.status,statusText:t.statusText,headers:[...t.headers].filter(([r])=>!Qn.includes(r.toLowerCase()))}]}function ro([e,t]){return [e,new Response(e,t)]}async function rt(e,t,{cacheInstance:r,cache:o,cacheKey:n=[e,t],shouldCacheResponse:a,waitUntil:s,debugInfo:c,streamConfig:i,onRawHeaders:u}){return !o&&(!t.method||t.method==="GET")&&(o=ue()),tt(n,async()=>{if(i){let g=null,p=await createGraphQLClient({url:e,customFetchApi:async(f,v)=>(g=await fetch(f,v),u?.(g.headers),g),headers:t.headers}).requestStream(i.query,{variables:i.variables}),l,S;for await(let f of p){let{data:v,errors:h}=f;l=v,S=h?.graphQLErrors??h;}return g?.ok?to({data:l,errors:S},g):g}let d=await fetch(e,t);if(u?.(d.headers),!d.ok)return d;let y=await d.text().catch(()=>"");try{y&&(y=z(y));}catch{}return to(y,d)},{cacheInstance:r,waitUntil:s,strategy:o??null,debugInfo:c,shouldCacheResult:d=>"ok"in d?!1:a(...ro(d))}).then(d=>"ok"in d?[null,d]:ro(d))}function Wn(e){let{cache:t,waitUntil:r,request:o}=e;return {run:({cacheKey:n,cacheStrategy:a,shouldCacheResult:s},c)=>tt(n,c,{shouldCacheResult:s,strategy:a,cacheInstance:t,waitUntil:r,debugInfo:{...ne(o),stackInfo:j?.()}}),fetch:(n,a,s)=>rt(n,a??{},{waitUntil:r,cacheKey:[n,a],cacheInstance:t,debugInfo:{url:n,...ne(o),stackInfo:j?.(),displayName:s?.displayName},cache:s.cacheStrategy,...s}).then(([c,i])=>({data:c,response:i}))}}var Nt=class{#e;constructor(){this.#e=new Map;}add(t){throw new Error("Method not implemented. Use `put` instead.")}addAll(t){throw new Error("Method not implemented. Use `put` instead.")}matchAll(t,r){throw new Error("Method not implemented. Use `match` instead.")}async put(t,r){if(t.method!=="GET")throw new TypeError("Cannot cache response to non-GET request.");if(r.status===206)throw new TypeError("Cannot cache response to a range request (206 Partial Content).");if(r.headers.get("vary")?.includes("*"))throw new TypeError("Cannot cache response with 'Vary: *' header.");this.#e.set(t.url,{body:new Uint8Array(await r.arrayBuffer()),status:r.status,headers:[...r.headers],timestamp:Date.now()});}async match(t){if(t.method!=="GET")return;let r=this.#e.get(t.url);if(!r)return;let{body:o,timestamp:n,...a}=r,s=new Headers(a.headers),c=s.get("cache-control")||s.get("real-cache-control")||"",i=parseInt(c.match(/max-age=(\d+)/)?.[1]||"0",10),u=parseInt(c.match(/stale-while-revalidate=(\d+)/)?.[1]||"0",10),d=(Date.now()-n)/1e3;if(d>i+u){this.#e.delete(t.url);return}let g=d>i;return s.set("cache",g?"STALE":"HIT"),s.set("date",new Date(n).toUTCString()),new Response(o,{status:a.status??200,headers:s})}async delete(t){return this.#e.has(t.url)?(this.#e.delete(t.url),true):false}keys(t){let r=[];for(let o of this.#e.keys())(!t||t.url===o)&&r.push(new Request(o));return Promise.resolve(r)}};var oo="cartFormInput";function J({children:e,action:t,inputs:r,route:o,fetcherKey:n}){let a=useFetcher({key:n});return jsxs(a.Form,{action:o||"",method:"post",children:[(t||r)&&jsx("input",{type:"hidden",name:oo,value:JSON.stringify({action:t,inputs:r})}),typeof e=="function"?e(a):e]})}J.INPUT_NAME=oo;J.ACTIONS={AttributesUpdateInput:"AttributesUpdateInput",BuyerIdentityUpdate:"BuyerIdentityUpdate",Create:"Create",DiscountCodesUpdate:"DiscountCodesUpdate",GiftCardCodesUpdate:"GiftCardCodesUpdate",GiftCardCodesAdd:"GiftCardCodesAdd",GiftCardCodesRemove:"GiftCardCodesRemove",LinesAdd:"LinesAdd",LinesRemove:"LinesRemove",LinesUpdate:"LinesUpdate",NoteUpdate:"NoteUpdate",SelectedDeliveryOptionsUpdate:"SelectedDeliveryOptionsUpdate",MetafieldsSet:"MetafieldsSet",MetafieldDelete:"MetafieldDelete",DeliveryAddressesAdd:"DeliveryAddressesAdd",DeliveryAddressesUpdate:"DeliveryAddressesUpdate",DeliveryAddressesRemove:"DeliveryAddressesRemove",DeliveryAddressesReplace:"DeliveryAddressesReplace"};function Kn(e){let t={};for(let s of e.entries()){let c=s[0],i=e.getAll(c);t[c]=i.length>1?i:s[1],t[c]==="on"?t[c]=true:t[c]==="off"&&(t[c]=false);}let{cartFormInput:r,...o}=t,{action:n,inputs:a}=r?JSON.parse(String(r)):{};return {action:n,inputs:{...a,...o}}}J.getFormInput=Kn;var Mt=e=>{let t=parse(Tt(e,"Cookie")||"");return ()=>t.cart?`gid://shopify/Cart/${t.cart}`:void 0};var Vt=e=>t=>{let r=new Headers;return r.append("Set-Cookie",stringify("cart",t.split("/").pop()||"",{path:"/",...e})),r};function ot(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`weak-${Math.random().toString(16).substring(2)}`}var Le="
|
|
23
|
+
`+s};return e.then(n=>{if(n?.errors&&Array.isArray(n.errors)){let a=typeof t.logErrors=="function"?t.logErrors:()=>t.logErrors??false;n.errors.forEach(s=>{s&&(s.stack=o(s.message,s.name),a(s)&&console.error(s));});}return n}).catch(n=>{throw n&&(n.stack=o(n.message,n.name)),n})}var j=void 0;var Xe="public",Nn="private",Dt="no-store",zr={maxAge:"max-age",staleWhileRevalidate:"stale-while-revalidate",sMaxAge:"s-maxage",staleIfError:"stale-if-error"};function Oe(e){let t=[];return Object.keys(e).forEach(r=>{r==="mode"?t.push(e[r]):zr[r]&&t.push(`${zr[r]}=${e[r]}`);}),t.join(", ")}function xt(){return {mode:Dt}}function Ot(e){if(e?.mode&&e?.mode!==Xe&&e?.mode!==Nn)throw Error("'mode' must be either 'public' or 'private'")}function ue(e){return Ot(e),{mode:Xe,maxAge:1,staleWhileRevalidate:9,...e}}function _t(e){return Ot(e),{mode:Xe,maxAge:3600,staleWhileRevalidate:82800,...e}}function me(e){return Ot(e),{mode:Xe,maxAge:1,staleWhileRevalidate:86399,...e}}function Lt(e){return e}function z(e){return String(e).includes("__proto__")?JSON.parse(e,Mn):JSON.parse(e)}function Mn(e,t){if(e!=="__proto__")return t}function Ze(e,t){return e&&t?{...e,...t}:e||me()}function Ut(e){return Oe(Ze(e))}async function Vn(e,t){if(!e)return;let r=await e.match(t);if(!r){return}return r}async function $n(e,t,r,o){if(!e)return;let n=Ze(o),a=Ut(Ze(n,{maxAge:(n.maxAge||0)+(n.staleWhileRevalidate||0)})),s=Ut(Ze(n));r.headers.set("cache-control",a),r.headers.set("real-cache-control",s),r.headers.set("cache-put-date",String(Date.now())),await e.put(t,r);}async function Fn(e,t){e&&await e.delete(t);}function Hn(e,t){let r=e.headers.get("real-cache-control"),o=0;if(r){let a=r.match(/max-age=(\d*)/);a&&a.length>1&&(o=parseFloat(a[1]));}return [(Date.now()-Number(t))/1e3,o]}function qn(e,t){let r=t.headers.get("cache-put-date");if(!r)return false;let[o,n]=Hn(t,r),a=o>n;return a}var et={get:Vn,set:$n,delete:Fn,generateDefaultCacheControlHeader:Ut,isStale:qn};function _e(e){return `https://shopify.dev/?${e}`}function Gn(e){return e||me()}async function Jr(e,t){if(!e)return;let r=_e(t),o=new Request(r),n=await et.get(e,o);if(!n)return;let a=await n.text();try{return [z(a),n]}catch{return [a,n]}}async function Xr(e,t,r,o){if(!e)return;let n=_e(t),a=new Request(n),s=new Response(JSON.stringify(r));await et.set(e,a,s,Gn(o));}function Zr(e,t){return et.isStale(new Request(_e(e)),t)}function eo(e){let t=Array.isArray(e)?e:[e],r="";for(let o of t)o!=null&&(typeof o=="object"?r+=JSON.stringify(o):r+=o.toString());return encodeURIComponent(r)}var kt=new Set;async function tt(e,t,{strategy:r=ue(),cacheInstance:o,shouldCacheResult:n=()=>true,waitUntil:a,debugInfo:s}){let i=eo([...typeof e=="string"?[e]:e]),y=f=>{({displayName:f.displayName,url:f.response?.url,responseInit:{status:f.response?.status||0,statusText:f.response?.statusText||"",headers:Array.from(f.response?.headers.entries()||[])}});},m=void 0;if(!o||!r||r.mode===Dt){let f=await t({addDebugData:y});return f}let p=f=>Xr(o,i,{value:f,debugInfo:void 0},r),l=await Jr(o,i);if(l&&typeof l[0]!="string"){let[{value:f,debugInfo:v},h]=l;let A=Zr(i,h)?"STALE":"HIT";if(!kt.has(i)&&A==="STALE"){kt.add(i);let C=Promise.resolve().then(async()=>{let R=Date.now();try{let I=await t({addDebugData:y});n(I)&&(await p(I),m?.({result:I,cacheStatus:"PUT",overrideStartTime:R}));}catch(I){I.message&&(I.message="SWR in sub-request failed: "+I.message),console.error(I);}finally{kt.delete(i);}});a?.(C);}return f}let S=await t({addDebugData:y});if(n(S)){let f=Promise.resolve().then(async()=>{await p(S);});a?.(f);}return S}var Qn=["set-cookie","server-timing"];function to(e,t){return [e,{status:t.status,statusText:t.statusText,headers:[...t.headers].filter(([r])=>!Qn.includes(r.toLowerCase()))}]}function ro([e,t]){return [e,new Response(e,t)]}async function rt(e,t,{cacheInstance:r,cache:o,cacheKey:n=[e,t],shouldCacheResponse:a,waitUntil:s,debugInfo:c,streamConfig:i,onRawHeaders:u}){return !o&&(!t.method||t.method==="GET")&&(o=ue()),tt(n,async()=>{if(i){let g=null,p=await createGraphQLClient({url:e,customFetchApi:async(f,v)=>(g=await fetch(f,v),u?.(g.headers),g),headers:t.headers}).requestStream(i.query,{variables:i.variables}),l,S;for await(let f of p){let{data:v,errors:h}=f;l=v,S=h?.graphQLErrors??h;}return g?.ok?to({data:l,errors:S},g):g}let d=await fetch(e,t);if(u?.(d.headers),!d.ok)return d;let y=await d.text().catch(()=>"");try{y&&(y=z(y));}catch{}return to(y,d)},{cacheInstance:r,waitUntil:s,strategy:o??null,debugInfo:c,shouldCacheResult:d=>"ok"in d?!1:a(...ro(d))}).then(d=>"ok"in d?[null,d]:ro(d))}function Wn(e){let{cache:t,waitUntil:r,request:o}=e;return {run:({cacheKey:n,cacheStrategy:a,shouldCacheResult:s},c)=>tt(n,c,{shouldCacheResult:s,strategy:a,cacheInstance:t,waitUntil:r,debugInfo:{...ne(o),stackInfo:j?.()}}),fetch:(n,a,s)=>rt(n,a??{},{waitUntil:r,cacheKey:[n,a],cacheInstance:t,debugInfo:{url:n,...ne(o),stackInfo:j?.(),displayName:s?.displayName},cache:s.cacheStrategy,...s}).then(([c,i])=>({data:c,response:i}))}}var Nt=class{#e;constructor(){this.#e=new Map;}add(t){throw new Error("Method not implemented. Use `put` instead.")}addAll(t){throw new Error("Method not implemented. Use `put` instead.")}matchAll(t,r){throw new Error("Method not implemented. Use `match` instead.")}async put(t,r){if(t.method!=="GET")throw new TypeError("Cannot cache response to non-GET request.");if(r.status===206)throw new TypeError("Cannot cache response to a range request (206 Partial Content).");if(r.headers.get("vary")?.includes("*"))throw new TypeError("Cannot cache response with 'Vary: *' header.");this.#e.set(t.url,{body:new Uint8Array(await r.arrayBuffer()),status:r.status,headers:[...r.headers],timestamp:Date.now()});}async match(t){if(t.method!=="GET")return;let r=this.#e.get(t.url);if(!r)return;let{body:o,timestamp:n,...a}=r,s=new Headers(a.headers),c=s.get("cache-control")||s.get("real-cache-control")||"",i=parseInt(c.match(/max-age=(\d+)/)?.[1]||"0",10),u=parseInt(c.match(/stale-while-revalidate=(\d+)/)?.[1]||"0",10),d=(Date.now()-n)/1e3;if(d>i+u){this.#e.delete(t.url);return}let g=d>i;return s.set("cache",g?"STALE":"HIT"),s.set("date",new Date(n).toUTCString()),new Response(o,{status:a.status??200,headers:s})}async delete(t){return this.#e.has(t.url)?(this.#e.delete(t.url),true):false}keys(t){let r=[];for(let o of this.#e.keys())(!t||t.url===o)&&r.push(new Request(o));return Promise.resolve(r)}};var oo="cartFormInput";function J({children:e,action:t,inputs:r,route:o,fetcherKey:n}){let a=useFetcher({key:n});return jsxs(a.Form,{action:o||"",method:"post",children:[(t||r)&&jsx("input",{type:"hidden",name:oo,value:JSON.stringify({action:t,inputs:r})}),typeof e=="function"?e(a):e]})}J.INPUT_NAME=oo;J.ACTIONS={AttributesUpdateInput:"AttributesUpdateInput",BuyerIdentityUpdate:"BuyerIdentityUpdate",Create:"Create",DiscountCodesUpdate:"DiscountCodesUpdate",GiftCardCodesUpdate:"GiftCardCodesUpdate",GiftCardCodesAdd:"GiftCardCodesAdd",GiftCardCodesRemove:"GiftCardCodesRemove",LinesAdd:"LinesAdd",LinesRemove:"LinesRemove",LinesUpdate:"LinesUpdate",NoteUpdate:"NoteUpdate",SelectedDeliveryOptionsUpdate:"SelectedDeliveryOptionsUpdate",MetafieldsSet:"MetafieldsSet",MetafieldDelete:"MetafieldDelete",DeliveryAddressesAdd:"DeliveryAddressesAdd",DeliveryAddressesUpdate:"DeliveryAddressesUpdate",DeliveryAddressesRemove:"DeliveryAddressesRemove",DeliveryAddressesReplace:"DeliveryAddressesReplace"};function Kn(e){let t={};for(let s of e.entries()){let c=s[0],i=e.getAll(c);t[c]=i.length>1?i:s[1],t[c]==="on"?t[c]=true:t[c]==="off"&&(t[c]=false);}let{cartFormInput:r,...o}=t,{action:n,inputs:a}=r?JSON.parse(String(r)):{};return {action:n,inputs:{...a,...o}}}J.getFormInput=Kn;var Mt=e=>{let t=parse(Tt(e,"Cookie")||"");return ()=>t.cart?`gid://shopify/Cart/${t.cart}`:void 0};var Vt=e=>t=>{let r=new Headers;return r.append("Set-Cookie",stringify("cart",t.split("/").pop()||"",{path:"/",...e})),r};function ot(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`weak-${Math.random().toString(16).substring(2)}`}var Le="2026.1.0";function ge(e){return e.replace(/\s*#.*$/gm,"").replace(/\s+/gm," ").trim()}var Zn=/(^|}\s)query[\s({]/im,ea=/(^|}\s)mutation[\s({]/im;function nt(e,t){if(!Zn.test(e))throw new Error(`[h2:error:${t}] Can only execute queries`)}function at(e,t){if(!ea.test(e))throw new Error(`[h2:error:${t}] Can only execute mutations`)}var de=class extends Error{locations;path;extensions;constructor(t,r={}){let n=(r.clientOperation?`[h2:error:${r.clientOperation}] `:"")+t+(r.requestId?` - Request ID: ${r.requestId}`:"");super(n),this.name="GraphQLError",this.extensions=r.extensions,this.locations=r.locations,this.path=r.path,this.stack=r.stack||void 0;try{this.cause=JSON.stringify({...typeof r.cause=="object"?r.cause:{},requestId:r.requestId});}catch{r.cause&&(this.cause=r.cause);}}get[Symbol.toStringTag](){return this.name}toString(){let t=`${this.name}: ${this.message}`;if(this.path)try{t+=` | path: ${JSON.stringify(this.path)}`;}catch{}if(this.extensions)try{t+=` | extensions: ${JSON.stringify(this.extensions)}`;}catch{}return t+=`
|
|
24
24
|
`,this.stack&&(t+=`${this.stack.slice(this.stack.indexOf(`
|
|
25
25
|
`)+1)}
|
|
26
26
|
`),t}toJSON(){return {name:"Error",message:""}}};function Ue({url:e,response:t,errors:r,type:o,query:n,queryVariables:a,ErrorConstructor:s=Error,client:c="storefront"}){let i=(typeof r=="string"?r:r?.map?.(d=>d.message).join(`
|
|
@@ -267,7 +267,7 @@ API response error: ${t.status}`,u=new de(i,{query:n,queryVariables:a,cause:{err
|
|
|
267
267
|
`;function Bt(e){return async(t,r)=>{let o=t.filter((s,c,i)=>i.indexOf(s)===c),{cartDiscountCodesUpdate:n,errors:a}=await e.storefront.mutate(pa(e.cartFragment),{variables:{cartId:e.getCartId(),discountCodes:o,...r}});return T(n,a)}}var pa=(e=w)=>`#graphql
|
|
268
268
|
mutation cartDiscountCodesUpdate(
|
|
269
269
|
$cartId: ID!
|
|
270
|
-
$discountCodes: [String!]
|
|
270
|
+
$discountCodes: [String!]!
|
|
271
271
|
$language: LanguageCode
|
|
272
272
|
$country: CountryCode
|
|
273
273
|
$visitorConsent: VisitorConsent
|
|
@@ -571,7 +571,7 @@ API response error: ${t.status}`,u=new de(i,{query:n,queryVariables:a,cause:{err
|
|
|
571
571
|
${e}
|
|
572
572
|
${b}
|
|
573
573
|
${D}
|
|
574
|
-
`;function er(e){let{getCartId:t,setCartId:r,storefront:o,customerAccount:n,cartQueryFragment:a,cartMutateFragment:s,buyerIdentity:c}=e,i=t(),u=()=>i||t(),d={storefront:o,getCartId:u,cartFragment:s,customerAccount:n},y=Ft(d),g=async function(...p){p[0].buyerIdentity={...c,...p[0].buyerIdentity};let l=await y(...p);return i=l?.cart?.id,l},m={get:$t({storefront:o,customerAccount:n,getCartId:u,cartFragment:a}),getCartId:u,setCartId:r,create:g,addLines:async(p,l)=>{let S=p.map(f=>({attributes:f.attributes,quantity:f.quantity,merchandiseId:f.merchandiseId,sellingPlanId:f.sellingPlanId,parent:f.parent}));return i||l?.cartId?await Ht(d)(S,l):await g({lines:S,buyerIdentity:c},l)},updateLines:qt(d),removeLines:Gt(d),updateDiscountCodes:async(p,l)=>i||l?.cartId?await Bt(d)(p,l):await g({discountCodes:p},l),updateGiftCardCodes:async(p,l)=>i||l?.cartId?await Jt(d)(p,l):await g({giftCardCodes:p},l),addGiftCardCodes:Xt(d),removeGiftCardCodes:Zt(d),updateBuyerIdentity:async(p,l)=>i||l?.cartId?await Qt(d)(p,l):await g({buyerIdentity:p},l),updateNote:async(p,l)=>i||l?.cartId?await Wt(d)(p,l):await g({note:p},l),updateSelectedDeliveryOption:jt(d),updateAttributes:async(p,l)=>i||l?.cartId?await Kt(d)(p,l):await g({attributes:p},l),setMetafields:async(p,l)=>i||l?.cartId?await Yt(d)(p,l):await g({metafields:p},l),deleteMetafield:zt(d),addDeliveryAddresses:lo(d),removeDeliveryAddresses:yo(d),updateDeliveryAddresses:fo(d),replaceDeliveryAddresses:mo(d)};return "customMethods"in e?{...m,...e.customMethods??{}}:m}function Ea(e){let t=useFetchers();if(!t||!t.length)return e;let r=e?.lines?structuredClone(e):{lines:{nodes:[]}},o=r.lines.nodes,n=false;for(let{formData:a}of t){if(!a)continue;let s=J.getFormInput(a);if(s.action===J.ACTIONS.LinesAdd)for(let c of s.inputs.lines){if(!c.selectedVariant){console.error("[h2:error:useOptimisticCart] No selected variant was passed in the cart action. Make sure to pass the selected variant if you want to use an optimistic cart");continue}let i=o.find(u=>u.merchandise.id===c.selectedVariant?.id);n=true,i?(i.quantity=(i.quantity||1)+(c.quantity||1),i.isOptimistic=true):o.unshift({id:po(c.selectedVariant.id),merchandise:c.selectedVariant,isOptimistic:true,quantity:c.quantity||1});}else if(s.action===J.ACTIONS.LinesRemove)for(let c of s.inputs.lineIds){let i=o.findIndex(u=>u.id===c);if(i!==-1){if(st(o[i].id)){console.error("[h2:error:useOptimisticCart] Tried to remove an optimistic line that has not been added to the cart yet");continue}o.splice(i,1),n=true;}else console.warn(`[h2:warn:useOptimisticCart] Tried to remove line '${c}' but it doesn't exist in the cart`);}else if(s.action===J.ACTIONS.LinesUpdate)for(let c of s.inputs.lines){let i=o.findIndex(u=>c.id===u.id);if(i>-1){if(st(o[i].id)){console.error("[h2:error:useOptimisticCart] Tried to update an optimistic line that has not been added to the cart yet");continue}o[i].quantity=c.quantity,o[i].quantity===0&&o.splice(i,1),n=true;}else console.warn(`[h2:warn:useOptimisticCart] Tried to update line '${c.id}' but it doesn't exist in the cart`);}}return n&&(r.isOptimistic=n),r.totalQuantity=o.reduce((a,s)=>a+s.quantity,0),r}var ba="https://raw.githubusercontent.com/Shopify/hydrogen/main/docs/changelog.json";async function wa({request:e,changelogUrl:t}){new URL(e.url).searchParams;return fetch(t||ba)}var ke=createContext$1(),tr=createContext$1(),rr=createContext$1(),or=createContext$1(),nr=createContext$1(),ar=createContext$1(),Da={storefront:ke,cart:tr,customerAccount:rr,env:or,session:nr,waitUntil:ar};var ct="2025-10",he=`Shopify Hydrogen ${Le}`,go="30243aa5-17c1-465a-8493-944bcc4e88aa",L="customerAccount",Ae="buyer";var H=class extends Response{constructor(t,r,o){super(`Bad request: ${t}`,{status:400,headers:o});}};function Me(e,t={}){let r=t.headers?new Headers(t.headers):new Headers({});return r.set("location",e),new Response(null,{status:t.status||302,headers:r})}async function xa({session:e,customerAccountId:t,customerAccountTokenExchangeUrl:r,httpsOrigin:o,debugInfo:n}){let a=new URLSearchParams,s=e.get(L),c=s?.refreshToken,i=s?.idToken;if(!c)throw new H("Unauthorized","No refreshToken found in the session. Make sure your session is configured correctly and passed to `createCustomerAccountClient`.");a.append("grant_type","refresh_token"),a.append("refresh_token",c),a.append("client_id",t);let u={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:o};new Date().getTime();let y=r,g=await fetch(y,{method:"POST",headers:u,body:a});if(!g.ok){let S=await g.text();throw new Response(S,{status:g.status,headers:{"Content-Type":"text/html; charset=utf-8"}})}let{access_token:m,expires_in:p,refresh_token:l}=await g.json();if(!m||m.length===0)throw new H("Unauthorized","Invalid access token received.");e.set(L,{accessToken:m,expiresAt:new Date(new Date().getTime()+(p-120)*1e3).getTime()+"",refreshToken:l,idToken:i});}function Pe(e){e.unset(L),e.unset(Ae);}async function Co({locks:e,expiresAt:t,session:r,customerAccountId:o,customerAccountTokenExchangeUrl:n,httpsOrigin:a,debugInfo:s}){if(parseInt(t,10)-1e3<new Date().getTime())try{e.refresh||(e.refresh=xa({session:r,customerAccountId:o,customerAccountTokenExchangeUrl:n,httpsOrigin:a,debugInfo:s})),await e.refresh,delete e.refresh;}catch(c){throw Pe(r),c&&c.status!==401?c:new H("Unauthorized","Login before querying the Customer Account API.")}}function ho(){let e=Oa();return Po(e)}async function Ao(e){let t=await crypto.subtle.digest({name:"SHA-256"},new TextEncoder().encode(e)),r=_a(t);return Po(r)}function Oa(){let e=new Uint8Array(32);return crypto.getRandomValues(e),String.fromCharCode.apply(null,Array.from(e))}function Po(e){return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function _a(e){let t=new Uint8Array(e),r=Array.from(t);return String.fromCharCode(...r)}function So(){let e=Date.now().toString(),t=Math.random().toString(36).substring(2);return e+t}async function vo(e,t,r,o,n){let a=t;if(!e)throw new H("Unauthorized","oAuth access token was not provided during token exchange.");let s=new URLSearchParams;s.append("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),s.append("client_id",a),s.append("audience",go),s.append("subject_token",e),s.append("subject_token_type","urn:ietf:params:oauth:token-type:access_token"),s.append("scopes","https://api.customers.com/auth/customer.graphql");let c={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:o};new Date().getTime();let u=r,d=await fetch(u,{method:"POST",headers:c,body:s});let y=await d.json();if(y.error)throw new H(y.error_description);return y.access_token}function Ro(e){return La(e).payload.nonce}function La(e){let[t,r,o]=e.split("."),n=JSON.parse(atob(t)),a=JSON.parse(atob(r));return {header:n,payload:a,signature:o}}function ut(){return ka(Ua())}function Ua(){try{return crypto.getRandomValues(new Uint8Array(16))}catch{return new Uint8Array(16).map(()=>Math.random()*255|0)}}function ka(e){return Array.from(e,function(t){return ("0"+(t&255).toString(16)).slice(-2)}).join("")}function dt(e){if(!e)return;let{pathname:t,search:r}=new URL(e),o=t+r,n=new URLSearchParams(r),a=n.get("return_to")||n.get("redirect");if(a){if(To(e,a))return a;console.warn(`Cross-domain redirects are not supported. Tried to redirect from ${o} to ${a}`);}}function To(e,t){try{return new URL(e).origin===new URL(t,e).origin}catch{return false}}function sr({requestUrl:e,defaultUrl:t,redirectUrl:r}){let o=e,n=Io(e,t),a=r?Io(e,r):n;return To(e,a.toString())?a.toString():(console.warn(`Cross-domain redirects are not supported. Tried to redirect from ${o} to ${a}. Default url ${n} is used instead.`),n.toString())}function Io(e,t){return Na(t)?new URL(t):new URL(t,new URL(e).origin)}function Na(e){try{return new URL(e),!0}catch{return false}}function Eo(e,t){let r=`https://shopify.com/${t}`,o=`https://shopify.com/authentication/${t}`;return function(a){switch(a){case "CA_BASE_URL":return r;case "CA_BASE_AUTH_URL":return o;case "GRAPHQL":return `${r}/account/customer/api/${e}/graphql`;case "AUTH":return `${o}/oauth/authorize`;case "LOGIN_SCOPE":return t?"openid email customer-account-api:full":"openid email https://api.customers.com/auth/customer.graphql";case "TOKEN_EXCHANGE":return `${o}/oauth/token`;case "LOGOUT":return `${o}/logout`}}}function Ma(e,t){if(!e.url)return t;let{pathname:r}=new URL(e.url),o=r.replace(/\.data$/,"").replace(/\/_root$/,"/").replace(/(.+)\/$/,"$1"),n=t+`?${new URLSearchParams({return_to:o}).toString()}`;return Me(n)}function cr({session:e,customerAccountId:t,shopId:r,customerApiVersion:o=ct,request:n,waitUntil:a,authUrl:s,customAuthStatusHandler:c,logErrors:i=true,loginPath:u="/account/login",authorizePath:d="/account/authorize",defaultRedirectPath:y="/account",language:g}){if(o!==ct&&console.warn(`[h2:warn:createCustomerAccountClient] You are using Customer Account API version ${o} when this version of Hydrogen was built for ${ct}.`),e||console.warn("[h2:warn:createCustomerAccountClient] session is required to use Customer Account API. Ensure the session object passed in exist."),!n?.url)throw new Error("[h2:error:createCustomerAccountClient] The request object does not contain a URL.");let m=c||(()=>Ma(n,u)),p=new URL(n.url),l=p.protocol==="http:"?p.origin.replace("http","https"):p.origin,S=sr({requestUrl:l,defaultUrl:d,redirectUrl:s}),f=Eo(o,r),v=Va(f,t),h=f("GRAPHQL"),A={};async function C({query:P,type:E,variables:x={}}){let O=await N();if(!O)throw m();new Date().getTime();let V=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":he,Origin:l,Authorization:O},body:JSON.stringify({query:P,variables:x})});let ee=await V.text(),K={url:h,response:V,type:E,query:P,queryVariables:x,errors:void 0,client:"customer"};if(!V.ok){if(V.status===401)throw Pe(e),m();let _;try{_=z(ee);}catch{_=[{message:ee}];}Ue({...K,errors:_});}try{let _=z(ee),{errors:Q}=_,Se=Q?.map(({message:G,...ve})=>new de(G,{...ve,clientOperation:`customerAccount.${K.type}`,requestId:V.headers.get("x-request-id"),queryVariables:x,query:P}));return {..._,...Q&&{errors:Se}}}catch{Ue({...K,errors:[{message:ee}]});}}async function R(){if(!r)return false;let P=e.get(L),E=P?.accessToken,x=P?.expiresAt;if(!E||!x)return false;let O=j?.();try{await Co({locks:A,expiresAt:x,session:e,customerAccountId:t,customerAccountTokenExchangeUrl:f("TOKEN_EXCHANGE"),httpsOrigin:l,debugInfo:{waitUntil:a,stackInfo:O,...ne(n)}});}catch{return false}return true}async function I(){if(!await R())throw m()}async function N(){if(await R())return e.get(L)?.accessToken}async function k(P,E){return v(),P=ge(P),at(P,"customer.mutate"),fe(C({query:P,type:"mutation",...E}),{logErrors:i})}async function ie(P,E){return v(),P=ge(P),nt(P,"customer.query"),fe(C({query:P,type:"query",...E}),{logErrors:i})}function Fe(P){e.set(Ae,{...e.get(Ae),...P});}async function He(){let P=await N();if(P)return {...e.get(Ae),customerAccessToken:P}}return {i18n:{language:g??"EN"},login:async P=>{v();let E=new URL(f("AUTH")),x=So(),O=ut();E.searchParams.set("client_id",t),E.searchParams.set("scope","openid email"),E.searchParams.append("response_type","code"),E.searchParams.append("redirect_uri",S),E.searchParams.set("scope",f("LOGIN_SCOPE")),E.searchParams.append("state",x),E.searchParams.append("nonce",O);let M=$a({contextLanguage:g??null,localeOverride:P?.locale??null,uiLocalesOverride:P?.uiLocales??null});M!=null&&E.searchParams.append("locale",M),P?.countryCode&&E.searchParams.append("region_country",P.countryCode),P?.acrValues&&E.searchParams.append("acr_values",P.acrValues),P?.loginHint&&(E.searchParams.append("login_hint",P.loginHint),P?.loginHintMode&&E.searchParams.append("login_hint_mode",P.loginHintMode));let q=ho(),V=await Ao(q);return e.set(L,{...e.get(L),codeVerifier:q,state:x,nonce:O,redirectPath:dt(n.url)||W(n,"Referer")||y}),E.searchParams.append("code_challenge",V),E.searchParams.append("code_challenge_method","S256"),Me(E.toString())},logout:async P=>{v();let E=e.get(L)?.idToken,x=sr({requestUrl:l,defaultUrl:l,redirectUrl:P?.postLogoutRedirectUri}),O=E?new URL(`${f("LOGOUT")}?${new URLSearchParams([["id_token_hint",E],["post_logout_redirect_uri",x]]).toString()}`).toString():x;Pe(e);let M=P?.headers instanceof Headers?P?.headers:new Headers(P?.headers);return P?.keepSession||(e.destroy?M.set("Set-Cookie",await e.destroy()):console.warn("[h2:warn:customerAccount] session.destroy is not available on your session implementation. All session data might not be cleared on logout."),e.isPending=false),Me(O,{headers:M})},isLoggedIn:R,handleAuthStatus:I,getAccessToken:N,getApiUrl:()=>h,mutate:k,query:ie,authorize:async()=>{v();let P=p.searchParams.get("code"),E=p.searchParams.get("state");if(!P||!E)throw Pe(e),new H("Unauthorized","No code or state parameter found in the redirect URL.");if(e.get(L)?.state!==E)throw Pe(e),new H("Unauthorized","The session state does not match the state parameter. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");let x=t,O=new URLSearchParams;O.append("grant_type","authorization_code"),O.append("client_id",x),O.append("redirect_uri",S),O.append("code",P);let M=e.get(L)?.codeVerifier;if(!M)throw new H("Unauthorized","No code verifier found in the session. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");O.append("code_verifier",M);let q={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:l};new Date().getTime();let K=f("TOKEN_EXCHANGE"),_=await fetch(K,{method:"POST",headers:q,body:O});if(!_.ok)throw new Response(await _.text(),{status:_.status,headers:{"Content-Type":"text/html; charset=utf-8"}});let{access_token:Q,expires_in:Se,id_token:G,refresh_token:ve}=await _.json(),$=e.get(L)?.nonce,te=await Ro(G);if($!==te)throw new H("Unauthorized",`Returned nonce does not match: ${$} !== ${te}`);let yt=Q;r||(yt=await vo(Q,t,f("TOKEN_EXCHANGE"),l,{...ne(n)}));let Bo=e.get(L)?.redirectPath;return e.set(L,{accessToken:yt,expiresAt:new Date(new Date().getTime()+(Se-120)*1e3).getTime()+"",refreshToken:ve,idToken:G}),Me(Bo||y)},setBuyer:Fe,getBuyer:He,UNSTABLE_setBuyer:P=>{B("[h2:warn:customerAccount] `customerAccount.UNSTABLE_setBuyer` is deprecated. Please use `customerAccount.setBuyer`."),Fe(P);},UNSTABLE_getBuyer:()=>(B("[h2:warn:customerAccount] `customerAccount.UNSTABLE_getBuyer` is deprecated. Please use `customerAccount.getBuyer`."),He())}}function Va(e,t){return function(){try{if(!t)throw Error();new URL(e("CA_BASE_URL")),new URL(e("CA_BASE_AUTH_URL"));}catch{console.error(new Error("[h2:error:customerAccount] You do not have the valid credential to use Customer Account API.\nRun `h2 env pull` to link your store credentials."));let o="Internal Server Error";throw new Response(o,{status:500})}}}function $a(e){return e.localeOverride!=null?ir(e.localeOverride):e.uiLocalesOverride!=null?ir(e.uiLocalesOverride):e.contextLanguage!=null?ir(e.contextLanguage):null}function ir(e){let r=e.toLowerCase().replaceAll("_","-").split("-"),o=r[0],n=r[1];return n?`${o}-${n.toUpperCase()}`:o}function Ha(e,t){let{env:r,request:o,cache:n,waitUntil:a,i18n:s,session:c,logErrors:i,storefront:u={},customerAccount:d,cart:y={},buyerIdentity:g}=e;c||console.warn("[h2:warn:createHydrogenContext] A session object is required to create hydrogen context."),d?.unstableB2b&&B("[h2:warn:createHydrogenContext] `customerAccount.unstableB2b` is now stable. Please remove the `unstableB2b` option.");let{storefront:m}=co({cache:n,waitUntil:a,i18n:s,logErrors:i,storefrontHeaders:u.headers||Yr(o),storefrontApiVersion:u.apiVersion,storefrontId:r.PUBLIC_STOREFRONT_ID,storeDomain:r.PUBLIC_STORE_DOMAIN,privateStorefrontToken:r.PRIVATE_STOREFRONT_API_TOKEN,publicStorefrontToken:r.PUBLIC_STOREFRONT_API_TOKEN}),p=cr({session:c,request:o,waitUntil:a,logErrors:i,customerApiVersion:d?.apiVersion,authUrl:d?.authUrl,customAuthStatusHandler:d?.customAuthStatusHandler,language:s?.language,customerAccountId:r.PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID,shopId:r.SHOP_ID}),l=er({getCartId:y.getId||Mt(o.headers),setCartId:y.setId||Vt(),cartQueryFragment:y.queryFragment,cartMutateFragment:y.mutateFragment,customMethods:y.customMethods,buyerIdentity:g,storefront:m,customerAccount:p}),S=new RouterContextProvider;S.set(ke,m),S.set(tr,l),S.set(rr,p),S.set(or,r),S.set(nr,c),a&&S.set(ar,a);let f={storefront:m,cart:l,customerAccount:p,env:r,session:c,waitUntil:a,...t||{}};return new Proxy(S,{get(h,A,C){if(A in h){let R=h[A];return typeof R=="function"?R.bind(h):R}return A in f?f[A]:Reflect.get(h,A,C)},has(h,A){return A in h||A in f},ownKeys(h){return [...Reflect.ownKeys(h),...Object.keys(f)]},getOwnPropertyDescriptor(h,A){if(A in h)return Reflect.getOwnPropertyDescriptor(h,A);if(A in f)return {enumerable:true,configurable:true,writable:false,value:f[A]}}})}function Ga({build:e,mode:t,poweredByHeader:r=true,getLoadContext:o,collectTrackingInformation:n=true,proxyStandardRoutes:a=true}){let s=createRequestHandler(e,t),c=r?i=>i.headers.append("powered-by","Shopify, Hydrogen"):void 0;return async i=>{let u=i.method;if((u==="GET"||u==="HEAD")&&i.body)return new Response(`${u} requests cannot have a body`,{status:400});let d=new URL(i.url);if(d.pathname.includes("//"))return new Response(null,{status:301,headers:{location:d.pathname.replace(/\/+/g,"/")}});let y=await o?.(i),g=y?.storefront||y?.get?.(ke);if(a&&(g||B("[h2:createRequestHandler] Storefront instance is required to proxy standard routes."),g?.isStorefrontApiUrl(i))){let p=await g.forward(i);return c?.(p),p}let m=await s(i,y);if(g&&a){n&&g.setCollectedSubrequestHeaders(m);let p=i.headers.get("sec-fetch-dest");(p&&p==="document"||i.headers.get("accept")?.includes("text/html"))&&Ie(m,{[Be]:"1"});}return c?.(m),m}}var bo=createContext(void 0),wo=bo.Provider,ur=()=>useContext(bo);function Ka(e){let t=ut(),r=Ya(t,e);return {nonce:t,header:r,NonceProvider:({children:n})=>createElement(wo,{value:t},n)}}function Ya(e,t){let{shop:r,...o}=t??{},n=`'nonce-${e}'`,a=["'self'","'unsafe-inline'","https://cdn.shopify.com"],s=["'self'","https://cdn.shopify.com/","https://monorail-edge.shopifysvc.com"];r&&r.checkoutDomain&&s.push(`https://${r.checkoutDomain}`),r&&r.storeDomain&&s.push(`https://${r.storeDomain}`);let i={baseUri:["'self'"],defaultSrc:["'self'",n,"https://cdn.shopify.com","https://shopify.com"],frameAncestors:["'none'"],styleSrc:a,connectSrc:s},u=Object.assign({},i,o);for(let d in i){let y=o[d];d&&y&&(u[d]=za(y,i[d]));}return u.scriptSrc instanceof Array?u.scriptSrc=[...u.scriptSrc.filter(d=>!d.startsWith("'nonce")),n]:u.defaultSrc instanceof Array&&(u.defaultSrc=[...u.defaultSrc.filter(d=>!d.startsWith("'nonce")),n]),ja({directives:u})}function za(e,t){let r=typeof t=="string"?[t]:t,o=Array.isArray(e)?e:[String(e)];return Array.isArray(r)?r.every(a=>a==="'none'")?o:[...o,...r]:r}var Za=forwardRef((e,t)=>{let{waitForHydration:r,src:o,...n}=e,a=ur();return r?jsx(es,{src:o,options:n}):jsx("script",{suppressHydrationWarning:true,...n,src:o,nonce:a,ref:t})});function es({src:e,options:t}){if(!e)throw new Error("`waitForHydration` with the Script component requires a `src` prop");return useLoadScript(e,{attributes:t}),null}async function ts(e){return e;}function os(e){let t=useFetchers(),r={};for(let{formData:o}of t)if(o?.get("optimistic-identifier")===e)try{if(o.has("optimistic-data")){let n=JSON.parse(String(o.get("optimistic-data")));Object.assign(r,n);}}catch{}return r}function ns({id:e,data:t}){return jsxs(Fragment,{children:[jsx("input",{type:"hidden",name:"optimistic-identifier",value:e}),jsx("input",{type:"hidden",name:"optimistic-data",value:JSON.stringify(t)})]})}function us({connection:e,children:t=()=>(console.warn("<Pagination> requires children to work properly"),null),namespace:r=""}){let [o,n]=useState(false),a=useNavigation(),s=useLocation();useNavigate();useEffect(()=>{a.state==="idle"&&n(false);},[a.state]);let{endCursor:i,hasNextPage:u,hasPreviousPage:d,nextPageUrl:y,nodes:g,previousPageUrl:m,startCursor:p}=ds(e,r),l=useMemo(()=>({...s.state,pagination:{...s.state?.pagination||{},[r]:{pageInfo:{endCursor:i,hasPreviousPage:d,hasNextPage:u,startCursor:p},nodes:g}}}),[i,u,d,p,g,r,s.state]),S=useMemo(()=>forwardRef(function(h,A){return u?createElement(Link,{preventScrollReset:true,...h,to:y,state:l,replace:true,ref:A,onClick:()=>n(true)}):null}),[u,y,l]),f=useMemo(()=>forwardRef(function(h,A){return d?createElement(Link,{preventScrollReset:true,...h,to:m,state:l,replace:true,ref:A,onClick:()=>n(true)}):null}),[d,m,l]);return t({state:l,hasNextPage:u,hasPreviousPage:d,isLoading:o,nextPageUrl:y,nodes:g,previousPageUrl:m,NextLink:S,PreviousLink:f})}function pt(e,t){let r=new URLSearchParams(e);return Object.keys(t?.pagination||{}).forEach(n=>{let a=n===""?"":`${n}_`,s=`${a}cursor`,c=`${a}direction`;r.delete(s),r.delete(c);}),r.toString()}function Ve(e){throw new Error(`The Pagination component requires ${"`"+e+"`"} to be a part of your query. See the guide on how to setup your query to include ${"`"+e+"`"}: https://shopify.dev/docs/custom-storefronts/hydrogen/data-fetching/pagination#setup-the-paginated-query`)}function ds(e,t=""){e.pageInfo||Ve("pageInfo"),typeof e.pageInfo.startCursor>"u"&&Ve("pageInfo.startCursor"),typeof e.pageInfo.endCursor>"u"&&Ve("pageInfo.endCursor"),typeof e.pageInfo.hasNextPage>"u"&&Ve("pageInfo.hasNextPage"),typeof e.pageInfo.hasPreviousPage>"u"&&Ve("pageInfo.hasPreviousPage");let r=useNavigation(),o=useNavigate(),{state:n,search:a,pathname:s}=useLocation(),c=t?`${t}_cursor`:"cursor",i=t?`${t}_direction`:"direction",y=new URLSearchParams(a).get(i)==="previous",g=useMemo(()=>!globalThis?.window?.__hydrogenHydrated||!n?.pagination?.[t]?.nodes?flattenConnection(e):y?[...flattenConnection(e),...n.pagination[t].nodes||[]]:[...n.pagination[t].nodes||[],...flattenConnection(e)],[n,e,t]),m=useMemo(()=>{let f=globalThis?.window?.__hydrogenHydrated,v=n?.pagination?.[t]?.pageInfo,h=!f||v?.startCursor===void 0?e.pageInfo.startCursor:v.startCursor,A=!f||v?.endCursor===void 0?e.pageInfo.endCursor:v.endCursor,C=!f||v?.hasPreviousPage===void 0?e.pageInfo.hasPreviousPage:v.hasPreviousPage,R=!f||v?.hasNextPage===void 0?e.pageInfo.hasNextPage:v.hasNextPage;return n?.pagination?.[t]?.nodes&&(y?(h=e.pageInfo.startCursor,C=e.pageInfo.hasPreviousPage):(A=e.pageInfo.endCursor,R=e.pageInfo.hasNextPage)),{startCursor:h,endCursor:A,hasPreviousPage:C,hasNextPage:R}},[y,n,t,e.pageInfo.hasNextPage,e.pageInfo.hasPreviousPage,e.pageInfo.startCursor,e.pageInfo.endCursor]),p=useRef({params:pt(a,n),pathname:s});useEffect(()=>{window.__hydrogenHydrated=true;},[]),useEffect(()=>{let f=pt(a,n),v=p.current.params;(s!==p.current.pathname||f!==v)&&!(r.state==="idle"&&!r.location)&&(p.current={pathname:s,params:pt(a,n)},o(`${s}?${pt(a,n)}`,{replace:true,preventScrollReset:true,state:{nodes:void 0,pageInfo:void 0}}));},[s,a,n]);let l=useMemo(()=>{let f=new URLSearchParams(a);return f.set(i,"previous"),m.startCursor&&f.set(c,m.startCursor),`?${f.toString()}`},[a,m.startCursor]),S=useMemo(()=>{let f=new URLSearchParams(a);return f.set(i,"next"),m.endCursor&&f.set(c,m.endCursor),`?${f.toString()}`},[a,m.endCursor]);return {...m,previousPageUrl:l,nextPageUrl:S,nodes:g}}function ps(e,t={pageBy:20}){if(typeof e?.url>"u")throw new Error("getPaginationVariables must be called with the Request object passed to your loader function");let{pageBy:r,namespace:o=""}=t,n=new URLSearchParams(new URL(e.url).search),a=o?`${o}_cursor`:"cursor",s=o?`${o}_direction`:"direction",c=n.get(a)??void 0;return (n.get(s)==="previous"?"previous":"next")==="previous"?{last:r,startCursor:c??null}:{first:r,endCursor:c??null}}function ms(e,t){let r=useNavigation(),[o,n]=useState([]);if(useEffect(()=>{Promise.resolve(t).then(a=>{a&&n(a instanceof Array?a:a.product?.variants?.nodes||[]);}).catch(a=>{reportError(new Error("[h2:error:useOptimisticVariant] An error occurred while resolving the variants for the optimistic product hook.",{cause:a}));});},[JSON.stringify(t)]),r.state==="loading"){let a=new URLSearchParams(r.location.search),s=false,c=o.find(i=>i.selectedOptions?i.selectedOptions.every(u=>a.get(u.name)===u.value):(s||(s=true,reportError(new Error("[h2:error:useOptimisticVariant] The optimistic product hook requires your product query to include variants with the selectedOptions field."))),false));if(c)return {...c,isOptimistic:true}}return e}function Ss({handle:e,options:t=[],variants:r=[],productPath:o="products",waitForNavigation:n=false,selectedVariant:a,children:s}){let c=t;c[0]?.values&&(B("[h2:warn:VariantSelector] product.options.values is deprecated. Use product.options.optionValues instead."),c[0]&&!c[0].optionValues&&(c=t.map(p=>({...p,optionValues:p.values?.map(l=>({name:l}))||[]}))));let i=r instanceof Array?r:flattenConnection(r),{searchParams:u,path:d,alreadyOnProductPage:y}=Rs(e,o,n),g=c.filter(p=>p?.optionValues?.length===1),m=a?a?.selectedOptions?.reduce((p,l)=>(p[l.name]=l.value,p),{}):{};return createElement(Fragment$1,null,...useMemo(()=>c.map(p=>{let l,S=[];for(let f of p.optionValues){let v=new URLSearchParams(y?u:void 0);v.set(p.name,f.name),g.forEach(I=>{I.optionValues[0].name&&v.set(I.name,I.optionValues[0].name);});let h=i.find(I=>I?.selectedOptions?.every(N=>(v.get(N?.name)||m?.[N?.name])===N?.value)),A=u.get(p.name);!A&&a&&(A=m?.[p.name]||null);let C=A?A===f.name:false;C&&(l=f.name);let R="?"+v.toString();S.push({value:f.name,optionValue:f,isAvailable:h?h.availableForSale:true,to:d+R,search:R,isActive:C,variant:h});}return s({option:{name:p.name,value:l,values:S}})}),[c,i,s]))}var vs=e=>{if(typeof e?.url>"u")throw new TypeError(`Expected a Request instance, got ${typeof e}`);let t=new URL(e.url).searchParams,r=[];return t.forEach((o,n)=>{r.push({name:n,value:o});}),r};function Rs(e,t,r){let{pathname:o,search:n}=useLocation(),a=useNavigation();return useMemo(()=>{let s=/(\/[a-zA-Z]{2}-[a-zA-Z]{2}\/)/g.exec(o),c=s&&s.length>0;t=t.startsWith("/")?t.substring(1):t;let i=c?`${s[0]}${t}/${e}`:`/${t}/${e}`;return {searchParams:new URLSearchParams(r||a.state!=="loading"?n:a.location.search),alreadyOnProductPage:i===o,path:i}},[o,n,r,e,t,a])}function Is(){return {name:"hydrogen-2025.7.0",reactRouterConfig:()=>({appDirectory:"app",buildDirectory:"dist",ssr:true,future:{v8_middleware:true,v8_splitRouteModules:true,v8_viteEnvironmentApi:false,unstable_optimizeDeps:true,unstable_subResourceIntegrity:false}}),reactRouterConfigResolved:({reactRouterConfig:e})=>{if(e.basename&&e.basename!=="/")throw new Error(`[Hydrogen Preset] basename is not supported in Hydrogen 2025.7.0.
|
|
574
|
+
`;function er(e){let{getCartId:t,setCartId:r,storefront:o,customerAccount:n,cartQueryFragment:a,cartMutateFragment:s,buyerIdentity:c}=e,i=t(),u=()=>i||t(),d={storefront:o,getCartId:u,cartFragment:s,customerAccount:n},y=Ft(d),g=async function(...p){p[0].buyerIdentity={...c,...p[0].buyerIdentity};let l=await y(...p);return i=l?.cart?.id,l},m={get:$t({storefront:o,customerAccount:n,getCartId:u,cartFragment:a}),getCartId:u,setCartId:r,create:g,addLines:async(p,l)=>{let S=p.map(f=>({attributes:f.attributes,quantity:f.quantity,merchandiseId:f.merchandiseId,sellingPlanId:f.sellingPlanId,parent:f.parent}));return i||l?.cartId?await Ht(d)(S,l):await g({lines:S,buyerIdentity:c},l)},updateLines:qt(d),removeLines:Gt(d),updateDiscountCodes:async(p,l)=>i||l?.cartId?await Bt(d)(p,l):await g({discountCodes:p},l),updateGiftCardCodes:async(p,l)=>i||l?.cartId?await Jt(d)(p,l):await g({giftCardCodes:p},l),addGiftCardCodes:Xt(d),removeGiftCardCodes:Zt(d),updateBuyerIdentity:async(p,l)=>i||l?.cartId?await Qt(d)(p,l):await g({buyerIdentity:p},l),updateNote:async(p,l)=>i||l?.cartId?await Wt(d)(p,l):await g({note:p},l),updateSelectedDeliveryOption:jt(d),updateAttributes:async(p,l)=>i||l?.cartId?await Kt(d)(p,l):await g({attributes:p},l),setMetafields:async(p,l)=>i||l?.cartId?await Yt(d)(p,l):await g({metafields:p},l),deleteMetafield:zt(d),addDeliveryAddresses:lo(d),removeDeliveryAddresses:yo(d),updateDeliveryAddresses:fo(d),replaceDeliveryAddresses:mo(d)};return "customMethods"in e?{...m,...e.customMethods??{}}:m}function Ea(e){let t=useFetchers();if(!t||!t.length)return e;let r=e?.lines?structuredClone(e):{lines:{nodes:[]}},o=r.lines.nodes,n=false;for(let{formData:a}of t){if(!a)continue;let s=J.getFormInput(a);if(s.action===J.ACTIONS.LinesAdd)for(let c of s.inputs.lines){if(!c.selectedVariant){console.error("[h2:error:useOptimisticCart] No selected variant was passed in the cart action. Make sure to pass the selected variant if you want to use an optimistic cart");continue}let i=o.find(u=>u.merchandise.id===c.selectedVariant?.id);n=true,i?(i.quantity=(i.quantity||1)+(c.quantity||1),i.isOptimistic=true):o.unshift({id:po(c.selectedVariant.id),merchandise:c.selectedVariant,isOptimistic:true,quantity:c.quantity||1});}else if(s.action===J.ACTIONS.LinesRemove)for(let c of s.inputs.lineIds){let i=o.findIndex(u=>u.id===c);if(i!==-1){if(st(o[i].id)){console.error("[h2:error:useOptimisticCart] Tried to remove an optimistic line that has not been added to the cart yet");continue}o.splice(i,1),n=true;}else console.warn(`[h2:warn:useOptimisticCart] Tried to remove line '${c}' but it doesn't exist in the cart`);}else if(s.action===J.ACTIONS.LinesUpdate)for(let c of s.inputs.lines){let i=o.findIndex(u=>c.id===u.id);if(i>-1){if(st(o[i].id)){console.error("[h2:error:useOptimisticCart] Tried to update an optimistic line that has not been added to the cart yet");continue}o[i].quantity=c.quantity,o[i].quantity===0&&o.splice(i,1),n=true;}else console.warn(`[h2:warn:useOptimisticCart] Tried to update line '${c.id}' but it doesn't exist in the cart`);}}return n&&(r.isOptimistic=n),r.totalQuantity=o.reduce((a,s)=>a+s.quantity,0),r}var ba="https://raw.githubusercontent.com/Shopify/hydrogen/main/docs/changelog.json";async function wa({request:e,changelogUrl:t}){new URL(e.url).searchParams;return fetch(t||ba)}var ke=createContext$1(),tr=createContext$1(),rr=createContext$1(),or=createContext$1(),nr=createContext$1(),ar=createContext$1(),Da={storefront:ke,cart:tr,customerAccount:rr,env:or,session:nr,waitUntil:ar};var ct="2026-01",he=`Shopify Hydrogen ${Le}`,go="30243aa5-17c1-465a-8493-944bcc4e88aa",L="customerAccount",Ae="buyer";var H=class extends Response{constructor(t,r,o){super(`Bad request: ${t}`,{status:400,headers:o});}};function Me(e,t={}){let r=t.headers?new Headers(t.headers):new Headers({});return r.set("location",e),new Response(null,{status:t.status||302,headers:r})}async function xa({session:e,customerAccountId:t,customerAccountTokenExchangeUrl:r,httpsOrigin:o,debugInfo:n}){let a=new URLSearchParams,s=e.get(L),c=s?.refreshToken,i=s?.idToken;if(!c)throw new H("Unauthorized","No refreshToken found in the session. Make sure your session is configured correctly and passed to `createCustomerAccountClient`.");a.append("grant_type","refresh_token"),a.append("refresh_token",c),a.append("client_id",t);let u={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:o};new Date().getTime();let y=r,g=await fetch(y,{method:"POST",headers:u,body:a});if(!g.ok){let S=await g.text();throw new Response(S,{status:g.status,headers:{"Content-Type":"text/html; charset=utf-8"}})}let{access_token:m,expires_in:p,refresh_token:l}=await g.json();if(!m||m.length===0)throw new H("Unauthorized","Invalid access token received.");e.set(L,{accessToken:m,expiresAt:new Date(new Date().getTime()+(p-120)*1e3).getTime()+"",refreshToken:l,idToken:i});}function Pe(e){e.unset(L),e.unset(Ae);}async function Co({locks:e,expiresAt:t,session:r,customerAccountId:o,customerAccountTokenExchangeUrl:n,httpsOrigin:a,debugInfo:s}){if(parseInt(t,10)-1e3<new Date().getTime())try{e.refresh||(e.refresh=xa({session:r,customerAccountId:o,customerAccountTokenExchangeUrl:n,httpsOrigin:a,debugInfo:s})),await e.refresh,delete e.refresh;}catch(c){throw Pe(r),c&&c.status!==401?c:new H("Unauthorized","Login before querying the Customer Account API.")}}function ho(){let e=Oa();return Po(e)}async function Ao(e){let t=await crypto.subtle.digest({name:"SHA-256"},new TextEncoder().encode(e)),r=_a(t);return Po(r)}function Oa(){let e=new Uint8Array(32);return crypto.getRandomValues(e),String.fromCharCode.apply(null,Array.from(e))}function Po(e){return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function _a(e){let t=new Uint8Array(e),r=Array.from(t);return String.fromCharCode(...r)}function So(){let e=Date.now().toString(),t=Math.random().toString(36).substring(2);return e+t}async function vo(e,t,r,o,n){let a=t;if(!e)throw new H("Unauthorized","oAuth access token was not provided during token exchange.");let s=new URLSearchParams;s.append("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),s.append("client_id",a),s.append("audience",go),s.append("subject_token",e),s.append("subject_token_type","urn:ietf:params:oauth:token-type:access_token"),s.append("scopes","https://api.customers.com/auth/customer.graphql");let c={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:o};new Date().getTime();let u=r,d=await fetch(u,{method:"POST",headers:c,body:s});let y=await d.json();if(y.error)throw new H(y.error_description);return y.access_token}function Ro(e){return La(e).payload.nonce}function La(e){let[t,r,o]=e.split("."),n=JSON.parse(atob(t)),a=JSON.parse(atob(r));return {header:n,payload:a,signature:o}}function ut(){return ka(Ua())}function Ua(){try{return crypto.getRandomValues(new Uint8Array(16))}catch{return new Uint8Array(16).map(()=>Math.random()*255|0)}}function ka(e){return Array.from(e,function(t){return ("0"+(t&255).toString(16)).slice(-2)}).join("")}function dt(e){if(!e)return;let{pathname:t,search:r}=new URL(e),o=t+r,n=new URLSearchParams(r),a=n.get("return_to")||n.get("redirect");if(a){if(To(e,a))return a;console.warn(`Cross-domain redirects are not supported. Tried to redirect from ${o} to ${a}`);}}function To(e,t){try{return new URL(e).origin===new URL(t,e).origin}catch{return false}}function sr({requestUrl:e,defaultUrl:t,redirectUrl:r}){let o=e,n=Io(e,t),a=r?Io(e,r):n;return To(e,a.toString())?a.toString():(console.warn(`Cross-domain redirects are not supported. Tried to redirect from ${o} to ${a}. Default url ${n} is used instead.`),n.toString())}function Io(e,t){return Na(t)?new URL(t):new URL(t,new URL(e).origin)}function Na(e){try{return new URL(e),!0}catch{return false}}function Eo(e,t){let r=`https://shopify.com/${t}`,o=`https://shopify.com/authentication/${t}`;return function(a){switch(a){case "CA_BASE_URL":return r;case "CA_BASE_AUTH_URL":return o;case "GRAPHQL":return `${r}/account/customer/api/${e}/graphql`;case "AUTH":return `${o}/oauth/authorize`;case "LOGIN_SCOPE":return t?"openid email customer-account-api:full":"openid email https://api.customers.com/auth/customer.graphql";case "TOKEN_EXCHANGE":return `${o}/oauth/token`;case "LOGOUT":return `${o}/logout`}}}function Ma(e,t){if(!e.url)return t;let{pathname:r}=new URL(e.url),o=r.replace(/\.data$/,"").replace(/\/_root$/,"/").replace(/(.+)\/$/,"$1"),n=t+`?${new URLSearchParams({return_to:o}).toString()}`;return Me(n)}function cr({session:e,customerAccountId:t,shopId:r,customerApiVersion:o=ct,request:n,waitUntil:a,authUrl:s,customAuthStatusHandler:c,logErrors:i=true,loginPath:u="/account/login",authorizePath:d="/account/authorize",defaultRedirectPath:y="/account",language:g}){if(o!==ct&&console.warn(`[h2:warn:createCustomerAccountClient] You are using Customer Account API version ${o} when this version of Hydrogen was built for ${ct}.`),e||console.warn("[h2:warn:createCustomerAccountClient] session is required to use Customer Account API. Ensure the session object passed in exist."),!n?.url)throw new Error("[h2:error:createCustomerAccountClient] The request object does not contain a URL.");let m=c||(()=>Ma(n,u)),p=new URL(n.url),l=p.protocol==="http:"?p.origin.replace("http","https"):p.origin,S=sr({requestUrl:l,defaultUrl:d,redirectUrl:s}),f=Eo(o,r),v=Va(f,t),h=f("GRAPHQL"),A={};async function C({query:P,type:E,variables:x={}}){let O=await N();if(!O)throw m();new Date().getTime();let V=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":he,Origin:l,Authorization:O},body:JSON.stringify({query:P,variables:x})});let ee=await V.text(),K={url:h,response:V,type:E,query:P,queryVariables:x,errors:void 0,client:"customer"};if(!V.ok){if(V.status===401)throw Pe(e),m();let _;try{_=z(ee);}catch{_=[{message:ee}];}Ue({...K,errors:_});}try{let _=z(ee),{errors:Q}=_,Se=Q?.map(({message:G,...ve})=>new de(G,{...ve,clientOperation:`customerAccount.${K.type}`,requestId:V.headers.get("x-request-id"),queryVariables:x,query:P}));return {..._,...Q&&{errors:Se}}}catch{Ue({...K,errors:[{message:ee}]});}}async function R(){if(!r)return false;let P=e.get(L),E=P?.accessToken,x=P?.expiresAt;if(!E||!x)return false;let O=j?.();try{await Co({locks:A,expiresAt:x,session:e,customerAccountId:t,customerAccountTokenExchangeUrl:f("TOKEN_EXCHANGE"),httpsOrigin:l,debugInfo:{waitUntil:a,stackInfo:O,...ne(n)}});}catch{return false}return true}async function I(){if(!await R())throw m()}async function N(){if(await R())return e.get(L)?.accessToken}async function k(P,E){return v(),P=ge(P),at(P,"customer.mutate"),fe(C({query:P,type:"mutation",...E}),{logErrors:i})}async function ie(P,E){return v(),P=ge(P),nt(P,"customer.query"),fe(C({query:P,type:"query",...E}),{logErrors:i})}function Fe(P){e.set(Ae,{...e.get(Ae),...P});}async function He(){let P=await N();if(P)return {...e.get(Ae),customerAccessToken:P}}return {i18n:{language:g??"EN"},login:async P=>{v();let E=new URL(f("AUTH")),x=So(),O=ut();E.searchParams.set("client_id",t),E.searchParams.set("scope","openid email"),E.searchParams.append("response_type","code"),E.searchParams.append("redirect_uri",S),E.searchParams.set("scope",f("LOGIN_SCOPE")),E.searchParams.append("state",x),E.searchParams.append("nonce",O);let M=$a({contextLanguage:g??null,localeOverride:P?.locale??null,uiLocalesOverride:P?.uiLocales??null});M!=null&&E.searchParams.append("locale",M),P?.countryCode&&E.searchParams.append("region_country",P.countryCode),P?.acrValues&&E.searchParams.append("acr_values",P.acrValues),P?.loginHint&&(E.searchParams.append("login_hint",P.loginHint),P?.loginHintMode&&E.searchParams.append("login_hint_mode",P.loginHintMode));let q=ho(),V=await Ao(q);return e.set(L,{...e.get(L),codeVerifier:q,state:x,nonce:O,redirectPath:dt(n.url)||W(n,"Referer")||y}),E.searchParams.append("code_challenge",V),E.searchParams.append("code_challenge_method","S256"),Me(E.toString())},logout:async P=>{v();let E=e.get(L)?.idToken,x=sr({requestUrl:l,defaultUrl:l,redirectUrl:P?.postLogoutRedirectUri}),O=E?new URL(`${f("LOGOUT")}?${new URLSearchParams([["id_token_hint",E],["post_logout_redirect_uri",x]]).toString()}`).toString():x;Pe(e);let M=P?.headers instanceof Headers?P?.headers:new Headers(P?.headers);return P?.keepSession||(e.destroy?M.set("Set-Cookie",await e.destroy()):console.warn("[h2:warn:customerAccount] session.destroy is not available on your session implementation. All session data might not be cleared on logout."),e.isPending=false),Me(O,{headers:M})},isLoggedIn:R,handleAuthStatus:I,getAccessToken:N,getApiUrl:()=>h,mutate:k,query:ie,authorize:async()=>{v();let P=p.searchParams.get("code"),E=p.searchParams.get("state");if(!P||!E)throw Pe(e),new H("Unauthorized","No code or state parameter found in the redirect URL.");if(e.get(L)?.state!==E)throw Pe(e),new H("Unauthorized","The session state does not match the state parameter. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");let x=t,O=new URLSearchParams;O.append("grant_type","authorization_code"),O.append("client_id",x),O.append("redirect_uri",S),O.append("code",P);let M=e.get(L)?.codeVerifier;if(!M)throw new H("Unauthorized","No code verifier found in the session. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");O.append("code_verifier",M);let q={"content-type":"application/x-www-form-urlencoded","User-Agent":he,Origin:l};new Date().getTime();let K=f("TOKEN_EXCHANGE"),_=await fetch(K,{method:"POST",headers:q,body:O});if(!_.ok)throw new Response(await _.text(),{status:_.status,headers:{"Content-Type":"text/html; charset=utf-8"}});let{access_token:Q,expires_in:Se,id_token:G,refresh_token:ve}=await _.json(),$=e.get(L)?.nonce,te=await Ro(G);if($!==te)throw new H("Unauthorized",`Returned nonce does not match: ${$} !== ${te}`);let yt=Q;r||(yt=await vo(Q,t,f("TOKEN_EXCHANGE"),l,{...ne(n)}));let Bo=e.get(L)?.redirectPath;return e.set(L,{accessToken:yt,expiresAt:new Date(new Date().getTime()+(Se-120)*1e3).getTime()+"",refreshToken:ve,idToken:G}),Me(Bo||y)},setBuyer:Fe,getBuyer:He,UNSTABLE_setBuyer:P=>{B("[h2:warn:customerAccount] `customerAccount.UNSTABLE_setBuyer` is deprecated. Please use `customerAccount.setBuyer`."),Fe(P);},UNSTABLE_getBuyer:()=>(B("[h2:warn:customerAccount] `customerAccount.UNSTABLE_getBuyer` is deprecated. Please use `customerAccount.getBuyer`."),He())}}function Va(e,t){return function(){try{if(!t)throw Error();new URL(e("CA_BASE_URL")),new URL(e("CA_BASE_AUTH_URL"));}catch{console.error(new Error("[h2:error:customerAccount] You do not have the valid credential to use Customer Account API.\nRun `h2 env pull` to link your store credentials."));let o="Internal Server Error";throw new Response(o,{status:500})}}}function $a(e){return e.localeOverride!=null?ir(e.localeOverride):e.uiLocalesOverride!=null?ir(e.uiLocalesOverride):e.contextLanguage!=null?ir(e.contextLanguage):null}function ir(e){let r=e.toLowerCase().replaceAll("_","-").split("-"),o=r[0],n=r[1];return n?`${o}-${n.toUpperCase()}`:o}function Ha(e,t){let{env:r,request:o,cache:n,waitUntil:a,i18n:s,session:c,logErrors:i,storefront:u={},customerAccount:d,cart:y={},buyerIdentity:g}=e;c||console.warn("[h2:warn:createHydrogenContext] A session object is required to create hydrogen context."),d?.unstableB2b&&B("[h2:warn:createHydrogenContext] `customerAccount.unstableB2b` is now stable. Please remove the `unstableB2b` option.");let{storefront:m}=co({cache:n,waitUntil:a,i18n:s,logErrors:i,storefrontHeaders:u.headers||Yr(o),storefrontApiVersion:u.apiVersion,storefrontId:r.PUBLIC_STOREFRONT_ID,storeDomain:r.PUBLIC_STORE_DOMAIN,privateStorefrontToken:r.PRIVATE_STOREFRONT_API_TOKEN,publicStorefrontToken:r.PUBLIC_STOREFRONT_API_TOKEN}),p=cr({session:c,request:o,waitUntil:a,logErrors:i,customerApiVersion:d?.apiVersion,authUrl:d?.authUrl,customAuthStatusHandler:d?.customAuthStatusHandler,language:s?.language,customerAccountId:r.PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID,shopId:r.SHOP_ID}),l=er({getCartId:y.getId||Mt(o.headers),setCartId:y.setId||Vt(),cartQueryFragment:y.queryFragment,cartMutateFragment:y.mutateFragment,customMethods:y.customMethods,buyerIdentity:g,storefront:m,customerAccount:p}),S=new RouterContextProvider;S.set(ke,m),S.set(tr,l),S.set(rr,p),S.set(or,r),S.set(nr,c),a&&S.set(ar,a);let f={storefront:m,cart:l,customerAccount:p,env:r,session:c,waitUntil:a,...t||{}};return new Proxy(S,{get(h,A,C){if(A in h){let R=h[A];return typeof R=="function"?R.bind(h):R}return A in f?f[A]:Reflect.get(h,A,C)},has(h,A){return A in h||A in f},ownKeys(h){return [...Reflect.ownKeys(h),...Object.keys(f)]},getOwnPropertyDescriptor(h,A){if(A in h)return Reflect.getOwnPropertyDescriptor(h,A);if(A in f)return {enumerable:true,configurable:true,writable:false,value:f[A]}}})}function Ga({build:e,mode:t,poweredByHeader:r=true,getLoadContext:o,collectTrackingInformation:n=true,proxyStandardRoutes:a=true}){let s=createRequestHandler(e,t),c=r?i=>i.headers.append("powered-by","Shopify, Hydrogen"):void 0;return async i=>{let u=i.method;if((u==="GET"||u==="HEAD")&&i.body)return new Response(`${u} requests cannot have a body`,{status:400});let d=new URL(i.url);if(d.pathname.includes("//"))return new Response(null,{status:301,headers:{location:d.pathname.replace(/\/+/g,"/")}});let y=await o?.(i),g=y?.storefront||y?.get?.(ke);if(a&&(g||B("[h2:createRequestHandler] Storefront instance is required to proxy standard routes."),g?.isStorefrontApiUrl(i))){let p=await g.forward(i);return c?.(p),p}let m=await s(i,y);if(g&&a){n&&g.setCollectedSubrequestHeaders(m);let p=i.headers.get("sec-fetch-dest");(p&&p==="document"||i.headers.get("accept")?.includes("text/html"))&&Ie(m,{[Be]:"1"});}return c?.(m),m}}var bo=createContext(void 0),wo=bo.Provider,ur=()=>useContext(bo);function Ka(e){let t=ut(),r=Ya(t,e);return {nonce:t,header:r,NonceProvider:({children:n})=>createElement(wo,{value:t},n)}}function Ya(e,t){let{shop:r,...o}=t??{},n=`'nonce-${e}'`,a=["'self'","'unsafe-inline'","https://cdn.shopify.com"],s=["'self'","https://cdn.shopify.com/","https://monorail-edge.shopifysvc.com"];r&&r.checkoutDomain&&s.push(`https://${r.checkoutDomain}`),r&&r.storeDomain&&s.push(`https://${r.storeDomain}`);let i={baseUri:["'self'"],defaultSrc:["'self'",n,"https://cdn.shopify.com","https://shopify.com"],frameAncestors:["'none'"],styleSrc:a,connectSrc:s},u=Object.assign({},i,o);for(let d in i){let y=o[d];d&&y&&(u[d]=za(y,i[d]));}return u.scriptSrc instanceof Array?u.scriptSrc=[...u.scriptSrc.filter(d=>!d.startsWith("'nonce")),n]:u.defaultSrc instanceof Array&&(u.defaultSrc=[...u.defaultSrc.filter(d=>!d.startsWith("'nonce")),n]),ja({directives:u})}function za(e,t){let r=typeof t=="string"?[t]:t,o=Array.isArray(e)?e:[String(e)];return Array.isArray(r)?r.every(a=>a==="'none'")?o:[...o,...r]:r}var Za=forwardRef((e,t)=>{let{waitForHydration:r,src:o,...n}=e,a=ur();return r?jsx(es,{src:o,options:n}):jsx("script",{suppressHydrationWarning:true,...n,src:o,nonce:a,ref:t})});function es({src:e,options:t}){if(!e)throw new Error("`waitForHydration` with the Script component requires a `src` prop");return useLoadScript(e,{attributes:t}),null}async function ts(e){return e;}function os(e){let t=useFetchers(),r={};for(let{formData:o}of t)if(o?.get("optimistic-identifier")===e)try{if(o.has("optimistic-data")){let n=JSON.parse(String(o.get("optimistic-data")));Object.assign(r,n);}}catch{}return r}function ns({id:e,data:t}){return jsxs(Fragment,{children:[jsx("input",{type:"hidden",name:"optimistic-identifier",value:e}),jsx("input",{type:"hidden",name:"optimistic-data",value:JSON.stringify(t)})]})}function us({connection:e,children:t=()=>(console.warn("<Pagination> requires children to work properly"),null),namespace:r=""}){let [o,n]=useState(false),a=useNavigation(),s=useLocation();useNavigate();useEffect(()=>{a.state==="idle"&&n(false);},[a.state]);let{endCursor:i,hasNextPage:u,hasPreviousPage:d,nextPageUrl:y,nodes:g,previousPageUrl:m,startCursor:p}=ds(e,r),l=useMemo(()=>({...s.state,pagination:{...s.state?.pagination||{},[r]:{pageInfo:{endCursor:i,hasPreviousPage:d,hasNextPage:u,startCursor:p},nodes:g}}}),[i,u,d,p,g,r,s.state]),S=useMemo(()=>forwardRef(function(h,A){return u?createElement(Link,{preventScrollReset:true,...h,to:y,state:l,replace:true,ref:A,onClick:()=>n(true)}):null}),[u,y,l]),f=useMemo(()=>forwardRef(function(h,A){return d?createElement(Link,{preventScrollReset:true,...h,to:m,state:l,replace:true,ref:A,onClick:()=>n(true)}):null}),[d,m,l]);return t({state:l,hasNextPage:u,hasPreviousPage:d,isLoading:o,nextPageUrl:y,nodes:g,previousPageUrl:m,NextLink:S,PreviousLink:f})}function pt(e,t){let r=new URLSearchParams(e);return Object.keys(t?.pagination||{}).forEach(n=>{let a=n===""?"":`${n}_`,s=`${a}cursor`,c=`${a}direction`;r.delete(s),r.delete(c);}),r.toString()}function Ve(e){throw new Error(`The Pagination component requires ${"`"+e+"`"} to be a part of your query. See the guide on how to setup your query to include ${"`"+e+"`"}: https://shopify.dev/docs/custom-storefronts/hydrogen/data-fetching/pagination#setup-the-paginated-query`)}function ds(e,t=""){e.pageInfo||Ve("pageInfo"),typeof e.pageInfo.startCursor>"u"&&Ve("pageInfo.startCursor"),typeof e.pageInfo.endCursor>"u"&&Ve("pageInfo.endCursor"),typeof e.pageInfo.hasNextPage>"u"&&Ve("pageInfo.hasNextPage"),typeof e.pageInfo.hasPreviousPage>"u"&&Ve("pageInfo.hasPreviousPage");let r=useNavigation(),o=useNavigate(),{state:n,search:a,pathname:s}=useLocation(),c=t?`${t}_cursor`:"cursor",i=t?`${t}_direction`:"direction",y=new URLSearchParams(a).get(i)==="previous",g=useMemo(()=>!globalThis?.window?.__hydrogenHydrated||!n?.pagination?.[t]?.nodes?flattenConnection(e):y?[...flattenConnection(e),...n.pagination[t].nodes||[]]:[...n.pagination[t].nodes||[],...flattenConnection(e)],[n,e,t]),m=useMemo(()=>{let f=globalThis?.window?.__hydrogenHydrated,v=n?.pagination?.[t]?.pageInfo,h=!f||v?.startCursor===void 0?e.pageInfo.startCursor:v.startCursor,A=!f||v?.endCursor===void 0?e.pageInfo.endCursor:v.endCursor,C=!f||v?.hasPreviousPage===void 0?e.pageInfo.hasPreviousPage:v.hasPreviousPage,R=!f||v?.hasNextPage===void 0?e.pageInfo.hasNextPage:v.hasNextPage;return n?.pagination?.[t]?.nodes&&(y?(h=e.pageInfo.startCursor,C=e.pageInfo.hasPreviousPage):(A=e.pageInfo.endCursor,R=e.pageInfo.hasNextPage)),{startCursor:h,endCursor:A,hasPreviousPage:C,hasNextPage:R}},[y,n,t,e.pageInfo.hasNextPage,e.pageInfo.hasPreviousPage,e.pageInfo.startCursor,e.pageInfo.endCursor]),p=useRef({params:pt(a,n),pathname:s});useEffect(()=>{window.__hydrogenHydrated=true;},[]),useEffect(()=>{let f=pt(a,n),v=p.current.params;(s!==p.current.pathname||f!==v)&&!(r.state==="idle"&&!r.location)&&(p.current={pathname:s,params:pt(a,n)},o(`${s}?${pt(a,n)}`,{replace:true,preventScrollReset:true,state:{nodes:void 0,pageInfo:void 0}}));},[s,a,n]);let l=useMemo(()=>{let f=new URLSearchParams(a);return f.set(i,"previous"),m.startCursor&&f.set(c,m.startCursor),`?${f.toString()}`},[a,m.startCursor]),S=useMemo(()=>{let f=new URLSearchParams(a);return f.set(i,"next"),m.endCursor&&f.set(c,m.endCursor),`?${f.toString()}`},[a,m.endCursor]);return {...m,previousPageUrl:l,nextPageUrl:S,nodes:g}}function ps(e,t={pageBy:20}){if(typeof e?.url>"u")throw new Error("getPaginationVariables must be called with the Request object passed to your loader function");let{pageBy:r,namespace:o=""}=t,n=new URLSearchParams(new URL(e.url).search),a=o?`${o}_cursor`:"cursor",s=o?`${o}_direction`:"direction",c=n.get(a)??void 0;return (n.get(s)==="previous"?"previous":"next")==="previous"?{last:r,startCursor:c??null}:{first:r,endCursor:c??null}}function ms(e,t){let r=useNavigation(),[o,n]=useState([]);if(useEffect(()=>{Promise.resolve(t).then(a=>{a&&n(a instanceof Array?a:a.product?.variants?.nodes||[]);}).catch(a=>{reportError(new Error("[h2:error:useOptimisticVariant] An error occurred while resolving the variants for the optimistic product hook.",{cause:a}));});},[JSON.stringify(t)]),r.state==="loading"){let a=new URLSearchParams(r.location.search),s=false,c=o.find(i=>i.selectedOptions?i.selectedOptions.every(u=>a.get(u.name)===u.value):(s||(s=true,reportError(new Error("[h2:error:useOptimisticVariant] The optimistic product hook requires your product query to include variants with the selectedOptions field."))),false));if(c)return {...c,isOptimistic:true}}return e}function Ss({handle:e,options:t=[],variants:r=[],productPath:o="products",waitForNavigation:n=false,selectedVariant:a,children:s}){let c=t;c[0]?.values&&(B("[h2:warn:VariantSelector] product.options.values is deprecated. Use product.options.optionValues instead."),c[0]&&!c[0].optionValues&&(c=t.map(p=>({...p,optionValues:p.values?.map(l=>({name:l}))||[]}))));let i=r instanceof Array?r:flattenConnection(r),{searchParams:u,path:d,alreadyOnProductPage:y}=Rs(e,o,n),g=c.filter(p=>p?.optionValues?.length===1),m=a?a?.selectedOptions?.reduce((p,l)=>(p[l.name]=l.value,p),{}):{};return createElement(Fragment$1,null,...useMemo(()=>c.map(p=>{let l,S=[];for(let f of p.optionValues){let v=new URLSearchParams(y?u:void 0);v.set(p.name,f.name),g.forEach(I=>{I.optionValues[0].name&&v.set(I.name,I.optionValues[0].name);});let h=i.find(I=>I?.selectedOptions?.every(N=>(v.get(N?.name)||m?.[N?.name])===N?.value)),A=u.get(p.name);!A&&a&&(A=m?.[p.name]||null);let C=A?A===f.name:false;C&&(l=f.name);let R="?"+v.toString();S.push({value:f.name,optionValue:f,isAvailable:h?h.availableForSale:true,to:d+R,search:R,isActive:C,variant:h});}return s({option:{name:p.name,value:l,values:S}})}),[c,i,s]))}var vs=e=>{if(typeof e?.url>"u")throw new TypeError(`Expected a Request instance, got ${typeof e}`);let t=new URL(e.url).searchParams,r=[];return t.forEach((o,n)=>{r.push({name:n,value:o});}),r};function Rs(e,t,r){let{pathname:o,search:n}=useLocation(),a=useNavigation();return useMemo(()=>{let s=/(\/[a-zA-Z]{2}-[a-zA-Z]{2}\/)/g.exec(o),c=s&&s.length>0;t=t.startsWith("/")?t.substring(1):t;let i=c?`${s[0]}${t}/${e}`:`/${t}/${e}`;return {searchParams:new URLSearchParams(r||a.state!=="loading"?n:a.location.search),alreadyOnProductPage:i===o,path:i}},[o,n,r,e,t,a])}function Is(){return {name:"hydrogen-2025.7.0",reactRouterConfig:()=>({appDirectory:"app",buildDirectory:"dist",ssr:true,future:{v8_middleware:true,v8_splitRouteModules:true,v8_viteEnvironmentApi:false,unstable_optimizeDeps:true,unstable_subResourceIntegrity:false}}),reactRouterConfigResolved:({reactRouterConfig:e})=>{if(e.basename&&e.basename!=="/")throw new Error(`[Hydrogen Preset] basename is not supported in Hydrogen 2025.7.0.
|
|
575
575
|
Reason: Requires major CLI infrastructure modernization.
|
|
576
576
|
Workaround: Use reverse proxy or CDN path rewriting for subdirectory hosting.`);if(e.prerender)throw new Error(`[Hydrogen Preset] prerender is not supported in Hydrogen 2025.7.0.
|
|
577
577
|
Reason: React Router plugin incompatibility with Hydrogen CLI build pipeline.
|
|
@@ -1039,13 +1039,13 @@ query SitemapIndex {
|
|
|
1039
1039
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartNoteUpdate
|
|
1040
1040
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartSelectedDeliveryOptionsUpdate
|
|
1041
1041
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartMetafieldsSet
|
|
1042
|
-
//! @see https://shopify.dev/docs/api/storefront/
|
|
1042
|
+
//! @see https://shopify.dev/docs/api/storefront/2026-01/mutations/cartMetafieldDelete
|
|
1043
1043
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartGiftCardCodesUpdate
|
|
1044
1044
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartGiftCardCodesAdd
|
|
1045
1045
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartGiftCardCodesRemove
|
|
1046
1046
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartDeliveryAddressesAdd
|
|
1047
1047
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartDeliveryAddressesRemove
|
|
1048
1048
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartDeliveryAddressesUpdate
|
|
1049
|
-
//! @see: https://shopify.dev/docs/api/storefront/
|
|
1049
|
+
//! @see: https://shopify.dev/docs/api/storefront/2026-01/mutations/cartDeliveryAddressesReplace
|
|
1050
1050
|
export{Un as Analytics,F as AnalyticsEvent,Lt as CacheCustom,_t as CacheLong,xt as CacheNone,ue as CacheShort,J as CartForm,Nt as InMemoryCache,wo as NonceProvider,ns as OptimisticInput,us as Pagination,bs as RichText,Za as Script,Fs as Seo,qs as ShopPayButton,Ss as VariantSelector,Kt as cartAttributesUpdateDefault,Qt as cartBuyerIdentityUpdateDefault,Ft as cartCreateDefault,Bt as cartDiscountCodesUpdateDefault,$t as cartGetDefault,Mt as cartGetIdDefault,Xt as cartGiftCardCodesAddDefault,Zt as cartGiftCardCodesRemoveDefault,Jt as cartGiftCardCodesUpdateDefault,Ht as cartLinesAddDefault,Gt as cartLinesRemoveDefault,qt as cartLinesUpdateDefault,zt as cartMetafieldDeleteDefault,Yt as cartMetafieldsSetDefault,Wt as cartNoteUpdateDefault,jt as cartSelectedDeliveryOptionsUpdateDefault,Vt as cartSetIdDefault,wa as changelogHandler,er as createCartHandler,Ka as createContentSecurityPolicy,cr as createCustomerAccountClient,Ha as createHydrogenContext,Ga as createRequestHandler,co as createStorefrontClient,Wn as createWithCache,T as formatAPIResult,Oe as generateCacheControlHeader,ps as getPaginationVariables,vs as getSelectedProductOptions,Ls as getSeoMeta,_n as getShopAnalytics,js as getSitemap,Ws as getSitemapIndex,ws as graphiqlLoader,Da as hydrogenContext,Is as hydrogenPreset,ts as hydrogenRoutes,Ds as storefrontRedirect,Y as useAnalytics,Pt as useCustomerPrivacy,ur as useNonce,Ea as useOptimisticCart,os as useOptimisticData,ms as useOptimisticVariant};//# sourceMappingURL=index.js.map
|
|
1051
1051
|
//# sourceMappingURL=index.js.map
|