@shopify/hydrogen-react 2024.10.1 → 2025.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/customer-account.schema.json +1 -1
- package/dist/browser-dev/CartLineProvider.mjs.map +1 -1
- package/dist/browser-dev/CartProvider.mjs.map +1 -1
- package/dist/browser-dev/Image.mjs.map +1 -1
- package/dist/browser-dev/ModelViewer.mjs.map +1 -1
- package/dist/browser-dev/Money.mjs.map +1 -1
- package/dist/browser-dev/Video.mjs.map +1 -1
- package/dist/browser-dev/codegen.helpers.mjs.map +1 -1
- package/dist/browser-dev/getProductOptions.mjs +11 -9
- package/dist/browser-dev/getProductOptions.mjs.map +1 -1
- package/dist/browser-dev/optionValueDecoder.mjs +10 -8
- package/dist/browser-dev/optionValueDecoder.mjs.map +1 -1
- package/dist/browser-dev/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/browser-dev/storefront-api-constants.mjs +1 -1
- package/dist/browser-dev/storefront-api-constants.mjs.map +1 -1
- package/dist/browser-dev/useCartAPIStateMachine.mjs.map +1 -1
- package/dist/browser-dev/useCartActions.mjs.map +1 -1
- package/dist/browser-prod/CartLineProvider.mjs.map +1 -1
- package/dist/browser-prod/CartProvider.mjs.map +1 -1
- package/dist/browser-prod/Image.mjs.map +1 -1
- package/dist/browser-prod/ModelViewer.mjs.map +1 -1
- package/dist/browser-prod/Money.mjs.map +1 -1
- package/dist/browser-prod/Video.mjs.map +1 -1
- package/dist/browser-prod/codegen.helpers.mjs.map +1 -1
- package/dist/browser-prod/getProductOptions.mjs +11 -9
- package/dist/browser-prod/getProductOptions.mjs.map +1 -1
- package/dist/browser-prod/optionValueDecoder.mjs +10 -8
- package/dist/browser-prod/optionValueDecoder.mjs.map +1 -1
- package/dist/browser-prod/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/browser-prod/storefront-api-constants.mjs +1 -1
- package/dist/browser-prod/storefront-api-constants.mjs.map +1 -1
- package/dist/browser-prod/useCartAPIStateMachine.mjs.map +1 -1
- package/dist/browser-prod/useCartActions.mjs.map +1 -1
- package/dist/node-dev/CartLineProvider.js.map +1 -1
- package/dist/node-dev/CartLineProvider.mjs.map +1 -1
- package/dist/node-dev/CartProvider.js.map +1 -1
- package/dist/node-dev/CartProvider.mjs.map +1 -1
- package/dist/node-dev/Image.js.map +1 -1
- package/dist/node-dev/Image.mjs.map +1 -1
- package/dist/node-dev/ModelViewer.js.map +1 -1
- package/dist/node-dev/ModelViewer.mjs.map +1 -1
- package/dist/node-dev/Money.js.map +1 -1
- package/dist/node-dev/Money.mjs.map +1 -1
- package/dist/node-dev/Video.js.map +1 -1
- package/dist/node-dev/Video.mjs.map +1 -1
- package/dist/node-dev/codegen.helpers.js.map +1 -1
- package/dist/node-dev/codegen.helpers.mjs.map +1 -1
- package/dist/node-dev/getProductOptions.js +11 -9
- package/dist/node-dev/getProductOptions.js.map +1 -1
- package/dist/node-dev/getProductOptions.mjs +11 -9
- package/dist/node-dev/getProductOptions.mjs.map +1 -1
- package/dist/node-dev/optionValueDecoder.js +10 -8
- package/dist/node-dev/optionValueDecoder.js.map +1 -1
- package/dist/node-dev/optionValueDecoder.mjs +10 -8
- package/dist/node-dev/optionValueDecoder.mjs.map +1 -1
- package/dist/node-dev/packages/hydrogen-react/package.json.js +1 -1
- package/dist/node-dev/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/node-dev/storefront-api-constants.js +1 -1
- package/dist/node-dev/storefront-api-constants.js.map +1 -1
- package/dist/node-dev/storefront-api-constants.mjs +1 -1
- package/dist/node-dev/storefront-api-constants.mjs.map +1 -1
- package/dist/node-dev/useCartAPIStateMachine.js.map +1 -1
- package/dist/node-dev/useCartAPIStateMachine.mjs.map +1 -1
- package/dist/node-dev/useCartActions.js.map +1 -1
- package/dist/node-dev/useCartActions.mjs.map +1 -1
- package/dist/node-prod/CartLineProvider.js.map +1 -1
- package/dist/node-prod/CartLineProvider.mjs.map +1 -1
- package/dist/node-prod/CartProvider.js.map +1 -1
- package/dist/node-prod/CartProvider.mjs.map +1 -1
- package/dist/node-prod/Image.js.map +1 -1
- package/dist/node-prod/Image.mjs.map +1 -1
- package/dist/node-prod/ModelViewer.js.map +1 -1
- package/dist/node-prod/ModelViewer.mjs.map +1 -1
- package/dist/node-prod/Money.js.map +1 -1
- package/dist/node-prod/Money.mjs.map +1 -1
- package/dist/node-prod/Video.js.map +1 -1
- package/dist/node-prod/Video.mjs.map +1 -1
- package/dist/node-prod/codegen.helpers.js.map +1 -1
- package/dist/node-prod/codegen.helpers.mjs.map +1 -1
- package/dist/node-prod/getProductOptions.js +11 -9
- package/dist/node-prod/getProductOptions.js.map +1 -1
- package/dist/node-prod/getProductOptions.mjs +11 -9
- package/dist/node-prod/getProductOptions.mjs.map +1 -1
- package/dist/node-prod/optionValueDecoder.js +10 -8
- package/dist/node-prod/optionValueDecoder.js.map +1 -1
- package/dist/node-prod/optionValueDecoder.mjs +10 -8
- package/dist/node-prod/optionValueDecoder.mjs.map +1 -1
- package/dist/node-prod/packages/hydrogen-react/package.json.js +1 -1
- package/dist/node-prod/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/node-prod/storefront-api-constants.js +1 -1
- package/dist/node-prod/storefront-api-constants.js.map +1 -1
- package/dist/node-prod/storefront-api-constants.mjs +1 -1
- package/dist/node-prod/storefront-api-constants.mjs.map +1 -1
- package/dist/node-prod/useCartAPIStateMachine.js.map +1 -1
- package/dist/node-prod/useCartAPIStateMachine.mjs.map +1 -1
- package/dist/node-prod/useCartActions.js.map +1 -1
- package/dist/node-prod/useCartActions.mjs.map +1 -1
- package/dist/types/CartLineProvider.d.ts +1 -1
- package/dist/types/CartProvider.d.ts +2 -2
- package/dist/types/Image.d.ts +1 -1
- package/dist/types/ModelViewer.d.ts +1 -1
- package/dist/types/Money.d.ts +1 -1
- package/dist/types/Video.d.ts +1 -1
- package/dist/types/codegen.helpers.d.ts +2 -2
- package/dist/types/optionValueDecoder.d.ts +2 -2
- package/dist/types/storefront-api-constants.d.ts +1 -1
- package/dist/types/storefront-api-types.d.ts +641 -127
- package/dist/types/useCartAPIStateMachine.d.ts +2 -2
- package/dist/types/useCartActions.d.ts +2 -2
- package/dist/umd/hydrogen-react.dev.js +23 -19
- package/dist/umd/hydrogen-react.dev.js.map +1 -1
- package/dist/umd/hydrogen-react.prod.js +7 -7
- package/dist/umd/hydrogen-react.prod.js.map +1 -1
- package/package.json +3 -3
- package/storefront.schema.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrogen-react.prod.js","sources":["../../../../node_modules/@xstate/fsm/es/index.js","../../../../node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js","../../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js","../../../../node_modules/use-sync-external-store/shim/index.js","../../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js","../../../../node_modules/use-sync-external-store/shim/with-selector.js","../../../../node_modules/@xstate/react/es/useConstant.js","../../../../node_modules/@xstate/react/es/fsm.js","../../src/flatten-connection.ts","../../src/cart-queries.ts","../../src/storefront-api-constants.ts","../../src/storefront-client.ts","../../src/ShopifyProvider.tsx","../../src/cart-constants.ts","../../../../node_modules/worktop/cookie/index.mjs","../../src/cookies-utils.tsx","../../src/cart-hooks.tsx","../../src/useCartActions.tsx","../../src/useCartAPIStateMachine.tsx","../../src/CartProvider.tsx","../../src/ProductProvider.tsx","../../src/BaseButton.tsx","../../src/AddToCartButton.tsx","../../src/analytics-constants.ts","../../src/analytics-utils.ts","../../src/analytics-schema-trekkie-storefront-page-view.ts","../../src/analytics-schema-custom-storefront-customer-tracking.ts","../../src/analytics.ts","../../src/BuyNowButton.tsx","../../src/CartCheckoutButton.tsx","../../src/useMoney.tsx","../../src/Money.tsx","../../src/CartCost.tsx","../../src/CartLineProvider.tsx","../../src/CartLineQuantity.tsx","../../src/CartLineQuantityAdjustButton.tsx","../../src/codegen.helpers.ts","../../src/ExternalVideo.tsx","../../src/optionValueDecoder.ts","../../src/getProductOptions.ts","../../src/Image.tsx","../../src/load-script.tsx","../../src/Video.tsx","../../src/ModelViewer.tsx","../../src/MediaFile.tsx","../../src/parse-metafield.ts","../../src/ProductPrice.tsx","../../src/RichText.components.tsx","../../src/RichText.tsx","../../src/ShopPayButton.tsx","../../src/useSelectedOptionInUrlParam.tsx","../../src/useShopifyCookies.tsx"],"sourcesContent":["/*! *****************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\nfunction t(t,n){var e=\"function\"==typeof Symbol&&t[Symbol.iterator];if(!e)return t;var r,i,o=e.call(t),a=[];try{for(;(void 0===n||n-- >0)&&!(r=o.next()).done;)a.push(r.value)}catch(t){i={error:t}}finally{try{r&&!r.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return a}var n;!function(t){t[t.NotStarted=0]=\"NotStarted\",t[t.Running=1]=\"Running\",t[t.Stopped=2]=\"Stopped\"}(n||(n={}));var e={type:\"xstate.init\"};function r(t){return void 0===t?[]:[].concat(t)}function i(t){return{type:\"xstate.assign\",assignment:t}}function o(t,n){return\"string\"==typeof(t=\"string\"==typeof t&&n&&n[t]?n[t]:t)?{type:t}:\"function\"==typeof t?{type:t.name,exec:t}:t}function a(t){return function(n){return t===n}}function u(t){return\"string\"==typeof t?{type:t}:t}function c(t,n){return{value:t,context:n,actions:[],changed:!1,matches:a(t)}}function f(t,n,e){var r=n,i=!1;return[t.filter((function(t){if(\"xstate.assign\"===t.type){i=!0;var n=Object.assign({},r);return\"function\"==typeof t.assignment?n=t.assignment(r,e):Object.keys(t.assignment).forEach((function(i){n[i]=\"function\"==typeof t.assignment[i]?t.assignment[i](r,e):t.assignment[i]})),r=n,!1}return!0})),r,i]}function s(n,i){void 0===i&&(i={});var s=t(f(r(n.states[n.initial].entry).map((function(t){return o(t,i.actions)})),n.context,e),2),l=s[0],v=s[1],y={config:n,_options:i,initialState:{value:n.initial,actions:l,context:v,matches:a(n.initial)},transition:function(e,i){var s,l,v=\"string\"==typeof e?{value:e,context:n.context}:e,p=v.value,g=v.context,d=u(i),x=n.states[p];if(x.on){var m=r(x.on[d.type]);try{for(var h=function(t){var n=\"function\"==typeof Symbol&&Symbol.iterator,e=n&&t[n],r=0;if(e)return e.call(t);if(t&&\"number\"==typeof t.length)return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(n?\"Object is not iterable.\":\"Symbol.iterator is not defined.\")}(m),b=h.next();!b.done;b=h.next()){var S=b.value;if(void 0===S)return c(p,g);var w=\"string\"==typeof S?{target:S}:S,j=w.target,E=w.actions,R=void 0===E?[]:E,N=w.cond,O=void 0===N?function(){return!0}:N,_=void 0===j,k=null!=j?j:p,T=n.states[k];if(O(g,d)){var q=t(f((_?r(R):[].concat(x.exit,R,T.entry).filter((function(t){return t}))).map((function(t){return o(t,y._options.actions)})),g,d),3),z=q[0],A=q[1],B=q[2],C=null!=j?j:p;return{value:C,context:A,actions:z,changed:j!==p||z.length>0||B,matches:a(C)}}}}catch(t){s={error:t}}finally{try{b&&!b.done&&(l=h.return)&&l.call(h)}finally{if(s)throw s.error}}}return c(p,g)}};return y}var l=function(t,n){return t.actions.forEach((function(e){var r=e.exec;return r&&r(t.context,n)}))};function v(t){var r=t.initialState,i=n.NotStarted,o=new Set,c={_machine:t,send:function(e){i===n.Running&&(r=t.transition(r,e),l(r,u(e)),o.forEach((function(t){return t(r)})))},subscribe:function(t){return o.add(t),t(r),{unsubscribe:function(){return o.delete(t)}}},start:function(o){if(o){var u=\"object\"==typeof o?o:{context:t.config.context,value:o};r={value:u.value,actions:[],context:u.context,matches:a(u.value)}}else r=t.initialState;return i=n.Running,l(r,e),c},stop:function(){return i=n.Stopped,o.clear(),c},get state(){return r},get status(){return i}};return c}export{n as InterpreterStatus,i as assign,s as createMachine,v as interpret};\n","import { useLayoutEffect } from 'react';\n\nvar index = useLayoutEffect ;\n\nexport default index;\n","/**\n * @license React\n * use-sync-external-store-shim.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var e=require(\"react\");function h(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var k=\"function\"===typeof Object.is?Object.is:h,l=e.useState,m=e.useEffect,n=e.useLayoutEffect,p=e.useDebugValue;function q(a,b){var d=b(),f=l({inst:{value:d,getSnapshot:b}}),c=f[0].inst,g=f[1];n(function(){c.value=d;c.getSnapshot=b;r(c)&&g({inst:c})},[a,d,b]);m(function(){r(c)&&g({inst:c});return a(function(){r(c)&&g({inst:c})})},[a]);p(d);return d}\nfunction r(a){var b=a.getSnapshot;a=a.value;try{var d=b();return!k(a,d)}catch(f){return!0}}function t(a,b){return b()}var u=\"undefined\"===typeof window||\"undefined\"===typeof window.document||\"undefined\"===typeof window.document.createElement?t:q;exports.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:u;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('../cjs/use-sync-external-store-shim.production.min.js');\n} else {\n module.exports = require('../cjs/use-sync-external-store-shim.development.js');\n}\n","/**\n * @license React\n * use-sync-external-store-shim/with-selector.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var h=require(\"react\"),n=require(\"use-sync-external-store/shim\");function p(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var q=\"function\"===typeof Object.is?Object.is:p,r=n.useSyncExternalStore,t=h.useRef,u=h.useEffect,v=h.useMemo,w=h.useDebugValue;\nexports.useSyncExternalStoreWithSelector=function(a,b,e,l,g){var c=t(null);if(null===c.current){var f={hasValue:!1,value:null};c.current=f}else f=c.current;c=v(function(){function a(a){if(!c){c=!0;d=a;a=l(a);if(void 0!==g&&f.hasValue){var b=f.value;if(g(b,a))return k=b}return k=a}b=k;if(q(d,a))return b;var e=l(a);if(void 0!==g&&g(b,e))return b;d=a;return k=e}var c=!1,d,k,m=void 0===e?null:e;return[function(){return a(b())},null===m?void 0:function(){return a(m())}]},[b,e,l,g]);var d=r(a,c[0],c[1]);\nu(function(){f.hasValue=!0;f.value=d},[d]);w(d);return d};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('../cjs/use-sync-external-store-shim/with-selector.production.min.js');\n} else {\n module.exports = require('../cjs/use-sync-external-store-shim/with-selector.development.js');\n}\n","import * as React from 'react';\nexport default function useConstant(fn) {\n var ref = React.useRef();\n if (!ref.current) {\n ref.current = { v: fn() };\n }\n return ref.current.v;\n}\n","var __read = (this && this.__read) || function (o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n};\nimport { createMachine, interpret, InterpreterStatus } from '@xstate/fsm';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';\nimport useConstant from './useConstant';\nfunction identity(a) {\n return a;\n}\nvar getServiceState = function (service) {\n var currentValue;\n service\n .subscribe(function (state) {\n currentValue = state;\n })\n .unsubscribe();\n return currentValue;\n};\nexport function useMachine(stateMachine, options) {\n var persistedStateRef = useRef();\n if (process.env.NODE_ENV !== 'production') {\n var _a = __read(useState(stateMachine), 1), initialMachine = _a[0];\n if (stateMachine !== initialMachine) {\n console.warn('Machine given to `useMachine` has changed between renders. This is not supported and might lead to unexpected results.\\n' +\n 'Please make sure that you pass the same Machine as argument each time.');\n }\n }\n var _b = __read(useConstant(function () {\n var queue = [];\n var service = interpret(createMachine(stateMachine.config, options ? options : stateMachine._options));\n var send = service.send;\n service.send = function (event) {\n if (service.status === InterpreterStatus.NotStarted) {\n queue.push(event);\n return;\n }\n send(event);\n persistedStateRef.current = service.state;\n };\n return [service, queue];\n }), 2), service = _b[0], queue = _b[1];\n useIsomorphicLayoutEffect(function () {\n if (options) {\n service._machine._options = options;\n }\n });\n var useServiceResult = useService(service);\n useEffect(function () {\n service.start(persistedStateRef.current);\n queue.forEach(service.send);\n persistedStateRef.current = service.state;\n return function () {\n service.stop();\n };\n }, []);\n return useServiceResult;\n}\nvar isEqual = function (_prevState, nextState) { return nextState.changed === false; };\nexport function useService(service) {\n var getSnapshot = useCallback(function () { return getServiceState(service); }, [service]);\n var subscribe = useCallback(function (handleStoreChange) {\n var unsubscribe = service.subscribe(handleStoreChange).unsubscribe;\n return unsubscribe;\n }, [service]);\n var storeSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);\n return [storeSnapshot, service.send, service];\n}\n","import type {PartialDeep} from 'type-fest';\n\n/**\n * The `flattenConnection` utility transforms a connection object from the Storefront API (for example, [Product-related connections](https://shopify.dev/api/storefront/reference/products/product)) into a flat array of nodes.\n * The utility works with either `nodes` or `edges.node`.\n *\n * If `connection` is null or undefined, will return an empty array instead in production. In development, an error will be thrown.\n */\nexport function flattenConnection<\n ConnectionGeneric extends\n | PartialDeep<ConnectionEdges, {recurseIntoArrays: true}>\n | PartialDeep<ConnectionNodes, {recurseIntoArrays: true}>\n | ConnectionEdges\n | ConnectionNodes,\n>(\n connection?: ConnectionGeneric,\n): ConnectionGeneric extends\n | {\n edges: Array<{node: infer ConnectionBaseType}>;\n }\n | {\n nodes: Array<infer ConnectionBaseType>;\n }\n ? // if it's not a PartialDeep, then return the infered type\n ConnectionBaseType[]\n : ConnectionGeneric extends\n | PartialDeep<\n {edges: {node: Array<infer ConnectionBaseType>}},\n {recurseIntoArrays: true}\n >\n | PartialDeep<\n {\n nodes: Array<infer ConnectionBaseType>;\n },\n {recurseIntoArrays: true}\n >\n ? // if it is a PartialDeep, return a PartialDeep inferred type\n PartialDeep<ConnectionBaseType[], {recurseIntoArrays: true}>\n : never {\n if (!connection) {\n const noConnectionErr = `flattenConnection(): needs a 'connection' to flatten, but received '${\n connection ?? ''\n }' instead.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noConnectionErr);\n } else {\n console.error(noConnectionErr + ` Returning an empty array`);\n // @ts-expect-error We don't want to crash prod, so return an empty array\n return [];\n }\n }\n\n if ('nodes' in connection) {\n // @ts-expect-error return type is failing\n return connection.nodes;\n }\n\n if ('edges' in connection && Array.isArray(connection.edges)) {\n // @ts-expect-error return type is failing\n return connection.edges.map((edge) => {\n if (!edge?.node) {\n throw new Error(\n 'flattenConnection(): Connection edges must contain nodes',\n );\n }\n return edge.node;\n }) as Array<unknown>;\n }\n\n if (__HYDROGEN_DEV__) {\n console.warn(\n `flattenConnection(): The connection did not contain either \"nodes\" or \"edges.node\". Returning an empty array.`,\n );\n }\n\n // @ts-expect-error We don't want to crash prod, so return an empty array\n return [];\n}\n\ntype ConnectionEdges = {\n edges: Array<{node: unknown}>;\n};\n\ntype ConnectionNodes = {\n nodes: Array<unknown>;\n};\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface ConnectionGenericForDoc {\n connection?: ConnectionEdges | ConnectionNodes;\n}\nexport type FlattenConnectionReturnForDoc = Array<unknown>;\n","export const CartLineAdd = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineAdd(\n $cartId: ID!\n $lines: [CartLineInput!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesAdd(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartCreate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartCreate(\n $input: CartInput!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartCreate(input: $input) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartLineRemove = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineRemove(\n $cartId: ID!\n $lines: [ID!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesRemove(cartId: $cartId, lineIds: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartLineUpdate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineUpdate(\n $cartId: ID!\n $lines: [CartLineUpdateInput!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesUpdate(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartNoteUpdate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartNoteUpdate(\n $cartId: ID!\n $note: String!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartNoteUpdate(cartId: $cartId, note: $note) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartBuyerIdentityUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartBuyerIdentityUpdate(\n $cartId: ID!\n $buyerIdentity: CartBuyerIdentityInput!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartBuyerIdentityUpdate(cartId: $cartId, buyerIdentity: $buyerIdentity) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartAttributesUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartAttributesUpdate(\n $attributes: [AttributeInput!]!\n $cartId: ID!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartAttributesUpdate(attributes: $attributes, cartId: $cartId) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartDiscountCodesUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartDiscountCodesUpdate(\n $cartId: ID!\n $discountCodes: [String!]\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartQuery = (cartFragment: string): string => /* GraphQL */ `\n query CartQuery(\n $id: ID!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cart(id: $id) {\n ...CartFragment\n }\n }\n\n ${cartFragment}\n`;\n\nexport const defaultCartFragment = /* GraphQL */ `\n fragment CartFragment on Cart {\n id\n checkoutUrl\n totalQuantity\n buyerIdentity {\n countryCode\n customer {\n id\n email\n firstName\n lastName\n displayName\n }\n email\n phone\n }\n lines(first: $numCartLines) {\n edges {\n node {\n id\n quantity\n attributes {\n key\n value\n }\n cost {\n totalAmount {\n amount\n currencyCode\n }\n compareAtAmountPerQuantity {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n availableForSale\n compareAtPrice {\n ...MoneyFragment\n }\n price {\n ...MoneyFragment\n }\n requiresShipping\n title\n image {\n ...ImageFragment\n }\n product {\n handle\n title\n id\n }\n selectedOptions {\n name\n value\n }\n }\n }\n }\n }\n }\n cost {\n subtotalAmount {\n ...MoneyFragment\n }\n totalAmount {\n ...MoneyFragment\n }\n totalDutyAmount {\n ...MoneyFragment\n }\n totalTaxAmount {\n ...MoneyFragment\n }\n }\n note\n attributes {\n key\n value\n }\n discountCodes {\n code\n applicable\n }\n }\n\n fragment MoneyFragment on MoneyV2 {\n currencyCode\n amount\n }\n fragment ImageFragment on Image {\n id\n url\n altText\n width\n height\n }\n`;\n","export const SFAPI_VERSION = '2024-10';\n","import {SFAPI_VERSION} from './storefront-api-constants.js';\n\nexport type StorefrontClientProps = {\n /** The host name of the domain (eg: `{shop}.myshopify.com`). */\n storeDomain?: string;\n /** The Storefront API delegate access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) and [delegate access token](https://shopify.dev/apps/auth/oauth/delegate-access-tokens) documentation for more details. */\n privateStorefrontToken?: string;\n /** The Storefront API access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n publicStorefrontToken?: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen React was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion?: string;\n /**\n * Customizes which `\"content-type\"` header is added when using `getPrivateTokenHeaders()` and `getPublicTokenHeaders()`. When fetching with a `JSON.stringify()`-ed `body`, use `\"json\"`. When fetching with a `body` that is a plain string, use `\"graphql\"`. Defaults to `\"json\"`\n *\n * Can also be customized on a call-by-call basis by passing in `'contentType'` to both `getPrivateTokenHeaders({...})` and `getPublicTokenHeaders({...})`, for example: `getPublicTokenHeaders({contentType: 'graphql'})`\n */\n contentType?: 'json' | 'graphql';\n};\n\nconst MOCK_SHOP_DOMAIN = 'mock.shop';\nconst isMockShop = (domain: string): boolean =>\n domain.includes(MOCK_SHOP_DOMAIN);\n\n/**\n * The `createStorefrontClient()` function creates helpers that enable you to quickly query the Shopify Storefront API.\n *\n * When used on the server, it is recommended to use the `privateStorefrontToken` prop. When used on the client, it is recommended to use the `publicStorefrontToken` prop.\n */\nexport function createStorefrontClient({\n storeDomain,\n privateStorefrontToken,\n publicStorefrontToken,\n storefrontApiVersion = SFAPI_VERSION,\n contentType,\n}: StorefrontClientProps): StorefrontClientReturn {\n if (!storeDomain) {\n if (__HYDROGEN_DEV__) {\n storeDomain = MOCK_SHOP_DOMAIN;\n warnOnce(\n `storeDomain missing, defaulting to ${MOCK_SHOP_DOMAIN}`,\n 'info',\n );\n } else {\n throw new Error(\n H2_PREFIX_ERROR +\n `\\`storeDomain\\` is required when creating a new Storefront client in production.`,\n );\n }\n }\n\n if (storefrontApiVersion !== SFAPI_VERSION) {\n warnOnce(\n `The Storefront API version that you're using is different than the version this build of Hydrogen React is targeting.` +\n `\\nYou may run into unexpected errors if these versions don't match. Received version: \"${storefrontApiVersion}\"; expected version \"${SFAPI_VERSION}\"`,\n );\n }\n\n // only warn if not in a browser environment\n if (\n __HYDROGEN_DEV__ &&\n !privateStorefrontToken &&\n !globalThis.document &&\n !isMockShop(storeDomain)\n ) {\n warnOnce(\n `Using a private storefront token is recommended for server environments.` +\n `\\nRefer to the authentication https://shopify.dev/api/storefront#authentication documentation for more details.`,\n );\n }\n\n // only warn if in a browser environment and you're using the privateStorefrontToken\n if (__HYDROGEN_DEV__ && privateStorefrontToken && globalThis.document) {\n warnOnce(\n 'You are attempting to use a private token in an environment where it can be easily accessed by anyone.' +\n '\\nThis is a security risk; please use the public token and the `publicStorefrontToken` prop',\n );\n }\n\n const getShopifyDomain: StorefrontClientReturn['getShopifyDomain'] = (\n overrideProps,\n ) => {\n const domain = overrideProps?.storeDomain ?? storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n };\n\n return {\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const domain = getShopifyDomain(overrideProps);\n const apiUrl = domain + (domain.endsWith('/') ? 'api' : '/api');\n\n if (isMockShop(domain)) return apiUrl;\n\n return `${apiUrl}/${\n overrideProps?.storefrontApiVersion ?? storefrontApiVersion\n }/graphql.json`;\n },\n getPrivateTokenHeaders(overrideProps): Record<string, string> {\n if (\n !privateStorefrontToken &&\n !overrideProps?.privateStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `privateStorefrontToken` while using `createStorefrontClient()` or `getPrivateTokenHeaders()`',\n );\n }\n\n if (__HYDROGEN_DEV__ && !overrideProps?.buyerIp) {\n warnOnce(\n 'It is recommended to pass in the `buyerIp` property which improves analytics and data in the admin.',\n );\n }\n\n const finalContentType = overrideProps?.contentType ?? contentType;\n\n return {\n // default to json\n 'content-type':\n finalContentType === 'graphql'\n ? 'application/graphql'\n : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'Shopify-Storefront-Private-Token':\n overrideProps?.privateStorefrontToken ?? privateStorefrontToken ?? '',\n ...(overrideProps?.buyerIp\n ? {'Shopify-Storefront-Buyer-IP': overrideProps.buyerIp}\n : {}),\n };\n },\n getPublicTokenHeaders(overrideProps): Record<string, string> {\n if (\n !publicStorefrontToken &&\n !overrideProps?.publicStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `publicStorefrontToken` while using `createStorefrontClient()` or `getPublicTokenHeaders()`',\n );\n }\n\n const finalContentType =\n overrideProps?.contentType ?? contentType ?? 'json';\n\n return getPublicTokenHeadersRaw(\n finalContentType,\n storefrontApiVersion,\n overrideProps?.publicStorefrontToken ?? publicStorefrontToken ?? '',\n );\n },\n };\n}\n\nexport function getPublicTokenHeadersRaw(\n contentType: 'graphql' | 'json',\n storefrontApiVersion: string,\n accessToken: string,\n): {\n 'content-type': string;\n 'X-SDK-Variant': string;\n 'X-SDK-Variant-Source': string;\n 'X-SDK-Version': string;\n 'X-Shopify-Storefront-Access-Token': string;\n} {\n return {\n // default to json\n 'content-type':\n contentType === 'graphql' ? 'application/graphql' : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'X-Shopify-Storefront-Access-Token': accessToken,\n };\n}\n\nconst warnings = new Set<string>();\nconst H2_PREFIX_ERROR = '[h2:error:createStorefrontClient] ';\nconst warnOnce = (string: string, type: 'warn' | 'info' = 'warn'): void => {\n if (!warnings.has(string)) {\n console[type](`[h2:${type}:createStorefrontClient] ` + string);\n warnings.add(string);\n }\n};\n\ntype OverrideTokenHeaderProps = Partial<\n Pick<StorefrontClientProps, 'contentType'>\n>;\n\ntype StorefrontClientReturn = {\n /**\n * Creates the fully-qualified URL to your myshopify.com domain.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getShopifyDomain({...})`:\n *\n * - `storeDomain`\n */\n getShopifyDomain: (\n props?: Partial<Pick<StorefrontClientProps, 'storeDomain'>>,\n ) => string;\n /**\n * Creates the fully-qualified URL to your store's GraphQL endpoint.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getStorefrontApiUrl({...})`:\n *\n * - `storeDomain`\n * - `storefrontApiVersion`\n */\n getStorefrontApiUrl: (\n props?: Partial<\n Pick<StorefrontClientProps, 'storeDomain' | 'storefrontApiVersion'>\n >,\n ) => string;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This method uses the private Server-to-Server token which reduces the chance of throttling but must not be exposed to clients. Server-side calls should prefer using this over `getPublicTokenHeaders()`.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getPrivateTokenHeaders({...})`:\n *\n * - `contentType`\n * - `privateStorefrontToken`\n * - `buyerIp`\n *\n * Note that `contentType` defaults to what you configured in `createStorefrontClient({...})` and defaults to `'json'`, but a specific call may require using `graphql`. When using `JSON.stringify()` on the `body`, use `'json'`; otherwise, use `'graphql'`.\n */\n getPrivateTokenHeaders: (\n props?: OverrideTokenHeaderProps &\n Pick<StorefrontClientProps, 'privateStorefrontToken'> & {\n /**\n * The client's IP address. Passing this to the Storefront API when using a server-to-server token will help improve your store's analytics data.\n */\n buyerIp?: string;\n },\n ) => Record<string, string>;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This method uses the public token which increases the chance of throttling but also can be exposed to clients. Server-side calls should prefer using `getPublicTokenHeaders()`.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getPublicTokenHeaders({...})`:\n *\n * - `contentType`\n * - `publicStorefrontToken`\n *\n * Note that `contentType` defaults to what you configured in `createStorefrontClient({...})` and defaults to `'json'`, but a specific call may require using `graphql`. When using `JSON.stringify()` on the `body`, use `'json'`; otherwise, use `'graphql'`.\n */\n getPublicTokenHeaders: (\n props?: OverrideTokenHeaderProps &\n Pick<StorefrontClientProps, 'publicStorefrontToken'>,\n ) => Record<string, string>;\n};\n","import {createContext, useContext, useMemo, type ReactNode} from 'react';\nimport type {LanguageCode, CountryCode} from './storefront-api-types.js';\nimport {SFAPI_VERSION} from './storefront-api-constants.js';\nimport {getPublicTokenHeadersRaw} from './storefront-client.js';\n\nexport const defaultShopifyContext: ShopifyContextValue = {\n storeDomain: 'test',\n storefrontToken: 'abc123',\n storefrontApiVersion: SFAPI_VERSION,\n countryIsoCode: 'US',\n languageIsoCode: 'EN',\n getStorefrontApiUrl() {\n return '';\n },\n getPublicTokenHeaders() {\n return {};\n },\n getShopifyDomain() {\n return '';\n },\n};\n\nconst ShopifyContext = createContext<ShopifyContextValue>(\n defaultShopifyContext,\n);\n\n/**\n * The `<ShopifyProvider/>` component enables use of the `useShop()` hook. The component should wrap your app.\n */\nexport function ShopifyProvider({\n children,\n ...shopifyConfig\n}: ShopifyProviderProps): JSX.Element {\n if (\n !shopifyConfig.countryIsoCode ||\n !shopifyConfig.languageIsoCode ||\n !shopifyConfig.storeDomain ||\n !shopifyConfig.storefrontToken ||\n !shopifyConfig.storefrontApiVersion\n ) {\n throw new Error(\n `Please provide the necessary props to '<ShopifyProvider/>'`,\n );\n }\n\n if (shopifyConfig.storefrontApiVersion !== SFAPI_VERSION) {\n console.warn(\n `<ShopifyProvider/>: This version of Hydrogen React is built for Shopify's Storefront API version ${SFAPI_VERSION}, but it looks like you're using version ${shopifyConfig.storefrontApiVersion}. There may be issues or bugs if you use a mismatched version of Hydrogen React and the Storefront API.`,\n );\n }\n\n const finalConfig = useMemo<ShopifyContextValue>(() => {\n function getShopifyDomain(overrideProps?: {storeDomain?: string}): string {\n const domain = overrideProps?.storeDomain ?? shopifyConfig.storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n }\n\n return {\n ...shopifyConfig,\n getPublicTokenHeaders(overrideProps): Record<string, string> {\n return getPublicTokenHeadersRaw(\n overrideProps.contentType,\n shopifyConfig.storefrontApiVersion,\n overrideProps.storefrontToken ?? shopifyConfig.storefrontToken,\n );\n },\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const finalDomainUrl = getShopifyDomain({\n storeDomain: overrideProps?.storeDomain ?? shopifyConfig.storeDomain,\n });\n return `${finalDomainUrl}${\n finalDomainUrl.endsWith('/') ? '' : '/'\n }api/${\n overrideProps?.storefrontApiVersion ??\n shopifyConfig.storefrontApiVersion\n }/graphql.json`;\n },\n };\n }, [shopifyConfig]);\n\n return (\n <ShopifyContext.Provider value={finalConfig}>\n {children}\n </ShopifyContext.Provider>\n );\n}\n\n/**\n * Provides access to the `shopifyConfig` prop of `<ShopifyProvider/>`. Must be a descendent of `<ShopifyProvider/>`.\n */\nexport function useShop(): ShopifyContextValue {\n const shopContext = useContext(ShopifyContext);\n if (!shopContext) {\n throw new Error(`'useShop()' must be a descendent of <ShopifyProvider/>`);\n }\n return shopContext;\n}\n\nexport interface ShopifyProviderBase {\n /** The globally-unique identifier for the Shop */\n storefrontId?: string;\n /** The full domain of your Shopify storefront URL (eg: the complete string of `{subdomain}.myshopify.com`). */\n storeDomain: string;\n /** The Storefront API public access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n storefrontToken: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen React was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion: string;\n /**\n * The code designating a country, which generally follows ISO 3166-1 alpha-2 guidelines. If a territory doesn't have a country code value in the `CountryCode` enum, it might be considered a subdivision of another country. For example, the territories associated with Spain are represented by the country code `ES`, and the territories associated with the United States of America are represented by the country code `US`.\n */\n countryIsoCode: CountryCode;\n /**\n * `ISO 369` language codes supported by Shopify.\n */\n languageIsoCode: LanguageCode;\n}\n\n/**\n * Shopify-specific values that are used in various Hydrogen React components and hooks.\n */\nexport interface ShopifyProviderProps extends ShopifyProviderBase {\n /** React children to render. */\n children?: ReactNode;\n}\n\nexport interface ShopifyContextValue\n extends ShopifyProviderBase,\n ShopifyContextReturn {}\n\ntype ShopifyContextReturn = {\n /**\n * Creates the fully-qualified URL to your store's GraphQL endpoint.\n *\n * By default, it will use the config you passed in when creating `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getStorefrontApiUrl({...})`:\n *\n * - `storeDomain`\n * - `storefrontApiVersion`\n */\n getStorefrontApiUrl: (props?: GetStorefrontApiUrlProps) => string;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This uses the public Storefront API token.\n *\n * By default, it will use the config you passed in when creating `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getPublicTokenHeaders({...})`:\n *\n * - `contentType`\n * - `storefrontToken`\n *\n */\n getPublicTokenHeaders: (\n props: GetPublicTokenHeadersProps,\n ) => Record<string, string>;\n /**\n * Creates the fully-qualified URL to your myshopify.com domain.\n *\n * By default, it will use the config you passed in when calling `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getShopifyDomain({...})`:\n *\n * - `storeDomain`\n */\n getShopifyDomain: (props?: GetShopifyDomainProps) => string;\n};\n\ntype GetStorefrontApiUrlProps = {\n /** The host name of the domain (eg: `{shop}.myshopify.com`). */\n storeDomain?: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen-UI was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion?: string;\n};\n\ntype GetPublicTokenHeadersProps = {\n /**\n * Customizes which `\"content-type\"` header is added when using `getPrivateTokenHeaders()` and `getPublicTokenHeaders()`. When fetching with a `JSON.stringify()`-ed `body`, use `\"json\"`. When fetching with a `body` that is a plain string, use `\"graphql\"`. Defaults to `\"json\"`\n */\n contentType: 'json' | 'graphql';\n /** The Storefront API access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n storefrontToken?: string;\n};\n\ntype GetShopifyDomainProps = {storeDomain?: string};\n","export const CART_ID_STORAGE_KEY = 'shopifyCartId';\nexport const CART_COOKIE_TTL_DAYS = 14;\n\n// Needed for cart analytics within Shopify\nexport const SHOPIFY_STOREFRONT_ID_HEADER = 'Shopify-Storefront-Id';\nexport const SHOPIFY_STOREFRONT_Y_HEADER = 'Shopify-Storefront-Y';\nexport const SHOPIFY_STOREFRONT_S_HEADER = 'Shopify-Storefront-S';\nexport const SHOPIFY_Y = '_shopify_y';\nexport const SHOPIFY_S = '_shopify_s';\n","// src/cookie.ts\nvar g = new Set([\n \"domain\",\n \"path\",\n \"max-age\",\n \"expires\",\n \"samesite\",\n \"secure\",\n \"httponly\"\n]);\nfunction u(a) {\n let r = {}, e, t, n = 0, m = a.split(/;\\s*/g), s, i;\n for (; n < m.length; n++)\n if (t = m[n], e = t.indexOf(\"=\"), ~e) {\n if (s = t.substring(0, e++).trim(), i = t.substring(e).trim(), i[0] === '\"' && (i = i.substring(1, i.length - 1)), ~i.indexOf(\"%\"))\n try {\n i = decodeURIComponent(i);\n } catch (f) {\n }\n g.has(t = s.toLowerCase()) ? t === \"expires\" ? r.expires = new Date(i) : t === \"max-age\" ? r.maxage = +i : r[t] = i : r[s] = i;\n } else\n (s = t.trim().toLowerCase()) && (s === \"httponly\" || s === \"secure\") && (r[s] = !0);\n return r;\n}\nfunction l(a, r, e = {}) {\n let t = a + \"=\" + encodeURIComponent(r);\n return e.expires && (t += \"; Expires=\" + new Date(e.expires).toUTCString()), e.maxage != null && e.maxage >= 0 && (t += \"; Max-Age=\" + (e.maxage | 0)), e.domain && (t += \"; Domain=\" + e.domain), e.path && (t += \"; Path=\" + e.path), e.samesite && (t += \"; SameSite=\" + e.samesite), (e.secure || e.samesite === \"None\") && (t += \"; Secure\"), e.httponly && (t += \"; HttpOnly\"), t;\n}\nexport {\n u as parse,\n l as stringify\n};\n","import {parse} from 'worktop/cookie';\nimport {ShopifyCookies} from './analytics-types.js';\nimport {SHOPIFY_Y, SHOPIFY_S} from './cart-constants.js';\n\nconst tokenHash = 'xxxx-4xxx-xxxx-xxxxxxxxxxxx';\n\nexport function buildUUID(): string {\n let hash = '';\n\n try {\n const crypto: Crypto = window.crypto;\n const randomValuesArray = new Uint16Array(31);\n crypto.getRandomValues(randomValuesArray);\n\n // Generate a strong UUID\n let i = 0;\n hash = tokenHash\n .replace(/[x]/g, (c: string): string => {\n const r = randomValuesArray[i] % 16;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n i++;\n return v.toString(16);\n })\n .toUpperCase();\n } catch (err) {\n // crypto not available, generate weak UUID\n hash = tokenHash\n .replace(/[x]/g, (c: string): string => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n })\n .toUpperCase();\n }\n\n return `${hexTime()}-${hash}`;\n}\n\nexport function hexTime(): string {\n // 32 bit representations of new Date().getTime() and performance.now()\n let dateNumber = 0;\n let perfNumber = 0;\n\n // Result of zero-fill right shift is always positive\n dateNumber = new Date().getTime() >>> 0;\n\n try {\n perfNumber = performance.now() >>> 0;\n } catch (err) {\n perfNumber = 0;\n }\n\n const output = Math.abs(dateNumber + perfNumber)\n .toString(16)\n .toLowerCase();\n\n // Ensure the output is exactly 8 characters\n return output.padStart(8, '0');\n}\n\nexport function getShopifyCookies(cookies: string): ShopifyCookies {\n const cookieData = parse(cookies);\n return {\n [SHOPIFY_Y]: cookieData[SHOPIFY_Y] || '',\n [SHOPIFY_S]: cookieData[SHOPIFY_S] || '',\n };\n}\n","import {useState, useCallback} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport {CartInput, Cart as CartType} from './storefront-api-types.js';\nimport {CartCreate, defaultCartFragment} from './cart-queries.js';\nimport {Cart} from './cart-types.js';\nimport {\n SHOPIFY_STOREFRONT_ID_HEADER,\n SHOPIFY_STOREFRONT_Y_HEADER,\n SHOPIFY_STOREFRONT_S_HEADER,\n SHOPIFY_Y,\n SHOPIFY_S,\n} from './cart-constants.js';\nimport type {StorefrontApiResponseOkPartial} from './storefront-api-response.types.js';\nimport {getShopifyCookies} from './cookies-utils.js';\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartFetch() {\n const {storefrontId, getPublicTokenHeaders, getStorefrontApiUrl} = useShop();\n\n return useCallback(\n <ReturnDataGeneric,>({\n query,\n variables,\n }: {\n query: string;\n variables: Record<string, unknown>;\n }): Promise<StorefrontApiResponseOkPartial<ReturnDataGeneric>> => {\n const headers = getPublicTokenHeaders({contentType: 'json'});\n\n if (storefrontId) {\n headers[SHOPIFY_STOREFRONT_ID_HEADER] = storefrontId;\n }\n\n // Find Shopify cookies\n const cookieData = getShopifyCookies(document.cookie);\n headers[SHOPIFY_STOREFRONT_Y_HEADER] = cookieData[SHOPIFY_Y];\n headers[SHOPIFY_STOREFRONT_S_HEADER] = cookieData[SHOPIFY_S];\n\n return fetch(getStorefrontApiUrl(), {\n method: 'POST',\n headers,\n body: JSON.stringify({\n query: query.toString(),\n variables,\n }),\n })\n .then(\n (res) =>\n res.json() as StorefrontApiResponseOkPartial<ReturnDataGeneric>,\n )\n .catch((error) => {\n return {\n data: undefined,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n errors: error?.toString(),\n };\n });\n },\n [getPublicTokenHeaders, storefrontId, getStorefrontApiUrl],\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useInstantCheckout() {\n const [cart, updateCart] = useState<Cart | undefined>();\n const [checkoutUrl, updateCheckoutUrl] = useState<Cart['checkoutUrl']>();\n const [error, updateError] = useState<string | undefined>();\n\n const fetch = useCartFetch();\n\n const createInstantCheckout = useCallback(\n async (cartInput: CartInput) => {\n const {data, errors} = await fetch<{\n cartCreate: {cart: CartType};\n }>({\n query: CartCreate(defaultCartFragment),\n variables: {\n input: cartInput,\n },\n });\n\n if (errors) {\n updateError(errors.toString());\n updateCart(undefined);\n updateCheckoutUrl(undefined);\n }\n\n if (data?.cartCreate?.cart) {\n const dataCart = data.cartCreate.cart;\n updateCart({\n ...dataCart,\n lines: flattenConnection(dataCart.lines),\n note: dataCart.note ?? undefined,\n });\n updateCheckoutUrl(dataCart.checkoutUrl);\n }\n },\n [fetch],\n );\n\n return {cart, checkoutUrl, error, createInstantCheckout};\n}\n","import {useCallback, useMemo} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n LanguageCode,\n Cart as CartType,\n MutationCartDiscountCodesUpdateArgs,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n CartAttributesUpdate,\n CartBuyerIdentityUpdate,\n CartCreate,\n CartDiscountCodesUpdate,\n CartLineAdd,\n CartLineRemove,\n CartLineUpdate,\n CartNoteUpdate,\n CartQuery,\n} from './cart-queries.js';\nimport {useCartFetch} from './cart-hooks.js';\nimport {PartialDeep} from 'type-fest';\n\ntype CartResponse = PartialDeep<CartType, {recurseIntoArrays: true}>;\n\n/**\n * The `useCartActions` hook returns helper graphql functions for Storefront Cart API\n *\n * See [cart API graphql mutations](https://shopify.dev/api/storefront/2024-10/objects/Cart)\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartActions({\n numCartLines,\n cartFragment,\n countryCode = 'US',\n languageCode = 'EN',\n}: {\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2024-10/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment: string;\n /** The ISO country code for i18n. Default to `US` */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. Default to `EN` */\n languageCode?: LanguageCode;\n}) {\n const fetchCart = useCartFetch();\n\n const cartFetch = useCallback(\n (cartId: string) => {\n return fetchCart<{cart: CartResponse}>({\n query: CartQuery(cartFragment),\n variables: {\n id: cartId,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [fetchCart, cartFragment, numCartLines, countryCode, languageCode],\n );\n\n const cartCreate = useCallback(\n (cart: CartInput) => {\n return fetchCart<{cartCreate: {cart: CartResponse}}>({\n query: CartCreate(cartFragment),\n variables: {\n input: cart,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineAdd = useCallback(\n (cartId: string, lines: CartLineInput[]) => {\n return fetchCart<{cartLinesAdd: {cart: CartResponse}}>({\n query: CartLineAdd(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineUpdate = useCallback(\n (cartId: string, lines: CartLineUpdateInput[]) => {\n return fetchCart<{cartLinesUpdate: {cart: CartResponse}}>({\n query: CartLineUpdate(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineRemove = useCallback(\n (cartId: string, lines: string[]) => {\n return fetchCart<{cartLinesRemove: {cart: CartResponse}}>({\n query: CartLineRemove(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const noteUpdate = useCallback(\n (cartId: string, note: MutationCartNoteUpdateArgs['note']) => {\n return fetchCart<{cartNoteUpdate: {cart: CartResponse}}>({\n query: CartNoteUpdate(cartFragment),\n variables: {\n cartId,\n note,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [fetchCart, cartFragment, numCartLines, countryCode, languageCode],\n );\n\n const buyerIdentityUpdate = useCallback(\n (cartId: string, buyerIdentity: CartBuyerIdentityInput) => {\n return fetchCart<{cartBuyerIdentityUpdate: {cart: CartResponse}}>({\n query: CartBuyerIdentityUpdate(cartFragment),\n variables: {\n cartId,\n buyerIdentity,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartAttributesUpdate = useCallback(\n (cartId: string, attributes: AttributeInput[]) => {\n return fetchCart<{cartAttributesUpdate: {cart: CartResponse}}>({\n query: CartAttributesUpdate(cartFragment),\n variables: {\n cartId,\n attributes,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const discountCodesUpdate = useCallback(\n (\n cartId: string,\n discountCodes: MutationCartDiscountCodesUpdateArgs['discountCodes'],\n ) => {\n return fetchCart<{cartDiscountCodesUpdate: {cart: CartResponse}}>({\n query: CartDiscountCodesUpdate(cartFragment),\n variables: {\n cartId,\n discountCodes,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n return useMemo(\n () => ({\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n cartFragment,\n }),\n [\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n cartFragment,\n ],\n );\n}\n","import {useMachine} from '@xstate/react/fsm';\nimport {createMachine, assign, StateMachine} from '@xstate/fsm';\nimport {\n Cart,\n CartMachineActionEvent,\n CartMachineActions,\n CartMachineContext,\n CartMachineEvent,\n CartMachineFetchResultEvent,\n CartMachineTypeState,\n} from './cart-types.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport {useCartActions} from './useCartActions.js';\nimport {useMemo} from 'react';\nimport {InitEvent} from '@xstate/fsm/lib/types.js';\nimport {\n CountryCode,\n Cart as CartType,\n LanguageCode,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nfunction invokeCart(\n action: keyof CartMachineActions,\n options?: {\n entryActions?: [keyof CartMachineActions];\n resolveTarget?: CartMachineTypeState['value'];\n errorTarget?: CartMachineTypeState['value'];\n exitActions?: [keyof CartMachineActions];\n },\n): StateMachine.Config<CartMachineContext, CartMachineEvent>['states']['on'] {\n return {\n entry: [\n ...(options?.entryActions || []),\n assign({\n lastValidCart: (context) => context?.cart,\n }),\n 'onCartActionEntry',\n 'onCartActionOptimisticUI',\n action,\n ],\n on: {\n RESOLVE: {\n target: options?.resolveTarget || 'idle',\n actions: [\n assign({\n prevCart: (context) => context?.lastValidCart,\n cart: (_, event) => event?.payload?.cart,\n rawCartResult: (_, event) => event?.payload?.rawCartResult,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n errors: (_) => undefined,\n }),\n ],\n },\n ERROR: {\n target: options?.errorTarget || 'error',\n actions: [\n assign({\n prevCart: (context) => context?.lastValidCart,\n cart: (context) => context?.lastValidCart,\n errors: (_, event) => event?.payload?.errors,\n }),\n ],\n },\n CART_COMPLETED: {\n target: 'cartCompleted',\n actions: assign({\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n prevCart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n cart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n lastValidCart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n rawCartResult: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n errors: (_) => undefined,\n }),\n },\n },\n exit: ['onCartActionComplete', ...(options?.exitActions || [])],\n };\n}\n\nconst INITIALIZING_CART_EVENTS: StateMachine.Machine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n>['config']['states']['uninitialized']['on'] = {\n CART_FETCH: {\n target: 'cartFetching',\n },\n CART_CREATE: {\n target: 'cartCreating',\n },\n CART_SET: {\n target: 'idle',\n actions: [\n assign({\n rawCartResult: (_, event) => event.payload.cart,\n cart: (_, event) => cartFromGraphQL(event.payload.cart),\n }),\n ],\n },\n};\n\nconst UPDATING_CART_EVENTS: StateMachine.Machine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n>['config']['states']['idle']['on'] = {\n CARTLINE_ADD: {\n target: 'cartLineAdding',\n },\n CARTLINE_UPDATE: {\n target: 'cartLineUpdating',\n },\n CARTLINE_REMOVE: {\n target: 'cartLineRemoving',\n },\n NOTE_UPDATE: {\n target: 'noteUpdating',\n },\n BUYER_IDENTITY_UPDATE: {\n target: 'buyerIdentityUpdating',\n },\n CART_ATTRIBUTES_UPDATE: {\n target: 'cartAttributesUpdating',\n },\n DISCOUNT_CODES_UPDATE: {\n target: 'discountCodesUpdating',\n },\n};\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction createCartMachine(\n initialCart?: PartialDeep<CartType, {recurseIntoArrays: true}>,\n) {\n return createMachine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n >({\n id: 'Cart',\n initial: initialCart ? 'idle' : 'uninitialized',\n context: {\n cart: initialCart && cartFromGraphQL(initialCart),\n },\n states: {\n uninitialized: {\n on: INITIALIZING_CART_EVENTS,\n },\n cartCompleted: {\n on: INITIALIZING_CART_EVENTS,\n },\n initializationError: {\n on: INITIALIZING_CART_EVENTS,\n },\n idle: {\n on: {...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS},\n },\n error: {\n on: {...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS},\n },\n cartFetching: invokeCart('cartFetchAction', {\n errorTarget: 'initializationError',\n }),\n cartCreating: invokeCart('cartCreateAction', {\n errorTarget: 'initializationError',\n }),\n cartLineRemoving: invokeCart('cartLineRemoveAction'),\n cartLineUpdating: invokeCart('cartLineUpdateAction'),\n cartLineAdding: invokeCart('cartLineAddAction'),\n noteUpdating: invokeCart('noteUpdateAction'),\n buyerIdentityUpdating: invokeCart('buyerIdentityUpdateAction'),\n cartAttributesUpdating: invokeCart('cartAttributesUpdateAction'),\n discountCodesUpdating: invokeCart('discountCodesUpdateAction'),\n },\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartAPIStateMachine({\n numCartLines,\n onCartActionEntry,\n onCartActionOptimisticUI,\n onCartActionComplete,\n data: cart,\n cartFragment,\n countryCode,\n languageCode,\n}: {\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked just before a Cart API action executes. */\n onCartActionEntry?: (\n context: CartMachineContext,\n event: CartMachineActionEvent,\n ) => void;\n /** A callback that is invoked after executing the entry actions for optimistic UI changes. */\n onCartActionOptimisticUI?: (\n context: CartMachineContext,\n event: CartMachineEvent,\n ) => Partial<CartMachineContext>;\n /** A callback that is invoked after a Cart API completes. */\n onCartActionComplete?: (\n context: CartMachineContext,\n event: CartMachineFetchResultEvent,\n ) => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/2024-10/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2024-10/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment: string;\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. */\n languageCode?: LanguageCode;\n}) {\n const {\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n } = useCartActions({\n numCartLines,\n cartFragment,\n countryCode,\n languageCode,\n });\n\n const cartMachine = useMemo(() => createCartMachine(cart), [cart]);\n\n const [state, send, service] = useMachine(cartMachine, {\n actions: {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartFetchAction: async (_, event) => {\n if (event.type !== 'CART_FETCH') return;\n\n const {data, errors} = await cartFetch(event?.payload?.cartId);\n const resultEvent = eventFromFetchResult(event, data?.cart, errors);\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartCreateAction: async (_, event) => {\n if (event.type !== 'CART_CREATE') return;\n\n const {data, errors} = await cartCreate(event?.payload);\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartCreate?.cart,\n errors,\n );\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineAddAction: async (context, event) => {\n if (event.type !== 'CARTLINE_ADD' || !context?.cart?.id) return;\n\n const {data, errors} = await cartLineAdd(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesAdd?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineUpdateAction: async (context, event) => {\n if (event.type !== 'CARTLINE_UPDATE' || !context?.cart?.id) return;\n const {data, errors} = await cartLineUpdate(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineRemoveAction: async (context, event) => {\n if (event.type !== 'CARTLINE_REMOVE' || !context?.cart?.id) return;\n const {data, errors} = await cartLineRemove(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesRemove?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n noteUpdateAction: async (context, event) => {\n if (event.type !== 'NOTE_UPDATE' || !context?.cart?.id) return;\n const {data, errors} = await noteUpdate(\n context.cart.id,\n event.payload.note,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartNoteUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n buyerIdentityUpdateAction: async (context, event) => {\n if (event.type !== 'BUYER_IDENTITY_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await buyerIdentityUpdate(\n context.cart.id,\n event.payload.buyerIdentity,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartBuyerIdentityUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartAttributesUpdateAction: async (context, event) => {\n if (event.type !== 'CART_ATTRIBUTES_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await cartAttributesUpdate(\n context.cart.id,\n event.payload.attributes,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartAttributesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n discountCodesUpdateAction: async (context, event) => {\n if (event.type !== 'DISCOUNT_CODES_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await discountCodesUpdate(\n context.cart.id,\n event.payload.discountCodes,\n );\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartDiscountCodesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n ...(onCartActionEntry && {\n onCartActionEntry: (context, event): void => {\n if (isCartActionEvent(event)) {\n onCartActionEntry(context, event);\n }\n },\n }),\n ...(onCartActionOptimisticUI && {\n onCartActionOptimisticUI: assign((context, event) => {\n return onCartActionOptimisticUI(context, event);\n }),\n }),\n ...(onCartActionComplete && {\n onCartActionComplete: (context, event): void => {\n if (isCartFetchResultEvent(event)) {\n onCartActionComplete(context, event);\n }\n },\n }),\n } as CartMachineActions,\n });\n\n return useMemo(() => [state, send, service] as const, [state, send, service]);\n}\n\nexport function cartFromGraphQL(\n cart: PartialDeep<CartType, {recurseIntoArrays: true}>,\n): Cart {\n return {\n ...cart,\n lines: flattenConnection(cart?.lines),\n note: cart.note ?? undefined,\n };\n}\n\nfunction eventFromFetchResult(\n cartActionEvent: CartMachineActionEvent,\n cart?: PartialDeep<CartType, {recurseIntoArrays: true}> | null,\n errors?: unknown,\n): CartMachineFetchResultEvent {\n if (errors) {\n return {type: 'ERROR', payload: {errors, cartActionEvent}};\n }\n\n if (!cart) {\n return {\n type: 'CART_COMPLETED',\n payload: {\n cartActionEvent,\n },\n };\n }\n\n return {\n type: 'RESOLVE',\n payload: {\n cart: cartFromGraphQL(cart),\n rawCartResult: cart,\n cartActionEvent,\n },\n };\n}\n\nfunction isCartActionEvent(\n event: CartMachineEvent | InitEvent,\n): event is CartMachineActionEvent {\n return (\n event.type === 'CART_CREATE' ||\n event.type === 'CARTLINE_ADD' ||\n event.type === 'CARTLINE_UPDATE' ||\n event.type === 'CARTLINE_REMOVE' ||\n event.type === 'NOTE_UPDATE' ||\n event.type === 'BUYER_IDENTITY_UPDATE' ||\n event.type === 'CART_ATTRIBUTES_UPDATE' ||\n event.type === 'DISCOUNT_CODES_UPDATE'\n );\n}\n\nfunction isCartFetchResultEvent(\n event: CartMachineEvent | InitEvent,\n): event is CartMachineFetchResultEvent {\n return (\n event.type === 'RESOLVE' ||\n event.type === 'ERROR' ||\n event.type === 'CART_COMPLETED'\n );\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n createContext,\n useContext,\n} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n LanguageCode,\n Cart as CartType,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n BuyerIdentityUpdateEvent,\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState,\n CartWithActions,\n CartWithActionsDocs,\n} from './cart-types.js';\nimport {useCartAPIStateMachine} from './useCartAPIStateMachine.js';\nimport {CART_ID_STORAGE_KEY} from './cart-constants.js';\nimport {PartialDeep} from 'type-fest';\nimport {defaultCartFragment} from './cart-queries.js';\nimport {useShop} from './ShopifyProvider.js';\n\nexport const CartContext = createContext<CartWithActions | null>(null);\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype UseCartDocs = () => CartWithActionsDocs;\n\n/**\n * The `useCart` hook provides access to the cart object. It must be a descendent of a `CartProvider` component.\n */\nexport function useCart(): CartWithActions {\n const context = useContext(CartContext);\n\n if (!context) {\n throw new Error('Expected a Cart Context, but no Cart Context was found');\n }\n\n return context;\n}\n\ntype CartProviderProps = {\n /** Any `ReactNode` elements. */\n children: React.ReactNode;\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. */\n onCreate?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. */\n onLineAdd?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. */\n onLineRemove?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. */\n onLineUpdate?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. */\n onNoteUpdate?: () => void;\n /** A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. */\n onBuyerIdentityUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. */\n onAttributesUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. */\n onDiscountCodesUpdate?: () => void;\n /** A callback that is invoked when the process to create a cart completes */\n onCreateComplete?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart completes */\n onLineAddComplete?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart completes */\n onLineRemoveComplete?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart completes */\n onLineUpdateComplete?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart completes */\n onNoteUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the buyer identity completes */\n onBuyerIdentityUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart attributes completes */\n onAttributesUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes completes */\n onDiscountCodesUpdateComplete?: () => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/2024-10/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2024-10/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment?: string;\n /** A customer access token that's accessible on the server if there's a customer login. */\n customerAccessToken?: CartBuyerIdentityInput['customerAccessToken'];\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. */\n languageCode?: LanguageCode;\n};\n\n/**\n * The `CartProvider` component synchronizes the state of the Storefront API Cart and a customer's cart,\n * and allows you to more easily manipulate the cart by adding, removing, and updating it.\n * It could be placed at the root of your app so that your whole app is able to use the `useCart()` hook anywhere.\n *\n * There are props that trigger when a call to the Storefront API is made, such as `onLineAdd={}` when a line is added to the cart.\n * There are also props that trigger when a call to the Storefront API is completed, such as `onLineAddComplete={}` when the fetch request for adding a line to the cart completes.\n *\n * The `CartProvider` component must be a descendant of the `ShopifyProvider` component.\n */\nexport function CartProvider({\n children,\n numCartLines,\n onCreate,\n onLineAdd,\n onLineRemove,\n onLineUpdate,\n onNoteUpdate,\n onBuyerIdentityUpdate,\n onAttributesUpdate,\n onDiscountCodesUpdate,\n onCreateComplete,\n onLineAddComplete,\n onLineRemoveComplete,\n onLineUpdateComplete,\n onNoteUpdateComplete,\n onBuyerIdentityUpdateComplete,\n onAttributesUpdateComplete,\n onDiscountCodesUpdateComplete,\n data: cart,\n cartFragment = defaultCartFragment,\n customerAccessToken,\n countryCode,\n languageCode,\n}: CartProviderProps): JSX.Element {\n const shop = useShop();\n\n if (!shop)\n throw new Error(\n '<CartProvider> needs to be a descendant of <ShopifyProvider>',\n );\n\n countryCode = (\n (countryCode as string) ??\n shop.countryIsoCode ??\n 'US'\n ).toUpperCase() as CountryCode;\n\n languageCode = (\n (languageCode as string) ??\n shop.languageIsoCode ??\n 'EN'\n ).toUpperCase() as LanguageCode;\n\n if (countryCode) countryCode = countryCode.toUpperCase() as CountryCode;\n\n const [prevCountryCode, setPrevCountryCode] = useState(countryCode);\n const [prevCustomerAccessToken, setPrevCustomerAccessToken] =\n useState(customerAccessToken);\n const customerOverridesCountryCode = useRef(false);\n\n if (\n prevCountryCode !== countryCode ||\n prevCustomerAccessToken !== customerAccessToken\n ) {\n setPrevCountryCode(countryCode);\n setPrevCustomerAccessToken(customerAccessToken);\n customerOverridesCountryCode.current = false;\n }\n\n const [cartState, cartSend] = useCartAPIStateMachine({\n numCartLines,\n data: cart,\n cartFragment,\n countryCode,\n languageCode,\n onCartActionEntry(_, event) {\n try {\n switch (event.type) {\n case 'CART_CREATE':\n return onCreate?.();\n case 'CARTLINE_ADD':\n return onLineAdd?.();\n case 'CARTLINE_REMOVE':\n return onLineRemove?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdate?.();\n case 'NOTE_UPDATE':\n return onNoteUpdate?.();\n case 'BUYER_IDENTITY_UPDATE':\n return onBuyerIdentityUpdate?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdate?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdate?.();\n }\n } catch (error) {\n console.error('Cart entry action failed', error);\n }\n },\n onCartActionOptimisticUI(context, event) {\n if (!context.cart) return {...context};\n switch (event.type) {\n case 'CARTLINE_REMOVE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.filter(\n (line) => line?.id && !event.payload.lines.includes(line?.id),\n ),\n },\n };\n case 'CARTLINE_UPDATE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.map((line) => {\n const updatedLine = event.payload.lines.find(\n ({id}) => id === line?.id,\n );\n\n if (updatedLine && updatedLine.quantity) {\n return {\n ...line,\n quantity: updatedLine.quantity,\n };\n }\n\n return line;\n }),\n },\n };\n }\n return {...context};\n },\n onCartActionComplete(context, event) {\n const cartActionEvent = event.payload.cartActionEvent;\n try {\n switch (event.type) {\n case 'RESOLVE':\n switch (cartActionEvent.type) {\n case 'CART_CREATE':\n return onCreateComplete?.();\n case 'CARTLINE_ADD':\n return onLineAddComplete?.();\n case 'CARTLINE_REMOVE':\n return onLineRemoveComplete?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdateComplete?.();\n case 'NOTE_UPDATE':\n return onNoteUpdateComplete?.();\n case 'BUYER_IDENTITY_UPDATE':\n if (countryCodeNotUpdated(context, cartActionEvent)) {\n customerOverridesCountryCode.current = true;\n }\n return onBuyerIdentityUpdateComplete?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdateComplete?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdateComplete?.();\n }\n }\n } catch (error) {\n console.error('onCartActionComplete failed', error);\n }\n },\n });\n\n const cartReady = useRef(false);\n const [isCartReady, setIsCartReady] = useState(false);\n const cartCompleted = cartState.matches('cartCompleted');\n\n const countryChanged =\n (cartState.value === 'idle' ||\n cartState.value === 'error' ||\n cartState.value === 'cartCompleted') &&\n countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&\n !cartState.context.errors;\n\n const fetchingFromStorage = useRef(false);\n\n /**\n * Initializes cart with priority in this order:\n * 1. cart props\n * 2. localStorage cartId\n */\n useEffect(() => {\n if (!cartReady.current && !fetchingFromStorage.current) {\n if (!cart && storageAvailable('localStorage')) {\n fetchingFromStorage.current = true;\n try {\n const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);\n if (cartId) {\n cartSend({type: 'CART_FETCH', payload: {cartId}});\n }\n } catch (error) {\n console.warn('error fetching cartId');\n console.warn(error);\n }\n }\n cartReady.current = true;\n // Providing a separate cart ready state variable to avoid re-renders in this logic while still being able to pass the reactive status through context.\n setIsCartReady(true);\n }\n }, [cart, cartReady, cartSend]);\n\n // Update cart country code if cart and props countryCode's as different\n useEffect(() => {\n if (!countryChanged || customerOverridesCountryCode.current) return;\n cartSend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {buyerIdentity: {countryCode, customerAccessToken}},\n });\n }, [\n countryCode,\n customerAccessToken,\n countryChanged,\n customerOverridesCountryCode,\n cartSend,\n ]);\n\n // send cart events when ready\n const onCartReadySend = useCallback(\n (cartEvent: CartMachineEvent) => {\n if (!cartReady.current) {\n return console.warn(\"Cart isn't ready yet\");\n }\n cartSend(cartEvent);\n },\n [cartSend],\n );\n\n // save cart id to local storage\n useEffect(() => {\n if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {\n try {\n window.localStorage.setItem(\n CART_ID_STORAGE_KEY,\n cartState.context.cart?.id,\n );\n } catch (error) {\n console.warn('Failed to save cartId to localStorage', error);\n }\n }\n }, [cartState?.context?.cart?.id]);\n\n // delete cart from local storage if cart fetched has been completed\n useEffect(() => {\n if (cartCompleted && storageAvailable('localStorage')) {\n try {\n window.localStorage.removeItem(CART_ID_STORAGE_KEY);\n } catch (error) {\n console.warn('Failed to delete cartId from localStorage', error);\n }\n }\n }, [cartCompleted]);\n\n const cartCreate = useCallback(\n (cartInput: CartInput) => {\n if (countryCode && !cartInput.buyerIdentity?.countryCode) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.countryCode = countryCode;\n }\n\n if (\n customerAccessToken &&\n !cartInput.buyerIdentity?.customerAccessToken\n ) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.customerAccessToken = customerAccessToken;\n }\n onCartReadySend({\n type: 'CART_CREATE',\n payload: cartInput,\n });\n },\n [countryCode, customerAccessToken, onCartReadySend],\n );\n\n // Delays the cart state in the context if the page is hydrating\n // preventing suspense boundary errors.\n const cartDisplayState = useDelayedStateUntilHydration(cartState);\n\n const cartContextValue = useMemo<CartWithActions>(() => {\n return {\n ...(cartDisplayState?.context?.cart ?? {lines: [], attributes: []}),\n status: transposeStatus(cartDisplayState.value),\n error: cartDisplayState?.context?.errors,\n totalQuantity: cartDisplayState?.context?.cart?.totalQuantity ?? 0,\n cartCreate,\n cartReady: isCartReady,\n linesAdd(lines: CartLineInput[]): void {\n if (cartDisplayState?.context?.cart?.id) {\n onCartReadySend({\n type: 'CARTLINE_ADD',\n payload: {lines},\n });\n } else {\n cartCreate({lines});\n }\n },\n linesRemove(lines: string[]): void {\n onCartReadySend({\n type: 'CARTLINE_REMOVE',\n payload: {\n lines,\n },\n });\n },\n linesUpdate(lines: CartLineUpdateInput[]): void {\n onCartReadySend({\n type: 'CARTLINE_UPDATE',\n payload: {\n lines,\n },\n });\n },\n noteUpdate(note: MutationCartNoteUpdateArgs['note']): void {\n onCartReadySend({\n type: 'NOTE_UPDATE',\n payload: {\n note,\n },\n });\n },\n buyerIdentityUpdate(buyerIdentity: CartBuyerIdentityInput): void {\n onCartReadySend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {\n buyerIdentity,\n },\n });\n },\n cartAttributesUpdate(attributes: AttributeInput[]): void {\n onCartReadySend({\n type: 'CART_ATTRIBUTES_UPDATE',\n payload: {\n attributes,\n },\n });\n },\n discountCodesUpdate(discountCodes: string[]): void {\n onCartReadySend({\n type: 'DISCOUNT_CODES_UPDATE',\n payload: {\n discountCodes,\n },\n });\n },\n cartFragment,\n };\n }, [\n cartCreate,\n isCartReady,\n cartDisplayState?.context?.cart,\n cartDisplayState?.context?.errors,\n cartDisplayState.value,\n cartFragment,\n onCartReadySend,\n ]);\n\n return (\n <CartContext.Provider value={cartContextValue}>\n {children}\n </CartContext.Provider>\n );\n}\n\nfunction transposeStatus(\n status: CartMachineTypeState['value'],\n): CartWithActions['status'] {\n switch (status) {\n case 'uninitialized':\n case 'initializationError':\n return 'uninitialized';\n case 'idle':\n case 'cartCompleted':\n case 'error':\n return 'idle';\n case 'cartFetching':\n return 'fetching';\n case 'cartCreating':\n return 'creating';\n case 'cartLineAdding':\n case 'cartLineRemoving':\n case 'cartLineUpdating':\n case 'noteUpdating':\n case 'buyerIdentityUpdating':\n case 'cartAttributesUpdating':\n case 'discountCodesUpdating':\n return 'updating';\n }\n}\n\n/**\n * Delays a state update until hydration finishes. Useful for preventing suspense boundaries errors when updating a context\n * @remarks this uses startTransition and waits for it to finish.\n */\nfunction useDelayedStateUntilHydration<T>(state: T): T {\n const [isPending, startTransition] = useTransition();\n const [delayedState, setDelayedState] = useState(state);\n\n const firstTimePending = useRef(false);\n if (isPending) {\n firstTimePending.current = true;\n }\n\n const firstTimePendingFinished = useRef(false);\n if (!isPending && firstTimePending.current) {\n firstTimePendingFinished.current = true;\n }\n\n useEffect(() => {\n startTransition(() => {\n if (!firstTimePendingFinished.current) {\n setDelayedState(state);\n }\n });\n }, [state]);\n\n const displayState = firstTimePendingFinished.current ? state : delayedState;\n\n return displayState;\n}\n\n/**\n * Check for storage availability function obtained from\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API\n */\nexport function storageAvailable(\n type: 'localStorage' | 'sessionStorage',\n): boolean {\n let storage;\n try {\n storage = window[type];\n const x = '__storage_test__';\n storage.setItem(x, x);\n storage.removeItem(x);\n return true;\n } catch (e) {\n return !!(\n e instanceof DOMException &&\n // everything except Firefox\n (e.code === 22 ||\n // Firefox\n e.code === 1014 ||\n // test name field too, because code might not be present\n // everything except Firefox\n e.name === 'QuotaExceededError' ||\n // Firefox\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&\n // acknowledge QuotaExceededError only if there's something already stored\n storage &&\n storage.length !== 0\n );\n }\n}\n\nfunction countryCodeNotUpdated(\n context: CartMachineContext,\n event: BuyerIdentityUpdateEvent,\n): boolean {\n return !!(\n event.payload.buyerIdentity.countryCode &&\n context.cart?.buyerIdentity?.countryCode !==\n event.payload.buyerIdentity.countryCode\n );\n}\n","import {\n useMemo,\n useState,\n useEffect,\n useCallback,\n createContext,\n useContext,\n} from 'react';\nimport type {\n SelectedOption as SelectedOptionType,\n SellingPlan,\n SellingPlanAllocation,\n Product,\n ProductVariant as ProductVariantType,\n ProductVariantConnection,\n SellingPlan as SellingPlanType,\n SellingPlanAllocation as SellingPlanAllocationType,\n SellingPlanGroup as SellingPlanGroupType,\n SellingPlanGroupConnection,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\n\nconst ProductOptionsContext = createContext<ProductHookValue | null>(null);\n\ntype InitialVariantId = ProductVariantType['id'] | null;\n\ninterface ProductProviderProps {\n /** A Storefront API [Product object](https://shopify.dev/api/storefront/reference/products/product). */\n data: PartialDeep<Product, {recurseIntoArrays: true}>;\n /** A `ReactNode` element. */\n children: React.ReactNode;\n /**\n * The initially selected variant.\n * The following logic applies to `initialVariantId`:\n * 1. If `initialVariantId` is provided, then it's used even if it's out of stock.\n * 2. If `initialVariantId` is provided but is `null`, then no variant is used.\n * 3. If nothing is passed to `initialVariantId` then the first available / in-stock variant is used.\n * 4. If nothing is passed to `initialVariantId` and no variants are in stock, then the first variant is used.\n */\n initialVariantId?: InitialVariantId;\n}\n\n/**\n * `<ProductProvider />` is a context provider that enables use of the `useProduct()` hook.\n *\n * It helps manage selected options and variants for a product.\n */\nexport function ProductProvider({\n children,\n data: product,\n initialVariantId: explicitVariantId,\n}: ProductProviderProps): JSX.Element {\n // The flattened variants\n const variants = useMemo(\n () => flattenConnection(product.variants ?? {}),\n [product.variants],\n );\n\n if (!isProductVariantArray(variants)) {\n throw new Error(\n `<ProductProvider/> requires 'product.variants.nodes' or 'product.variants.edges'`,\n );\n }\n\n // All the options available for a product, based on all the variants\n const options = useMemo(() => getOptions(variants), [variants]);\n\n /**\n * Track the selectedVariant within the provider.\n */\n const [selectedVariant, setSelectedVariant] = useState<\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null\n >(() => getVariantBasedOnIdProp(explicitVariantId, variants));\n\n /**\n * Track the selectedOptions within the provider. If a `initialVariantId`\n * is passed, use that to select initial options.\n */\n const [selectedOptions, setSelectedOptions] = useState<SelectedOptions>(() =>\n getSelectedOptions(selectedVariant),\n );\n\n /**\n * When the initialVariantId changes, we need to make sure we\n * update the selected variant and selected options. If not,\n * then the selected variant and options will reference incorrect\n * values.\n */\n useEffect(() => {\n const newSelectedVariant = getVariantBasedOnIdProp(\n explicitVariantId,\n variants,\n );\n setSelectedVariant(newSelectedVariant);\n setSelectedOptions(getSelectedOptions(newSelectedVariant));\n }, [explicitVariantId, variants]);\n\n /**\n * Allow the developer to select an option.\n */\n const setSelectedOption = useCallback(\n (name: string, value: string) => {\n setSelectedOptions((selectedOptions) => {\n const opts = {...selectedOptions, [name]: value};\n setSelectedVariant(getSelectedVariant(variants, opts));\n return opts;\n });\n },\n [setSelectedOptions, variants],\n );\n\n const isOptionInStock = useCallback(\n (option: string, value: string) => {\n const proposedVariant = getSelectedVariant(variants, {\n ...selectedOptions,\n ...{[option]: value},\n });\n\n return proposedVariant?.availableForSale ?? true;\n },\n [selectedOptions, variants],\n );\n\n const sellingPlanGroups = useMemo(\n () =>\n flattenConnection(product.sellingPlanGroups ?? {}).map(\n (sellingPlanGroup) => ({\n ...sellingPlanGroup,\n sellingPlans: flattenConnection(sellingPlanGroup?.sellingPlans ?? {}),\n }),\n ),\n [product.sellingPlanGroups],\n );\n\n /**\n * Track the selectedSellingPlan within the hook. If `initialSellingPlanId`\n * is passed, use that as an initial value. Look it up from the `selectedVariant`, since\n * that is also a requirement.\n */\n const [selectedSellingPlan, setSelectedSellingPlan] = useState<\n PartialDeep<SellingPlan, {recurseIntoArrays: true}> | undefined\n >(undefined);\n\n const selectedSellingPlanAllocation = useMemo<\n PartialDeep<SellingPlanAllocation, {recurseIntoArrays: true}> | undefined\n >(() => {\n if (!selectedVariant || !selectedSellingPlan) {\n return;\n }\n\n if (\n !selectedVariant.sellingPlanAllocations?.nodes &&\n !selectedVariant.sellingPlanAllocations?.edges\n ) {\n throw new Error(\n `<ProductProvider/>: You must include 'sellingPlanAllocations.nodes' or 'sellingPlanAllocations.edges' in your variants in order to calculate selectedSellingPlanAllocation`,\n );\n }\n\n return flattenConnection(selectedVariant.sellingPlanAllocations).find(\n (allocation) => allocation?.sellingPlan?.id === selectedSellingPlan.id,\n );\n }, [selectedVariant, selectedSellingPlan]);\n\n const value = useMemo<ProductHookValue>(\n () => ({\n product,\n variants,\n variantsConnection: product.variants,\n options,\n selectedVariant,\n setSelectedVariant,\n selectedOptions,\n setSelectedOption,\n setSelectedOptions,\n isOptionInStock,\n selectedSellingPlan,\n setSelectedSellingPlan,\n selectedSellingPlanAllocation,\n sellingPlanGroups,\n sellingPlanGroupsConnection: product.sellingPlanGroups,\n }),\n [\n product,\n isOptionInStock,\n options,\n selectedOptions,\n selectedSellingPlan,\n selectedSellingPlanAllocation,\n selectedVariant,\n sellingPlanGroups,\n setSelectedOption,\n variants,\n ],\n );\n\n return (\n <ProductOptionsContext.Provider value={value}>\n {children}\n </ProductOptionsContext.Provider>\n );\n}\n\n/**\n * Provides access to the context value provided by `<ProductProvider />`. Must be a descendent of `<ProductProvider />`.\n */\nexport function useProduct(): ProductHookValue {\n const context = useContext(ProductOptionsContext);\n\n if (!context) {\n throw new Error(`'useProduct' must be a child of <ProductProvider />`);\n }\n\n return context;\n}\n\nfunction getSelectedVariant(\n variants: PartialDeep<ProductVariantType, {recurseIntoArrays: true}>[],\n choices: SelectedOptions,\n): PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined {\n /**\n * Ensure the user has selected all the required options, not just some.\n */\n if (\n !variants.length ||\n variants?.[0]?.selectedOptions?.length !== Object.keys(choices).length\n ) {\n return;\n }\n\n return variants?.find((variant) => {\n return Object.entries(choices).every(([name, value]) => {\n return variant?.selectedOptions?.some(\n (option) => option?.name === name && option?.value === value,\n );\n });\n });\n}\n\nfunction getOptions(\n variants: PartialDeep<ProductVariantType, {recurseIntoArrays: true}>[],\n): OptionWithValues[] {\n const map = variants.reduce((memo, variant) => {\n if (!variant.selectedOptions) {\n throw new Error(`'getOptions' requires 'variant.selectedOptions'`);\n }\n variant?.selectedOptions?.forEach((opt) => {\n memo[opt?.name ?? ''] = memo[opt?.name ?? ''] || new Set();\n memo[opt?.name ?? ''].add(opt?.value ?? '');\n });\n\n return memo;\n }, {} as Record<string, Set<string>>);\n\n return Object.keys(map).map((option) => {\n return {\n name: option,\n values: Array.from(map[option]),\n };\n });\n}\n\nfunction getVariantBasedOnIdProp(\n explicitVariantId: InitialVariantId | undefined,\n variants: Array<\n PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined\n >,\n):\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null {\n // get the initial variant based on the logic outlined in the comments for 'initialVariantId' above\n // * 1. If `initialVariantId` is provided, then it's used even if it's out of stock.\n if (explicitVariantId) {\n const foundVariant = variants.find(\n (variant) => variant?.id === explicitVariantId,\n );\n if (!foundVariant) {\n console.warn(\n `<ProductProvider/> received a 'initialVariantId' prop, but could not actually find a variant with that ID`,\n );\n }\n return foundVariant;\n }\n // * 2. If `initialVariantId` is provided but is `null`, then no variant is used.\n if (explicitVariantId === null) {\n return null;\n }\n // * 3. If nothing is passed to `initialVariantId` then the first available / in-stock variant is used.\n // * 4. If nothing is passed to `initialVariantId` and no variants are in stock, then the first variant is used.\n if (explicitVariantId === undefined) {\n return variants.find((variant) => variant?.availableForSale) || variants[0];\n }\n}\n\nfunction getSelectedOptions(\n selectedVariant:\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null,\n): SelectedOptions {\n return selectedVariant?.selectedOptions\n ? selectedVariant.selectedOptions.reduce<SelectedOptions>(\n (memo, optionSet) => {\n memo[optionSet?.name ?? ''] = optionSet?.value ?? '';\n return memo;\n },\n {},\n )\n : {};\n}\n\nfunction isProductVariantArray(\n maybeVariantArray:\n | (PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined)[]\n | undefined,\n): maybeVariantArray is PartialDeep<\n ProductVariantType,\n {recurseIntoArrays: true}\n>[] {\n if (!maybeVariantArray || !Array.isArray(maybeVariantArray)) {\n return false;\n }\n\n return true;\n}\n\nexport interface OptionWithValues {\n name: SelectedOptionType['name'];\n values: SelectedOptionType['value'][];\n}\n\ntype UseProductObjects = {\n /** The raw product from the Storefront API */\n product: Product;\n /** An array of the variant `nodes` from the `VariantConnection`. */\n variants: ProductVariantType[];\n variantsConnection?: ProductVariantConnection;\n /** An array of the product's options and values. */\n options: OptionWithValues[];\n /** The selected variant. */\n selectedVariant?: ProductVariantType | null;\n selectedOptions: SelectedOptions;\n /** The selected selling plan. */\n selectedSellingPlan?: SellingPlanType;\n /** The selected selling plan allocation. */\n selectedSellingPlanAllocation?: SellingPlanAllocationType;\n /** The selling plan groups. */\n sellingPlanGroups?: (Omit<SellingPlanGroupType, 'sellingPlans'> & {\n sellingPlans: SellingPlanType[];\n })[];\n sellingPlanGroupsConnection?: SellingPlanGroupConnection;\n};\n\ntype UseProductFunctions = {\n /** A callback to set the selected variant to the variant passed as an argument. */\n setSelectedVariant: (\n variant: PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | null,\n ) => void;\n /** A callback to set the selected option. */\n setSelectedOption: (\n name: SelectedOptionType['name'],\n value: SelectedOptionType['value'],\n ) => void;\n /** A callback to set multiple selected options at once. */\n setSelectedOptions: (options: SelectedOptions) => void;\n /** A callback to set the selected selling plan to the one passed as an argument. */\n setSelectedSellingPlan: (\n sellingPlan: PartialDeep<SellingPlanType, {recurseIntoArrays: true}>,\n ) => void;\n /** A callback that returns a boolean indicating if the option is in stock. */\n isOptionInStock: (\n name: SelectedOptionType['name'],\n value: SelectedOptionType['value'],\n ) => boolean;\n};\n\ntype ProductHookValue = PartialDeep<\n UseProductObjects,\n {recurseIntoArrays: true}\n> &\n UseProductFunctions;\n\nexport type SelectedOptions = {\n [key: string]: string;\n};\n","import {ReactNode, Ref, useCallback} from 'react';\n\nexport interface CustomBaseButtonProps<AsType> {\n /** Provide a React element or component to render as the underlying button. Note: for accessibility compliance, almost always you should use a `button` element, or a component that renders an underlying button. */\n as?: AsType;\n /** Any ReactNode elements. */\n children: ReactNode;\n /** Click event handler. Default behaviour triggers unless prevented */\n onClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => void | boolean;\n /** A default `onClick` behavior */\n defaultOnClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => void | boolean;\n /** A `ref` to the underlying button */\n buttonRef?: Ref<HTMLButtonElement>;\n}\n\nexport type BaseButtonProps<AsType extends React.ElementType> =\n CustomBaseButtonProps<AsType> &\n (AsType extends keyof React.JSX.IntrinsicElements\n ? Omit<\n React.ComponentPropsWithoutRef<AsType>,\n keyof CustomBaseButtonProps<AsType>\n >\n : React.ComponentPropsWithoutRef<AsType>);\n\nexport function BaseButton<AsType extends React.ElementType = 'button'>(\n props: BaseButtonProps<AsType>,\n): JSX.Element {\n const {\n as,\n onClick,\n defaultOnClick,\n children,\n buttonRef,\n ...passthroughProps\n } = props;\n\n const handleOnClick = useCallback(\n (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (onClick) {\n const clickShouldContinue = onClick(event);\n if (\n (typeof clickShouldContinue === 'boolean' &&\n clickShouldContinue === false) ||\n event?.defaultPrevented\n )\n return;\n }\n\n defaultOnClick?.(event);\n },\n [defaultOnClick, onClick],\n );\n\n const Component = as || 'button';\n\n return (\n <Component ref={buttonRef} onClick={handleOnClick} {...passthroughProps}>\n {children}\n </Component>\n );\n}\n","import {useCallback, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {useProduct} from './ProductProvider.js';\nimport {\n BaseButton,\n type CustomBaseButtonProps,\n type BaseButtonProps,\n} from './BaseButton.js';\nimport * as React from 'react';\n\nexport interface AddToCartButtonPropsBase {\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n /** The ID of the variant. */\n variantId?: string | null;\n /** The item quantity. */\n quantity?: number;\n /** The text that is announced by the screen reader when the item is being added to the cart. Used for accessibility purposes only and not displayed on the page. */\n accessibleAddingToCartLabel?: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n}\n\nexport type AddToCartButtonProps<AsType extends React.ElementType = 'button'> =\n AddToCartButtonPropsBase & BaseButtonProps<AsType>;\n\n/**\n * The `AddToCartButton` component renders a button that adds an item to the cart when pressed.\n * It must be a descendent of the `CartProvider` component.\n */\nexport function AddToCartButton<AsType extends React.ElementType = 'button'>(\n props: AddToCartButtonProps<AsType>,\n): JSX.Element {\n const [addingItem, setAddingItem] = useState<boolean>(false);\n const {\n variantId: explicitVariantId,\n quantity = 1,\n attributes,\n sellingPlanId,\n onClick,\n children,\n accessibleAddingToCartLabel,\n ...passthroughProps\n } = props;\n const {status, linesAdd} = useCart();\n const {selectedVariant} = useProduct();\n const variantId = explicitVariantId ?? selectedVariant?.id ?? '';\n const disabled =\n explicitVariantId === null ||\n variantId === '' ||\n selectedVariant === null ||\n addingItem ||\n // Only certain 'as' types such as 'button' contain `disabled`\n (passthroughProps as {disabled?: boolean}).disabled;\n\n useEffect(() => {\n if (addingItem && status === 'idle') {\n setAddingItem(false);\n }\n }, [status, addingItem]);\n\n const handleAddItem = useCallback(() => {\n setAddingItem(true);\n linesAdd([\n {\n quantity,\n merchandiseId: variantId || '',\n attributes,\n sellingPlanId,\n },\n ]);\n }, [linesAdd, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <>\n <BaseButton\n {...passthroughProps}\n disabled={disabled}\n onClick={onClick}\n defaultOnClick={handleAddItem}\n >\n {children}\n </BaseButton>\n {accessibleAddingToCartLabel ? (\n <p\n style={{\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n }}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n {addingItem ? accessibleAddingToCartLabel : null}\n </p>\n ) : null}\n </>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface AddToCartButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends AddToCartButtonPropsBase,\n CustomBaseButtonProps<AsType> {}\n","export const AnalyticsEventName = {\n PAGE_VIEW: 'PAGE_VIEW',\n ADD_TO_CART: 'ADD_TO_CART',\n PAGE_VIEW_2: 'PAGE_VIEW_2',\n COLLECTION_VIEW: 'COLLECTION_VIEW',\n PRODUCT_VIEW: 'PRODUCT_VIEW',\n SEARCH_VIEW: 'SEARCH_VIEW',\n} as const;\n\nexport const AnalyticsPageType: AnalyticsPageType = {\n article: 'article',\n blog: 'blog',\n captcha: 'captcha',\n cart: 'cart',\n collection: 'collection',\n customersAccount: 'customers/account',\n customersActivateAccount: 'customers/activate_account',\n customersAddresses: 'customers/addresses',\n customersLogin: 'customers/login',\n customersOrder: 'customers/order',\n customersRegister: 'customers/register',\n customersResetPassword: 'customers/reset_password',\n giftCard: 'gift_card',\n home: 'index',\n listCollections: 'list-collections',\n forbidden: '403',\n notFound: '404',\n page: 'page',\n password: 'password',\n product: 'product',\n policy: 'policy',\n search: 'search',\n} as const;\n\nexport const ShopifySalesChannel: ShopifySalesChannel = {\n hydrogen: 'hydrogen',\n headless: 'headless',\n} as const;\n\nexport const ShopifyAppId = {\n hydrogen: '6167201',\n headless: '12875497473',\n} as const;\n\n/**\n * These duplicated interface declaration is so that we can generate proper documentation\n * for these public facing constants\n */\nexport interface AnalyticsEventName {\n /** Page view */\n PAGE_VIEW: 'PAGE_VIEW';\n /** Add to cart */\n ADD_TO_CART: 'ADD_TO_CART';\n}\n\nexport interface AnalyticsPageType {\n article: 'article';\n blog: 'blog';\n captcha: 'captcha';\n cart: 'cart';\n collection: 'collection';\n customersAccount: 'customers/account';\n customersActivateAccount: 'customers/activate_account';\n customersAddresses: 'customers/addresses';\n customersLogin: 'customers/login';\n customersOrder: 'customers/order';\n customersRegister: 'customers/register';\n customersResetPassword: 'customers/reset_password';\n giftCard: 'gift_card';\n home: 'index';\n listCollections: 'list-collections';\n forbidden: '403';\n notFound: '404';\n page: 'page';\n password: 'password';\n product: 'product';\n policy: 'policy';\n search: 'search';\n}\n\nexport interface ShopifySalesChannel {\n /** Shopify Hydrogen sales channel */\n hydrogen: 'hydrogen';\n /** Shopify Headless sales channel */\n headless: 'headless';\n}\n","import type {\n ShopifyMonorailPayload,\n ShopifyMonorailEvent,\n ShopifyGid,\n} from './analytics-types.js';\n\n/**\n * Builds a Shopify Monorail event from a Shopify Monorail payload and a schema ID.\n * @param payload - The Monorail payload\n * @param schemaId - The schema ID to use\n * @returns The formatted payload\n **/\nexport function schemaWrapper(\n schemaId: string,\n payload: ShopifyMonorailPayload,\n): ShopifyMonorailEvent {\n return {\n schema_id: schemaId,\n payload,\n metadata: {\n event_created_at_ms: Date.now(),\n },\n };\n}\n\n/**\n * Parses global id (gid) and returns the resource type and id.\n * @see https://shopify.dev/api/usage/gids\n * @param gid - A shopify GID (string)\n *\n * @example\n * ```ts\n * const {id, resource} = parseGid('gid://shopify/Order/123')\n * // => id = \"123\", resource = 'Order'\n *\n * * const {id, resource} = parseGid('gid://shopify/Cart/abc123')\n * // => id = \"abc123\", resource = 'Cart'\n * ```\n **/\nexport function parseGid(gid: string | undefined): ShopifyGid {\n const defaultReturn: ShopifyGid = {\n id: '',\n resource: null,\n resourceId: null,\n search: '',\n searchParams: new URLSearchParams(),\n hash: '',\n };\n\n if (typeof gid !== 'string') {\n return defaultReturn;\n }\n\n try {\n const {search, searchParams, pathname, hash} = new URL(gid);\n const pathnameParts = pathname.split('/');\n const lastPathnamePart = pathnameParts[pathnameParts.length - 1];\n const resourcePart = pathnameParts[pathnameParts.length - 2];\n\n if (!lastPathnamePart || !resourcePart) {\n return defaultReturn;\n }\n\n const id = `${lastPathnamePart}${search}${hash}` || '';\n const resourceId = lastPathnamePart || null;\n const resource = resourcePart ?? null;\n\n return {id, resource, resourceId, search, searchParams, hash};\n } catch {\n return defaultReturn;\n }\n}\n\n/**\n * Filters properties from an object and returns a new object with only the properties that have a truthy value.\n * @param keyValuePairs - An object of key-value pairs\n * @param formattedData - An object which will hold the truthy values\n * @returns The formatted object\n **/\nexport function addDataIf(\n keyValuePairs: ShopifyMonorailPayload,\n formattedData: ShopifyMonorailPayload,\n): ShopifyMonorailPayload {\n if (typeof keyValuePairs !== 'object') {\n return {};\n }\n Object.entries(keyValuePairs).forEach(([key, value]) => {\n if (value) {\n formattedData[key] = value;\n }\n });\n return formattedData;\n}\n\n/**\n * Utility that errors if a function is called on the server.\n * @param fnName - The name of the function\n * @returns A boolean\n **/\nexport function errorIfServer(fnName: string): boolean {\n if (typeof document === 'undefined') {\n console.error(\n `${fnName} should only be used within the useEffect callback or event handlers`,\n );\n return true;\n }\n return false;\n}\n","import {\n ShopifyPageViewPayload,\n ShopifyMonorailPayload,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {ShopifyAppId} from './analytics-constants.js';\nimport {addDataIf, schemaWrapper, parseGid} from './analytics-utils.js';\nimport {buildUUID} from './cookies-utils.js';\n\nconst SCHEMA_ID = 'trekkie_storefront_page_view/1.4';\nconst OXYGEN_DOMAIN = 'myshopify.dev';\n\nexport function pageView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const {id, resource} = parseGid(pageViewPayload.resourceId);\n const resourceType = resource ? resource.toLowerCase() : undefined;\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n pageType: pageViewPayload.pageType,\n customerId: parseInt(parseGid(pageViewPayload.customerId).id || '0'),\n resourceType,\n resourceId: parseInt(id),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\nfunction formatPayload(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailPayload {\n return {\n appClientId: payload.shopifySalesChannel\n ? ShopifyAppId[payload.shopifySalesChannel]\n : ShopifyAppId.headless,\n isMerchantRequest: isMerchantRequest(payload.url),\n hydrogenSubchannelId:\n payload.storefrontId || payload.hydrogenSubchannelId || '0',\n\n isPersistentCookie: payload.hasUserConsent,\n uniqToken: payload.uniqueToken,\n visitToken: payload.visitToken,\n microSessionId: buildUUID(),\n microSessionCount: 1,\n\n url: payload.url,\n path: payload.path,\n search: payload.search,\n referrer: payload.referrer,\n title: payload.title,\n\n shopId: parseInt(parseGid(payload.shopId).id),\n currency: payload.currency,\n contentLanguage: payload.acceptedLanguage || 'en',\n };\n}\n\nfunction isMerchantRequest(url: string): boolean {\n if (typeof url !== 'string') {\n return false;\n }\n const hostname = new URL(url).hostname;\n if (hostname.indexOf(OXYGEN_DOMAIN) !== -1 || hostname === 'localhost') {\n return true;\n }\n return false;\n}\n","import {\n ShopifyAnalyticsPayload,\n ShopifyPageViewPayload,\n ShopifyAddToCartPayload,\n ShopifyMonorailPayload,\n ShopifyAnalyticsProduct,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {AnalyticsPageType, ShopifySalesChannel} from './analytics-constants.js';\nimport {addDataIf, schemaWrapper, parseGid} from './analytics-utils.js';\nimport {buildUUID} from './cookies-utils.js';\nimport {version} from '../package.json';\n\nconst SCHEMA_ID = 'custom_storefront_customer_tracking/1.2';\nconst PAGE_RENDERED_EVENT_NAME = 'page_rendered';\nconst COLLECTION_PAGE_RENDERED_EVENT_NAME = 'collection_page_rendered';\nconst PRODUCT_PAGE_RENDERED_EVENT_NAME = 'product_page_rendered';\nconst PRODUCT_ADDED_TO_CART_EVENT_NAME = 'product_added_to_cart';\nconst SEARCH_SUBMITTED_EVENT_NAME = 'search_submitted';\n\nfunction prepareAdditionalPayload(\n payload: ShopifyPageViewPayload,\n): Pick<ShopifyMonorailPayload, 'canonical_url' | 'customer_id'> {\n return {\n canonical_url: payload.canonicalUrl || payload.url,\n customer_id: parseInt(parseGid(payload.customerId).id || '0'),\n };\n}\n\n// Send the page view event to the Monorail server.\n// It also sends additional page view events based on the page type.\nexport function pageView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n const pageType = pageViewPayload.pageType;\n const pageViewEvents = [];\n\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n\n switch (pageType) {\n case AnalyticsPageType.collection:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: COLLECTION_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n collection_name: pageViewPayload.collectionHandle,\n collection_id: parseInt(\n parseGid(pageViewPayload.collectionId).id,\n ),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n case AnalyticsPageType.product:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n products: formatProductPayload(pageViewPayload.products),\n total_value: pageViewPayload.totalValue,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n case AnalyticsPageType.search:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: SEARCH_SUBMITTED_EVENT_NAME,\n ...additionalPayload,\n search_string: pageViewPayload.searchString,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n }\n\n return pageViewEvents;\n}\n\n// Sends page view event to the Monorail server.\nexport function pageView2(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends collection view event to the Monorail server.\nexport function collectionView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: COLLECTION_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n collection_name: pageViewPayload.collectionHandle,\n collection_id: parseInt(parseGid(pageViewPayload.collectionId).id),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends product view event to the Monorail server.\nexport function productView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n products: formatProductPayload(pageViewPayload.products),\n total_value: pageViewPayload.totalValue,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends search view event to the Monorail server.\nexport function searchView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: SEARCH_SUBMITTED_EVENT_NAME,\n ...additionalPayload,\n search_string: pageViewPayload.searchString,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\nexport function addToCart(\n payload: ShopifyAddToCartPayload,\n): ShopifyMonorailEvent[] {\n const addToCartPayload = payload;\n const cartToken = parseGid(addToCartPayload.cartId);\n const cart_token = cartToken?.id ? `${cartToken.id}` : null;\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_ADDED_TO_CART_EVENT_NAME,\n customerId: addToCartPayload.customerId,\n cart_token,\n total_value: addToCartPayload.totalValue,\n products: formatProductPayload(addToCartPayload.products),\n customer_id: parseInt(\n parseGid(addToCartPayload.customerId).id || '0',\n ),\n },\n formatPayload(addToCartPayload),\n ),\n ),\n ];\n}\n\nfunction formatPayload(\n payload: ShopifyAnalyticsPayload,\n): ShopifyMonorailPayload {\n return {\n source: payload.shopifySalesChannel || ShopifySalesChannel.headless,\n asset_version_id: payload.assetVersionId || version,\n hydrogenSubchannelId:\n payload.storefrontId || payload.hydrogenSubchannelId || '0',\n\n is_persistent_cookie: payload.hasUserConsent,\n deprecated_visit_token: payload.visitToken,\n unique_token: payload.uniqueToken,\n event_time: Date.now(),\n event_id: buildUUID(),\n\n event_source_url: payload.url,\n referrer: payload.referrer,\n user_agent: payload.userAgent,\n navigation_type: payload.navigationType,\n navigation_api: payload.navigationApi,\n\n shop_id: parseInt(parseGid(payload.shopId).id),\n currency: payload.currency,\n\n ccpa_enforced: payload.ccpaEnforced || false,\n gdpr_enforced: payload.gdprEnforced || false,\n gdpr_enforced_as_string: payload.gdprEnforced ? 'true' : 'false',\n analytics_allowed: payload.analyticsAllowed || false,\n marketing_allowed: payload.marketingAllowed || false,\n sale_of_data_allowed: payload.saleOfDataAllowed || false,\n };\n}\n\nfunction formatProductPayload(products?: ShopifyAnalyticsProduct[]): string[] {\n return products\n ? products.map((p: ShopifyAnalyticsProduct) => {\n const product = addDataIf(\n {\n variant_gid: p.variantGid,\n category: p.category,\n sku: p.sku,\n product_id: parseInt(parseGid(p.productGid).id),\n variant_id: parseInt(parseGid(p.variantGid).id),\n },\n {\n product_gid: p.productGid,\n name: p.name,\n variant: p.variantName || '',\n brand: p.brand,\n price: parseFloat(p.price),\n quantity: Number(p.quantity || 0),\n },\n );\n return JSON.stringify(product);\n })\n : [];\n}\n","import {SHOPIFY_S, SHOPIFY_Y} from './cart-constants.js';\nimport type {\n ClientBrowserParameters,\n ShopifyAddToCartPayload,\n ShopifyAnalytics,\n ShopifyPageViewPayload,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {AnalyticsEventName} from './analytics-constants.js';\nimport {errorIfServer} from './analytics-utils.js';\nimport {getShopifyCookies} from './cookies-utils.js';\n\nimport {pageView as trekkiePageView} from './analytics-schema-trekkie-storefront-page-view.js';\nimport {\n pageView as customerPageView,\n pageView2 as customerPageView2,\n collectionView as customerCollectionView,\n productView as customerProductView,\n searchView as customerSearchView,\n addToCart as customerAddToCart,\n} from './analytics-schema-custom-storefront-customer-tracking.js';\n\n/**\n * Set user and session cookies and refresh the expiry time\n * @param event - The analytics event.\n * @param shopDomain - The Online Store domain to sent Shopify analytics under the same\n * top level domain.\n */\nexport function sendShopifyAnalytics(\n event: ShopifyAnalytics,\n shopDomain?: string,\n): Promise<void> {\n const {eventName, payload} = event;\n if (!payload.hasUserConsent) return Promise.resolve();\n\n let events: ShopifyMonorailEvent[] = [];\n const pageViewPayload = payload as ShopifyPageViewPayload;\n\n if (eventName === AnalyticsEventName.PAGE_VIEW) {\n events = events.concat(\n trekkiePageView(pageViewPayload),\n customerPageView(pageViewPayload),\n );\n } else if (eventName === AnalyticsEventName.ADD_TO_CART) {\n events = events.concat(\n customerAddToCart(payload as ShopifyAddToCartPayload),\n );\n } else if (eventName === AnalyticsEventName.PAGE_VIEW_2) {\n events = events.concat(\n trekkiePageView(pageViewPayload),\n customerPageView2(pageViewPayload),\n );\n } else if (eventName === AnalyticsEventName.COLLECTION_VIEW) {\n events = events.concat(customerCollectionView(pageViewPayload));\n } else if (eventName === AnalyticsEventName.PRODUCT_VIEW) {\n events = events.concat(customerProductView(pageViewPayload));\n } else if (eventName === AnalyticsEventName.SEARCH_VIEW) {\n events = events.concat(customerSearchView(pageViewPayload));\n }\n\n if (events.length) {\n return sendToShopify(events, shopDomain);\n } else {\n return Promise.resolve();\n }\n}\n\n// Shopify monorail return invalid agent for Lighthouse userAgents\nfunction isLighthouseUserAgent(): boolean {\n if (typeof window === 'undefined' || !window.navigator) return false;\n return /Chrome-Lighthouse/.test(window.navigator.userAgent);\n}\n\ntype MonorailResponse = {\n status: number;\n message: string;\n};\n\nconst ERROR_MESSAGE = 'sendShopifyAnalytics request is unsuccessful';\n\nfunction sendToShopify(\n events: ShopifyMonorailEvent[],\n shopDomain?: string,\n): Promise<void> {\n if (isLighthouseUserAgent()) {\n return Promise.resolve();\n }\n\n const eventsToBeSent = {\n events,\n metadata: {\n event_sent_at_ms: Date.now(),\n },\n };\n\n try {\n return fetch(\n shopDomain\n ? `https://${shopDomain}/.well-known/shopify/monorail/unstable/produce_batch`\n : 'https://monorail-edge.shopifysvc.com/unstable/produce_batch',\n {\n method: 'post',\n headers: {\n 'content-type': 'text/plain',\n },\n body: JSON.stringify(eventsToBeSent),\n },\n )\n .then((response) => {\n if (!response.ok) {\n throw new Error('Response failed');\n }\n return response.text();\n })\n .then((data) => {\n if (data) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const jsonResponse = JSON.parse(data);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n jsonResponse.result.forEach((eventResponse: MonorailResponse) => {\n if (eventResponse.status !== 200) {\n console.error(ERROR_MESSAGE, '\\n\\n', eventResponse.message);\n }\n });\n }\n })\n .catch((err) => {\n console.error(ERROR_MESSAGE, err);\n if (__HYDROGEN_DEV__) {\n throw new Error(ERROR_MESSAGE);\n }\n });\n } catch (error) {\n // Do nothing\n return Promise.resolve();\n }\n}\n\nexport function getClientBrowserParameters(): ClientBrowserParameters {\n if (errorIfServer('getClientBrowserParameters')) {\n return {\n uniqueToken: '',\n visitToken: '',\n url: '',\n path: '',\n search: '',\n referrer: '',\n title: '',\n userAgent: '',\n navigationType: '',\n navigationApi: '',\n };\n }\n\n const [navigationType, navigationApi] = getNavigationType();\n const cookies = getShopifyCookies(document.cookie);\n\n return {\n uniqueToken: cookies[SHOPIFY_Y],\n visitToken: cookies[SHOPIFY_S],\n url: location.href,\n path: location.pathname,\n search: location.search,\n referrer: document.referrer,\n title: document.title,\n userAgent: navigator.userAgent,\n navigationType,\n navigationApi,\n };\n}\n\nfunction getNavigationTypeExperimental(): string | undefined {\n try {\n const navigationEntries =\n performance?.getEntriesByType &&\n performance?.getEntriesByType('navigation');\n\n if (navigationEntries && navigationEntries[0]) {\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming\n const rawType = (\n window.performance.getEntriesByType(\n 'navigation',\n )[0] as PerformanceNavigationTiming\n )['type'];\n const navType = rawType && rawType.toString();\n\n return navType;\n }\n } catch (err) {\n // Do nothing\n }\n return undefined;\n}\n\nfunction getNavigationTypeLegacy(): string | undefined {\n try {\n if (\n PerformanceNavigation &&\n performance?.navigation?.type !== null &&\n performance?.navigation?.type !== undefined\n ) {\n // https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation\n const rawType = performance.navigation.type;\n switch (rawType) {\n case PerformanceNavigation.TYPE_NAVIGATE:\n return 'navigate';\n break;\n case PerformanceNavigation.TYPE_RELOAD:\n return 'reload';\n break;\n case PerformanceNavigation.TYPE_BACK_FORWARD:\n return 'back_forward';\n break;\n default:\n return `unknown: ${rawType}`;\n }\n }\n } catch (err) {\n // do nothing\n }\n return undefined;\n}\n\nfunction getNavigationType(): [string, string] {\n try {\n let navApi = 'PerformanceNavigationTiming';\n let navType = getNavigationTypeExperimental();\n if (!navType) {\n navType = getNavigationTypeLegacy();\n navApi = 'performance.navigation';\n }\n if (navType) {\n return [navType, navApi];\n } else {\n return ['unknown', 'unknown'];\n }\n } catch (err) {\n // do nothing\n }\n return ['error', 'error'];\n}\n","import {useEffect, useState, useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {\n BaseButton,\n type BaseButtonProps,\n type CustomBaseButtonProps,\n} from './BaseButton.js';\n\ninterface BuyNowButtonPropsBase {\n /** The item quantity. Defaults to 1. */\n quantity?: number;\n /** The ID of the variant. */\n variantId: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n}\n\ntype BuyNowButtonProps<AsType extends React.ElementType = 'button'> =\n BuyNowButtonPropsBase & BaseButtonProps<AsType>;\n\n/**\n * The `BuyNowButton` component renders a button that adds an item to the cart and redirects the customer to checkout.\n * Must be a child of a `CartProvider` component.\n */\nexport function BuyNowButton<AsType extends React.ElementType = 'button'>(\n props: BuyNowButtonProps<AsType>,\n): JSX.Element {\n const {cartCreate, checkoutUrl} = useCart();\n const [loading, setLoading] = useState<boolean>(false);\n\n const {\n quantity,\n variantId,\n sellingPlanId,\n onClick,\n attributes,\n children,\n ...passthroughProps\n } = props;\n\n useEffect(() => {\n if (loading && checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n }, [loading, checkoutUrl]);\n\n const handleBuyNow = useCallback(() => {\n setLoading(true);\n cartCreate({\n lines: [\n {\n quantity: quantity ?? 1,\n merchandiseId: variantId,\n attributes,\n sellingPlanId,\n },\n ],\n });\n }, [cartCreate, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <BaseButton\n // Only certain 'as' types such as 'button' contain `disabled`\n disabled={loading ?? (passthroughProps as {disabled?: boolean}).disabled}\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleBuyNow}\n >\n {children}\n </BaseButton>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface BuyNowButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends BuyNowButtonPropsBase,\n CustomBaseButtonProps<AsType> {}\n","import {ReactNode, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {\n BaseButton,\n type BaseButtonProps,\n type CustomBaseButtonProps,\n} from './BaseButton.js';\n\ntype ChildrenProps = {\n /** A `ReactNode` element. */\n children: ReactNode;\n};\ntype CartCheckoutButtonProps = Omit<BaseButtonProps<'button'>, 'onClick'> &\n ChildrenProps;\n\n/**\n * The `CartCheckoutButton` component renders a button that redirects to the checkout URL for the cart.\n * It must be a descendent of a `CartProvider` component.\n */\nexport function CartCheckoutButton(\n props: CartCheckoutButtonProps,\n): JSX.Element {\n const [requestedCheckout, setRequestedCheckout] = useState(false);\n const {status, checkoutUrl} = useCart();\n const {children, ...passthroughProps} = props;\n\n useEffect(() => {\n if (requestedCheckout && checkoutUrl && status === 'idle') {\n window.location.href = checkoutUrl;\n }\n }, [requestedCheckout, status, checkoutUrl]);\n\n return (\n <BaseButton\n {...passthroughProps}\n disabled={requestedCheckout || passthroughProps.disabled}\n onClick={(): void => setRequestedCheckout(true)}\n >\n {children}\n </BaseButton>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\n// we ignore this issue because it makes the documentation look better than the equivalent `type` that it wants us to convert to\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface CartCheckoutButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends Omit<CustomBaseButtonProps<AsType>, 'onClick'> {}\n","import {useMemo} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {CurrencyCode, MoneyV2} from './storefront-api-types.js';\n\nexport type UseMoneyValue = {\n /**\n * The currency code from the `MoneyV2` object.\n */\n currencyCode: CurrencyCode;\n /**\n * The name for the currency code, returned by `Intl.NumberFormat`.\n */\n currencyName?: string;\n /**\n * The currency symbol returned by `Intl.NumberFormat`.\n */\n currencySymbol?: string;\n /**\n * The currency narrow symbol returned by `Intl.NumberFormat`.\n */\n currencyNarrowSymbol?: string;\n /**\n * The localized amount, without any currency symbols or non-number types from the `Intl.NumberFormat.formatToParts` parts.\n */\n amount: string;\n /**\n * All parts returned by `Intl.NumberFormat.formatToParts`.\n */\n parts: Intl.NumberFormatPart[];\n /**\n * A string returned by `new Intl.NumberFormat` for the amount and currency code,\n * using the `locale` value in the [`LocalizationProvider` component](https://shopify.dev/api/hydrogen/components/localization/localizationprovider).\n */\n localizedString: string;\n /**\n * The `MoneyV2` object provided as an argument to the hook.\n */\n original: MoneyV2;\n /**\n * A string with trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n * For example, `$640.00` turns into `$640`.\n * `$640.42` remains `$640.42`.\n */\n withoutTrailingZeros: string;\n /**\n * A string without currency and without trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n * For example, `$640.00` turns into `640`.\n * `$640.42` turns into `640.42`.\n */\n withoutTrailingZerosAndCurrency: string;\n};\n\n/**\n * The `useMoney` hook takes a [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2) and returns a\n * default-formatted string of the amount with the correct currency indicator, along with some of the parts provided by\n * [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).\n * Uses `locale` from `ShopifyProvider`\n * \n * @see {@link https://shopify.dev/api/hydrogen/hooks/usemoney}\n * @example initialize the money object\n * ```ts\n * const money = useMoney({\n * amount: '100.00',\n * currencyCode: 'USD'\n * })\n * ```\n * \n *\n * @example basic usage, outputs: $100.00\n * ```ts\n * money.localizedString\n * ```\n * \n *\n * @example without currency, outputs: 100.00\n * ```ts\n * money.amount\n * ```\n * \n *\n * @example without trailing zeros, outputs: $100\n * ```ts\n * money.withoutTrailingZeros\n * ```\n * \n *\n * @example currency name, outputs: US dollars\n * ```ts\n * money.currencyCode\n * ```\n * \n *\n * @example currency symbol, outputs: $\n * ```ts\n * money.currencySymbol\n * ```\n * \n *\n * @example without currency and without trailing zeros, outputs: 100\n * ```ts\n * money.withoutTrailingZerosAndCurrency\n * ```\n */\nexport function useMoney(money: MoneyV2): UseMoneyValue {\n const {countryIsoCode, languageIsoCode} = useShop();\n const locale = languageIsoCode.includes('_')\n ? languageIsoCode.replace('_', '-')\n : `${languageIsoCode}-${countryIsoCode}`;\n\n if (!locale) {\n throw new Error(\n `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to '<ShopifyProvider/>'. 'locale' is required for 'useMoney()' to work`,\n );\n }\n\n const amount = parseFloat(money.amount);\n\n const {\n defaultFormatter,\n nameFormatter,\n narrowSymbolFormatter,\n withoutTrailingZerosFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n } = useMemo(() => {\n const options = {\n style: 'currency' as const,\n currency: money.currencyCode,\n };\n\n return {\n defaultFormatter: getLazyFormatter(locale, options),\n nameFormatter: getLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'name',\n }),\n narrowSymbolFormatter: getLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'narrowSymbol',\n }),\n withoutTrailingZerosFormatter: getLazyFormatter(locale, {\n ...options,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }),\n withoutCurrencyFormatter: getLazyFormatter(locale),\n withoutTrailingZerosOrCurrencyFormatter: getLazyFormatter(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }),\n };\n }, [money.currencyCode, locale]);\n\n const isPartCurrency = (part: Intl.NumberFormatPart): boolean =>\n part.type === 'currency';\n\n // By wrapping these properties in functions, we only\n // create formatters if they are going to be used.\n const lazyFormatters = useMemo(\n () => ({\n original: () => money,\n currencyCode: () => money.currencyCode,\n\n localizedString: () => defaultFormatter().format(amount),\n\n parts: () => defaultFormatter().formatToParts(amount),\n\n withoutTrailingZeros: () =>\n amount % 1 === 0\n ? withoutTrailingZerosFormatter().format(amount)\n : defaultFormatter().format(amount),\n\n withoutTrailingZerosAndCurrency: () =>\n amount % 1 === 0\n ? withoutTrailingZerosOrCurrencyFormatter().format(amount)\n : withoutCurrencyFormatter().format(amount),\n\n currencyName: () =>\n nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"US dollars\"\n\n currencySymbol: () =>\n defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"USD\"\n\n currencyNarrowSymbol: () =>\n narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)\n ?.value ?? '', // e.g. \"$\"\n\n amount: () =>\n defaultFormatter()\n .formatToParts(amount)\n .filter((part) =>\n ['decimal', 'fraction', 'group', 'integer', 'literal'].includes(\n part.type,\n ),\n )\n .map((part) => part.value)\n .join(''),\n }),\n [\n money,\n amount,\n nameFormatter,\n defaultFormatter,\n narrowSymbolFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n ],\n );\n\n // Call functions automatically when the properties are accessed\n // to keep these functions as an implementation detail.\n return useMemo(\n () =>\n new Proxy(lazyFormatters as unknown as UseMoneyValue, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n get: (target, key) => Reflect.get(target, key)?.call(null),\n }),\n [lazyFormatters],\n );\n}\n\nconst formatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getLazyFormatter(\n locale: string,\n options?: Intl.NumberFormatOptions,\n): () => Intl.NumberFormat {\n const key = JSON.stringify([locale, options]);\n\n return function (): Intl.NumberFormat {\n let formatter = formatterCache.get(key);\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, options);\n formatterCache.set(key, formatter);\n }\n return formatter;\n };\n}\n","import {type ReactNode} from 'react';\nimport {useMoney} from './useMoney.js';\nimport type {MoneyV2, UnitPriceMeasurement} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nexport interface MoneyPropsBase<ComponentGeneric extends React.ElementType> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `div`. */\n as?: ComponentGeneric;\n /** An object with fields that correspond to the Storefront API's [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2). */\n data: PartialDeep<MoneyV2, {recurseIntoArrays: true}>;\n /** Whether to remove the currency symbol from the output. */\n withoutCurrency?: boolean;\n /** Whether to remove trailing zeros (fractional money) from the output. */\n withoutTrailingZeros?: boolean;\n /** A [UnitPriceMeasurement object](https://shopify.dev/api/storefront/2024-10/objects/unitpricemeasurement). */\n measurement?: PartialDeep<UnitPriceMeasurement, {recurseIntoArrays: true}>;\n /** Customizes the separator between the money output and the measurement output. Used with the `measurement` prop. Defaults to `'/'`. */\n measurementSeparator?: ReactNode;\n}\n\n// This article helps understand the typing here https://www.benmvp.com/blog/polymorphic-react-components-typescript/ Ben is the best :)\nexport type MoneyProps<ComponentGeneric extends React.ElementType> =\n MoneyPropsBase<ComponentGeneric> &\n (ComponentGeneric extends keyof React.JSX.IntrinsicElements\n ? Omit<\n React.ComponentPropsWithoutRef<ComponentGeneric>,\n keyof MoneyPropsBase<ComponentGeneric>\n >\n : React.ComponentPropsWithoutRef<ComponentGeneric>);\n\n/**\n * The `Money` component renders a string of the Storefront API's\n * [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2)\n * according to the `locale` in the `ShopifyProvider` component.\n * \n * @see {@link https://shopify.dev/api/hydrogen/components/money}\n * @example basic usage, outputs: $100.00\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} />\n * ```\n * \n *\n * @example without currency, outputs: 100.00\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} withoutCurrency />\n * ```\n * \n *\n * @example without trailing zeros, outputs: $100\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} withoutTrailingZeros />\n * ```\n * \n *\n * @example with per-unit measurement, outputs: $100.00 per G\n * ```ts\n * <Money\n * data={{amount: '100.00', currencyCode: 'USD'}}\n * measurement={{referenceUnit: 'G'}}\n * measurementSeparator=\" per \"\n * />\n * ```\n */\nexport function Money<ComponentGeneric extends React.ElementType = 'div'>({\n data,\n as,\n withoutCurrency,\n withoutTrailingZeros,\n measurement,\n measurementSeparator = '/',\n ...passthroughProps\n}: MoneyProps<ComponentGeneric>): JSX.Element {\n if (!isMoney(data)) {\n throw new Error(\n `<Money/> needs a valid 'data' prop that has 'amount' and 'currencyCode'`,\n );\n }\n const moneyObject = useMoney(data);\n const Wrapper = as ?? 'div';\n\n let output = moneyObject.localizedString;\n\n if (withoutCurrency || withoutTrailingZeros) {\n if (withoutCurrency && !withoutTrailingZeros) {\n output = moneyObject.amount;\n } else if (!withoutCurrency && withoutTrailingZeros) {\n output = moneyObject.withoutTrailingZeros;\n } else {\n // both\n output = moneyObject.withoutTrailingZerosAndCurrency;\n }\n }\n\n return (\n <Wrapper {...passthroughProps}>\n {output}\n {measurement && measurement.referenceUnit && (\n <>\n {measurementSeparator}\n {measurement.referenceUnit}\n </>\n )}\n </Wrapper>\n );\n}\n\n// required in order to narrow the money object down and make TS happy\nfunction isMoney(\n maybeMoney: PartialDeep<MoneyV2, {recurseIntoArrays: true}>,\n): maybeMoney is MoneyV2 {\n return (\n typeof maybeMoney.amount === 'string' &&\n !!maybeMoney.amount &&\n typeof maybeMoney.currencyCode === 'string' &&\n !!maybeMoney.currencyCode\n );\n}\n","import {Money, type MoneyPropsBase} from './Money.js';\nimport {useCart} from './CartProvider.js';\n\ninterface CartCostPropsBase {\n /** A string type that defines the type of cost needed. Valid values: `total`, `subtotal`, `tax`, or `duty`. */\n amountType?: 'total' | 'subtotal' | 'tax' | 'duty';\n /** Any `ReactNode` elements. */\n children?: React.ReactNode;\n}\n\ntype CartCostProps = Omit<React.ComponentProps<typeof Money>, 'data'> &\n CartCostPropsBase;\n\n/**\n * The `CartCost` component renders a `Money` component with the cost associated with the `amountType` prop.\n * If no `amountType` prop is specified, then it defaults to `totalAmount`.\n * Depends on `useCart()` and must be a child of `<CartProvider/>`\n */\nexport function CartCost(props: CartCostProps): JSX.Element | null {\n const {cost} = useCart();\n const {amountType = 'total', children, ...passthroughProps} = props;\n let amount;\n\n if (amountType == 'total') {\n amount = cost?.totalAmount;\n } else if (amountType == 'subtotal') {\n amount = cost?.subtotalAmount;\n } else if (amountType == 'tax') {\n amount = cost?.totalTaxAmount;\n } else if (amountType == 'duty') {\n amount = cost?.totalDutyAmount;\n }\n\n if (amount == null) {\n return null;\n }\n\n return (\n <Money {...passthroughProps} data={amount}>\n {children}\n </Money>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface CartCostPropsForDocs<AsType extends React.ElementType = 'div'>\n extends Omit<MoneyPropsBase<AsType>, 'data'>,\n CartCostPropsBase {}\n","import {useContext, createContext, type ReactNode} from 'react';\nimport {\n ComponentizableCartLine,\n type CartLine,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\ntype CartLinePartialDeep = PartialDeep<\n CartLine | ComponentizableCartLine,\n {recurseIntoArrays: true}\n>;\n\nexport const CartLineContext = createContext<CartLinePartialDeep | null>(null);\n\n/**\n * The `useCartLine` hook provides access to the [CartLine object](https://shopify.dev/api/storefront/2024-10/objects/cartline) from the Storefront API. It must be a descendent of a `CartProvider` component.\n */\nexport function useCartLine(): CartLinePartialDeep {\n const context = useContext(CartLineContext);\n\n if (context == null) {\n throw new Error('Expected a cart line context but none was found');\n }\n\n return context;\n}\n\ntype CartLineProviderProps = {\n /** Any `ReactNode` elements. */\n children: ReactNode;\n /** A cart line object. */\n line: CartLinePartialDeep;\n};\n\n/**\n * The `CartLineProvider` component creates a context for using a cart line.\n */\nexport function CartLineProvider({\n children,\n line,\n}: CartLineProviderProps): JSX.Element {\n return (\n <CartLineContext.Provider value={line}>{children}</CartLineContext.Provider>\n );\n}\n","import type {ComponentPropsWithoutRef, ElementType} from 'react';\nimport {useCartLine} from './CartLineProvider.js';\n\ninterface CartLineQuantityBaseProps<\n ComponentGeneric extends ElementType = 'span',\n> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `span`. */\n as?: ComponentGeneric;\n}\n\nexport type CartLineQuantityProps<ComponentGeneric extends ElementType> =\n CartLineQuantityBaseProps<ComponentGeneric> &\n Omit<\n ComponentPropsWithoutRef<ComponentGeneric>,\n keyof CartLineQuantityBaseProps<ComponentGeneric>\n >;\n\n/**\n * The `<CartLineQuantity/>` component renders a `span` (or another element / component that can be customized by the `as` prop) with the cart line's quantity.\n *\n * It must be a descendent of a `<CartLineProvider/>` component, and uses the `useCartLine()` hook internally.\n */\nexport function CartLineQuantity<ComponentGeneric extends ElementType = 'span'>(\n props: CartLineQuantityProps<ComponentGeneric>,\n): JSX.Element {\n const cartLine = useCartLine();\n const {as, ...passthroughProps} = props;\n\n const Wrapper = as ? as : 'span';\n\n return <Wrapper {...passthroughProps}>{cartLine.quantity}</Wrapper>;\n}\n","import {useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {useCartLine} from './CartLineProvider.js';\nimport {BaseButton, type BaseButtonProps} from './BaseButton.js';\nimport type {CartLineUpdateInput} from './storefront-api-types.js';\n\ninterface CartLineQuantityAdjustButtonBaseProps {\n /** The adjustment for a cart line's quantity. Valid values: `increase` (default), `decrease`, or `remove`. */\n adjust?: 'increase' | 'decrease' | 'remove';\n}\n\ntype CartLineQuantityAdjustButtonProps<\n AsType extends React.ElementType = 'button',\n> = BaseButtonProps<AsType> & CartLineQuantityAdjustButtonBaseProps;\n\n/**\n * The `<CartLineQuantityAdjustButton />` component renders a button that adjusts the cart line's quantity when pressed.\n *\n * It must be a descendent of `<CartLineProvider/>` and `<CartProvider/>`.\n */\nexport function CartLineQuantityAdjustButton<\n AsType extends React.ElementType = 'button',\n>(props: CartLineQuantityAdjustButtonProps<AsType>): JSX.Element {\n const {status, linesRemove, linesUpdate} = useCart();\n const cartLine = useCartLine();\n const {children, adjust, onClick, ...passthroughProps} = props;\n\n const handleAdjust = useCallback(() => {\n if (adjust === 'remove') {\n linesRemove([cartLine?.id ?? '']);\n return;\n }\n\n const quantity =\n adjust === 'decrease'\n ? (cartLine?.quantity ?? 0) - 1\n : (cartLine?.quantity ?? 0) + 1;\n\n if (quantity <= 0) {\n linesRemove([cartLine?.id ?? '']);\n return;\n }\n\n const lineUpdate = {\n id: cartLine?.id ?? '',\n quantity,\n attributes: (cartLine?.attributes ??\n []) as CartLineUpdateInput['attributes'],\n } satisfies CartLineUpdateInput;\n\n linesUpdate([lineUpdate]);\n }, [\n adjust,\n cartLine?.attributes,\n cartLine?.id,\n cartLine?.quantity,\n linesRemove,\n linesUpdate,\n ]);\n\n // Only certain 'as' types such as 'button' contain `disabled`\n const disabledAttr = (passthroughProps as {disabled?: boolean}).disabled;\n\n return (\n <BaseButton\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleAdjust}\n disabled={\n typeof disabledAttr !== 'undefined' ? disabledAttr : status !== 'idle'\n }\n >\n {children}\n </BaseButton>\n );\n}\n","/**\n * Meant to be used with GraphQL CodeGen to type the Storefront API's custom scalars correctly.\n * Reference for the GraphQL types: https://shopify.dev/docs/api/storefront/2024-10/scalars/HTML\n * Note: JSON is generated as 'unknown' by default.\n */\nexport const storefrontApiCustomScalars = {\n // Keep in sync with the definitions in the app/nextjs/codegen.ts!\n DateTime: 'string',\n Decimal: 'string',\n HTML: 'string',\n URL: 'string',\n Color: 'string',\n UnsignedInt64: 'string',\n};\n\n/**\n * Meant to be used with GraphQL CodeGen to type the Storefront API's custom scalars correctly.\n * Reference for the GraphQL types: https://shopify.dev/docs/api/customer/2024-10/scalars/HTML\n * Note: JSON is generated as 'unknown' by default.\n */\nexport const customerAccountApiCustomScalars = {\n DateTime: 'string',\n Decimal: 'string',\n HTML: 'string',\n ISO8601DateTime: 'string',\n URL: 'string',\n UnsignedInt64: 'string',\n};\n","import type {ExternalVideo as ExternalVideoType} from './storefront-api-types.js';\nimport type {Entries, PartialDeep} from 'type-fest';\nimport {forwardRef, IframeHTMLAttributes} from 'react';\n\nexport interface ExternalVideoBaseProps {\n /**\n * An object with fields that correspond to the Storefront API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).\n */\n data: PartialDeep<ExternalVideoType, {recurseIntoArrays: true}>;\n /** An object containing the options available for either\n * [YouTube](https://developers.google.com/youtube/player_parameters#Parameters) or\n * [Vimeo](https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters).\n */\n options?: YouTube | Vimeo;\n}\n\nexport type ExternalVideoProps = Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n 'src'\n> &\n ExternalVideoBaseProps;\n\n/**\n * The `ExternalVideo` component renders an embedded video for the Storefront\n * API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).\n */\nexport const ExternalVideo = forwardRef<HTMLIFrameElement, ExternalVideoProps>(\n (props, ref): JSX.Element => {\n const {\n data,\n options,\n id = data.id,\n frameBorder = '0',\n allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture',\n allowFullScreen = true,\n loading = 'lazy',\n ...passthroughProps\n } = props;\n\n if (!data.embedUrl) {\n throw new Error(`<ExternalVideo/> requires the 'embedUrl' property`);\n }\n\n let finalUrl: string = data.embedUrl;\n\n if (options) {\n const urlObject = new URL(data.embedUrl);\n for (const [key, value] of Object.entries(options) as Entries<\n typeof options\n >) {\n if (typeof value === 'undefined') {\n continue;\n }\n\n urlObject.searchParams.set(key, value.toString());\n }\n finalUrl = urlObject.toString();\n }\n\n return (\n <iframe\n {...passthroughProps}\n id={id ?? data.embedUrl}\n title={data.alt ?? data.id ?? 'external video'}\n frameBorder={frameBorder}\n allow={allow}\n allowFullScreen={allowFullScreen}\n src={finalUrl}\n loading={loading}\n ref={ref}\n ></iframe>\n );\n },\n);\n\ninterface YouTube {\n autoplay?: 0 | 1;\n cc_lang_pref?: string;\n cc_load_policy?: 1;\n color?: 'red' | 'white';\n controls?: 0 | 1;\n disablekb?: 0 | 1;\n enablejsapi?: 0 | 1;\n end?: number;\n fs?: 0 | 1;\n hl?: string;\n iv_load_policy?: 1 | 3;\n list?: string;\n list_type?: 'playlist' | 'user_uploads';\n loop?: 0 | 1;\n modest_branding?: 1;\n origin?: string;\n playlist?: string;\n plays_inline?: 0 | 1;\n rel?: 0 | 1;\n start?: number;\n widget_referrer?: string;\n}\n\ntype VimeoBoolean = 0 | 1 | boolean;\n\ninterface Vimeo {\n autopause?: VimeoBoolean;\n autoplay?: VimeoBoolean;\n background?: VimeoBoolean;\n byline?: VimeoBoolean;\n color?: string;\n controls?: VimeoBoolean;\n dnt?: VimeoBoolean;\n loop?: VimeoBoolean;\n muted?: VimeoBoolean;\n pip?: VimeoBoolean;\n playsinline?: VimeoBoolean;\n portrait?: VimeoBoolean;\n quality?: '240p' | '360p' | '540p' | '720p' | '1080p' | '2k' | '4k';\n speed?: VimeoBoolean;\n '#t'?: string;\n texttrack?: string;\n title?: VimeoBoolean;\n transparent?: VimeoBoolean;\n}\n","/**\n * This file provides utility functions for determining whether or not an option value combination is present in an encoded option value string.\n *\n * In V1 of the encoding strategy, option value arrays are encoded as a trie with the following rules:\n * - `:` `,` ` ` and `-` are control characters.\n * - `:` indicates a new option. ex: 0:1 indicates value 0 for the option in position 1, value 1 for the option in position 2.\n * - `,` indicates the end of a repeated prefix, mulitple consecutive commas indicate the end of multiple repeated prefixes.\n * - ` ` indicates a gap in the sequence of option values. ex: `0 4` indicates option values in position 0 and 4 are present.\n * - `-` indicates a continuous range of option values. ex: `0 1-3 4`. Ranges are only present encoded in the final option value position, so for example the trie for the set [[0,0,0],[0,0,1], ..., [0,2,2]] will be structured as `0:0:0-2,1:0-2,2:0-2`, not `0:0-2:0-2`.\n */\n\nimport {Product} from './storefront-api-types.js';\n\nconst OPTION_VALUE_SEPARATOR = ',';\n\nconst V1_CONTROL_CHARS = {\n OPTION: ':',\n END_OF_PREFIX: ',',\n SEQUENCE_GAP: ' ',\n RANGE: '-',\n};\n\nexport type IsOptionValueCombinationInEncodedVariant = (\n targetOptionValueCombination: number[],\n encodedVariantField: string,\n) => boolean;\n\n/**\n * Determine whether an option value combination is present in an encoded option value string. Function is memoized by encodedVariantField.\n *\n * @param targetOptionValueCombination - Indices of option values to look up in the encoded option value string. A partial set of indices may be passed to determine whether a node or any children is present. For example, if a product has 3 options, passing [0] will return true if any option value combination for the first option's option value is present in the encoded string.\n * @param encodedVariantField - Encoded option value string from the Storefront API, e.g. [product.encodedVariantExistence](/docs/api/storefront/2024-10/objects/Product#field-encodedvariantexistence) or [product.encodedVariantAvailability](/docs/api/storefront/2024-10/objects/Product#field-encodedvariantavailability)\n * @returns - True if a full or partial targetOptionValueIndices is present in the encoded option value string, false otherwise.\n */\nexport const isOptionValueCombinationInEncodedVariant: IsOptionValueCombinationInEncodedVariant =\n ((): IsOptionValueCombinationInEncodedVariant => {\n const decodedOptionValues = new Map<string, Set<string>>();\n\n return function (\n targetOptionValueCombination: number[],\n encodedVariantField: string,\n ): boolean {\n if (targetOptionValueCombination.length === 0) {\n return false;\n }\n\n if (!decodedOptionValues.has(encodedVariantField)) {\n const decodedOptionValuesSet = new Set<string>();\n\n for (const optionValue of decodeEncodedVariant(encodedVariantField)) {\n // add the complete option value to the decoded option values set\n decodedOptionValuesSet.add(optionValue.join(OPTION_VALUE_SEPARATOR));\n\n // add all composite parts of the option value to the decoded option values set. e.g. if the option value is [0,1,2], add \"0\", \"0,1\", \"0,1,2\"\n for (let i = 0; i < optionValue.length; i++) {\n decodedOptionValuesSet.add(\n optionValue.slice(0, i + 1).join(OPTION_VALUE_SEPARATOR),\n );\n }\n }\n\n decodedOptionValues.set(encodedVariantField, decodedOptionValuesSet);\n }\n\n return Boolean(\n decodedOptionValues\n .get(encodedVariantField)\n ?.has(targetOptionValueCombination.join(OPTION_VALUE_SEPARATOR)),\n );\n };\n })();\n\ntype EncodedVariantField =\n | Product['encodedVariantAvailability']\n | Product['encodedVariantExistence'];\ntype DecodedOptionValues = number[][];\n\n/**\n * For an encoded option value string, decode into option value combinations. Entries represent a valid combination formatted as an array of option value positions.\n * @param encodedVariantField - Encoded option value string from the Storefront API, e.g. [product.encodedVariantExistence](/docs/api/storefront/2024-10/objects/Product#field-encodedvariantexistence) or [product.encodedVariantAvailability](/docs/api/storefront/2024-10/objects/Product#field-encodedvariantavailability)\n * @returns Decoded option value combinations\n */\nexport function decodeEncodedVariant(\n encodedVariantField: EncodedVariantField,\n): DecodedOptionValues {\n if (!encodedVariantField) return [];\n\n if (encodedVariantField.startsWith('v1_')) {\n return v1Decoder(stripVersion(encodedVariantField));\n }\n\n throw new Error('Unsupported option value encoding');\n}\n\nconst stripVersion: (encodedVariantField: string) => string = (\n encodedVariantField: string,\n) => encodedVariantField.replace(/^v1_/, '');\n\n/**\n * We encode an array of arrays representing variants, expressed in terms of options and option values, as a trie.\n *\n * This encoding strategy allows extremely large numbers of variants to be expressed in an extremely compact data structure.\n *\n * Integers represent option and values, so [0,0,0] represents option_value at array index 0 for the options at array indexes 0, 1 and 2\n *\n * `:`, `,`, ` ` and `-` are control characters.\n * `:` indicates a new option\n * `,` indicates the end of a repeated prefix, mulitple consecutive commas indicate the end of multiple repeated prefixes.\n * ` ` indicates a gap in the sequence of option values\n * `-` indicates a continuous range of option values\n *\n * Encoding process:\n *\n * example input array: [[0,0,0], [0,1,0], [0,1,1], [1,0,0], [1,0,1], [1,1,1], [2,0,1], [2,1,0]]\n *\n * step 1: encode as string: \"0:0:0,0:1:0,0:1:1,1:0:0,1:0:1,1:1:1,2:0:1,2:1:0,\"\n * step 2: combine nodes that share a prefix: \"0:0:0,0:1:0 1,1:0:0 1,1:1:1,2:0:1,2:1:0,\"\n * step 3: encode data as a trie so no prefixes need to be repeated: \"0:0:0,1:0 1,,1:0:0 1,1:1,,2:0:1,1:0,,\"\n * step 4: since the options are sorted, use a dash to express ranges: \"0:0:0,1:0-1,,1:0:0-1,1:1,,2:0:1,1:0,,\"\n */\nfunction v1Decoder(encodedVariantField: string): number[][] {\n const tokenizer = /[ :,-]/g;\n let index = 0;\n let token: RegExpExecArray | null;\n const options: number[][] = [];\n const currentOptionValue: number[] = [];\n let depth = 0;\n let rangeStart: number | null = null;\n\n // iterate over control characters\n while ((token = tokenizer.exec(encodedVariantField))) {\n const operation = token[0];\n const optionValueIndex =\n Number.parseInt(encodedVariantField.slice(index, token.index)) || 0;\n\n if (rangeStart !== null) {\n // If a range has been started, iterate over the range and add each option value to the list of options\n // - `rangeStart` is set if the last control char was a dash, e.g. `0` for 0-2. It represents the numeric option value position for the start of the range.\n // - `optionValueIndex` is the numeric option value position for the end of the range\n for (; rangeStart < optionValueIndex; rangeStart++) {\n currentOptionValue[depth] = rangeStart;\n options.push([...currentOptionValue]);\n }\n // indicates the range has been processed\n rangeStart = null;\n }\n\n currentOptionValue[depth] = optionValueIndex;\n\n if (operation === V1_CONTROL_CHARS.RANGE) {\n // dash operation indicates we are in a range. e.g. 0-2 means option values 0, 1, 2\n rangeStart = optionValueIndex;\n } else if (operation === V1_CONTROL_CHARS.OPTION) {\n // colon operation indicates that we are moving down to the next layer of option values. e.g. 0:0:0-2 means we traverse down from option1 to option3 and represents [[0,0,0], [0,0,1], [0,0,2]]\n depth++;\n } else {\n if (\n operation === V1_CONTROL_CHARS.SEQUENCE_GAP ||\n (operation === V1_CONTROL_CHARS.END_OF_PREFIX &&\n encodedVariantField[token.index - 1] !==\n V1_CONTROL_CHARS.END_OF_PREFIX)\n ) {\n // add the current option value to the list of options if we hit a gap in our sequence or we are at the end of our depth and need to move back up\n options.push([...currentOptionValue]);\n }\n if (operation === V1_CONTROL_CHARS.END_OF_PREFIX) {\n // go up an option level, trash the last item in currentOptionValue\n currentOptionValue.pop();\n depth--;\n }\n }\n index = tokenizer.lastIndex;\n }\n\n // Because we iterate over control characters and the range processing happens in the while,\n // if the last control char is a range we need to manually add the final range to the option list.\n const lastRangeStartIndex = encodedVariantField.lastIndexOf('-');\n if (rangeStart != null && lastRangeStartIndex > 0) {\n const finalValueIndex = parseInt(\n encodedVariantField.substring(lastRangeStartIndex + 1),\n );\n for (; rangeStart <= finalValueIndex; rangeStart++) {\n currentOptionValue[depth] = rangeStart;\n options.push([...currentOptionValue]);\n }\n }\n\n return options;\n}\n","import {isOptionValueCombinationInEncodedVariant} from './optionValueDecoder.js';\nimport type {\n Product,\n ProductOption,\n ProductOptionValue,\n ProductVariant,\n SelectedOption,\n} from './storefront-api-types';\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: RecursivePartial<T[P]>;\n};\ntype ProductOptionsMapping = Record<string, number>;\ntype ProductOptionValueState = {\n variant: ProductVariant;\n handle: string;\n variantUriQuery: string;\n selected: boolean;\n exists: boolean;\n available: boolean;\n isDifferentProduct: boolean;\n};\ntype MappedProductOptionValue = ProductOptionValue & ProductOptionValueState;\n\n/**\n * Creates a mapping of product options to their index for matching encoded values\n * For example, a product option of\n * [\n * \\{\n * name: 'Color',\n * optionValues: [\\{name: 'Red'\\}, \\{name: 'Blue'\\}]\n * \\},\n * \\{\n * name: 'Size',\n * optionValues: [\\{name: 'Small'\\}, \\{name: 'Medium'\\}, \\{name: 'Large'\\}]\n * \\}\n * ]\n * Would return\n * [\n * \\{Red: 0, Blue: 1\\},\n * \\{Small: 0, Medium: 1, Large: 2\\}\n * ]\n */\nfunction mapProductOptions(options: ProductOption[]): ProductOptionsMapping[] {\n return options.map((option: ProductOption) => {\n return Object.assign(\n {},\n ...(option?.optionValues\n ? option.optionValues.map((value, index) => {\n return {[value.name]: index};\n })\n : []),\n ) as ProductOptionsMapping;\n });\n}\n\n/**\n * Converts the product option into an Object\\<key, value\\> for building query params\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n */\nexport function mapSelectedProductOptionToObject(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): Record<string, string> {\n return Object.assign(\n {},\n ...options.map((key) => {\n return {[key.name]: key.value};\n }),\n ) as Record<string, string>;\n}\n\n/**\n * Returns the JSON stringify result of mapSelectedProductOptionToObject\n */\nfunction mapSelectedProductOptionToObjectAsString(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): string {\n return JSON.stringify(mapSelectedProductOptionToObject(options));\n}\n\n/**\n * Encode the selected product option as a key for mapping to the encoded variants\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * [0,1]\n *\n * Also works with the result of mapSelectedProductOption. For example:\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n * Would return\n * [0,1]\n *\n * @param selectedOption - The selected product option\n * @param productOptionMappings - The result of product option mapping from mapProductOptions\n * @returns\n */\nfunction encodeSelectedProductOptionAsKey(\n selectedOption:\n | Pick<SelectedOption, 'name' | 'value'>[]\n | Record<string, string>,\n productOptionMappings: ProductOptionsMapping[],\n): string {\n if (Array.isArray(selectedOption)) {\n return JSON.stringify(\n selectedOption.map((key, index) => {\n return productOptionMappings[index][key.value];\n }),\n );\n } else {\n return JSON.stringify(\n Object.keys(selectedOption).map((key, index) => {\n return productOptionMappings[index][selectedOption[key]];\n }),\n );\n }\n}\n\n/**\n * Takes an array of product variants and maps them to an object with the encoded selected option values as the key.\n * For example, a product variant of\n * [\n * \\{\n * id: 1,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Small'\\},\n * ],\n * \\},\n * \\{\n * id: 2,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Medium'\\},\n * ],\n * \\}\n * ]\n * Would return\n * \\{\n * '[0,0]': \\{id: 1, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Small'\\}]\\},\n * '[0,1]': \\{id: 2, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Medium'\\}]\\},\n * \\}\n */\nfunction mapVariants(\n variants: ProductVariant[],\n productOptionMappings: ProductOptionsMapping[],\n): Record<string, ProductVariant> {\n return Object.assign(\n {},\n ...variants.map((variant) => {\n const variantKey = encodeSelectedProductOptionAsKey(\n variant.selectedOptions || [],\n productOptionMappings,\n );\n return {[variantKey]: variant};\n }),\n ) as Record<string, ProductVariant>;\n}\n\nexport type MappedProductOptions = Omit<ProductOption, 'optionValues'> & {\n optionValues: MappedProductOptionValue[];\n};\n\nconst PRODUCT_INPUTS = [\n 'options',\n 'selectedOrFirstAvailableVariant',\n 'adjacentVariants',\n];\n\nconst PRODUCT_INPUTS_EXTRA = [\n 'handle',\n 'encodedVariantExistence',\n 'encodedVariantAvailability',\n];\n\nfunction logErrorAndReturnFalse(key: string): boolean {\n console.error(\n `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`,\n );\n return false;\n}\n\nexport function checkProductParam(\n product: RecursivePartial<Product>,\n checkAll = false,\n): Product {\n let validParam = true;\n const productKeys = Object.keys(product);\n\n // Check product input\n (checkAll\n ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA]\n : PRODUCT_INPUTS\n ).forEach((key) => {\n if (!productKeys.includes(key)) {\n validParam = logErrorAndReturnFalse(key);\n }\n });\n\n // Check for nested options requirements\n if (product.options) {\n const firstOption = product?.options[0];\n\n if (checkAll && !firstOption?.name) {\n validParam = logErrorAndReturnFalse('options.name');\n }\n\n // Check for options.optionValues\n if (product?.options[0]?.optionValues) {\n const firstOptionValues = product.options[0].optionValues[0];\n\n // Check for options.optionValues.name\n if (checkAll && !firstOptionValues?.name) {\n validParam = logErrorAndReturnFalse('options.optionValues.name');\n }\n\n // Check for options.optionValues.firstSelectableVariant\n if (firstOptionValues?.firstSelectableVariant) {\n // check product variant\n validParam = checkProductVariantParam(\n firstOptionValues.firstSelectableVariant,\n 'options.optionValues.firstSelectableVariant',\n validParam,\n checkAll,\n );\n } else {\n validParam = logErrorAndReturnFalse(\n 'options.optionValues.firstSelectableVariant',\n );\n }\n } else {\n validParam = logErrorAndReturnFalse('options.optionValues');\n }\n }\n\n // Check for nested selectedOrFirstAvailableVariant requirements\n if (product.selectedOrFirstAvailableVariant) {\n validParam = checkProductVariantParam(\n product.selectedOrFirstAvailableVariant,\n 'selectedOrFirstAvailableVariant',\n validParam,\n checkAll,\n );\n }\n\n // Check for nested adjacentVariants requirements\n if (!!product.adjacentVariants && product.adjacentVariants[0]) {\n validParam = checkProductVariantParam(\n product.adjacentVariants[0],\n 'adjacentVariants',\n validParam,\n checkAll,\n );\n }\n\n return (validParam ? product : {}) as Product;\n}\n\nfunction checkProductVariantParam(\n variant: RecursivePartial<ProductVariant>,\n key: string,\n currentValidParamState: boolean,\n checkAll: boolean,\n): boolean {\n let validParam = currentValidParamState;\n\n if (checkAll && !variant.product?.handle) {\n validParam = logErrorAndReturnFalse(`${key}.product.handle`);\n }\n if (variant.selectedOptions) {\n const firstSelectedOption = variant.selectedOptions[0];\n if (!firstSelectedOption?.name) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);\n }\n if (!firstSelectedOption?.value) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);\n }\n } else {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);\n }\n\n return validParam;\n}\n\n/**\n * Finds all the variants provided by adjacentVariants, options.optionValues.firstAvailableVariant,\n * and selectedOrFirstAvailableVariant and return them in a single array\n */\nexport function getAdjacentAndFirstAvailableVariants(\n product: RecursivePartial<Product>,\n): ProductVariant[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product);\n\n if (!checkedProduct.options) return [];\n\n const availableVariants: Record<string, ProductVariant> = {};\n checkedProduct.options.map((option) => {\n option.optionValues?.map((value) => {\n if (value.firstSelectableVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n value.firstSelectableVariant.selectedOptions,\n );\n availableVariants[variantKey] = value.firstSelectableVariant;\n }\n });\n });\n\n checkedProduct.adjacentVariants.map((variant) => {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n variant.selectedOptions,\n );\n availableVariants[variantKey] = variant;\n });\n\n const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;\n if (selectedVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n selectedVariant.selectedOptions,\n );\n availableVariants[variantKey] = selectedVariant;\n }\n\n return Object.values(availableVariants);\n}\n\n/**\n * Returns a product options array with its relevant information\n * about the variant\n */\nexport function getProductOptions(\n product: RecursivePartial<Product>,\n): MappedProductOptions[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product, true);\n\n if (!checkedProduct.options) return [];\n\n const {\n options,\n selectedOrFirstAvailableVariant: selectedVariant,\n adjacentVariants,\n encodedVariantExistence,\n encodedVariantAvailability,\n handle: productHandle,\n } = checkedProduct;\n // Get a mapping of product option names to their index for matching encoded values\n const productOptionMappings = mapProductOptions(options);\n\n // Get the adjacent variants mapped to the encoded selected option values\n const variants = mapVariants(\n selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,\n productOptionMappings,\n );\n\n // Get the key:value version of selected options for building url query params\n const selectedOptions = mapSelectedProductOptionToObject(\n selectedVariant ? selectedVariant.selectedOptions : [],\n );\n\n const productOptions = options.map((option, optionIndex) => {\n return {\n ...option,\n optionValues: option.optionValues.map((value) => {\n const targetOptionParams = {...selectedOptions}; // Clones the selected options\n\n // Modify the selected option value to the current option value\n targetOptionParams[option.name] = value.name;\n\n // Encode the new selected option values as a key for mapping to the product variants\n const targetKey = encodeSelectedProductOptionAsKey(\n targetOptionParams || [],\n productOptionMappings,\n );\n\n // Top-down option check for existence and availability\n const topDownKey = (JSON.parse(targetKey) as number[]).slice(\n 0,\n optionIndex + 1,\n );\n const exists = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantExistence || '',\n );\n const available = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantAvailability || '',\n );\n\n // Get the variant for the current option value if exists, else use the first selectable variant\n const variant: ProductVariant =\n variants[targetKey] || value.firstSelectableVariant;\n\n // Build the query params for this option value\n const variantOptionParam = mapSelectedProductOptionToObject(\n variant.selectedOptions || [],\n );\n const searchParams = new URLSearchParams(variantOptionParam);\n const handle = variant?.product?.handle;\n\n return {\n ...value,\n variant,\n handle,\n variantUriQuery: searchParams.toString(),\n selected: selectedOptions[option.name] === value.name,\n exists,\n available,\n isDifferentProduct: handle !== productHandle,\n };\n }),\n };\n });\n\n return productOptions;\n}\n","/* eslint-disable eslint-comments/disable-enable-pair */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable hydrogen/prefer-image-component */\nimport * as React from 'react';\nimport type {PartialDeep} from 'type-fest';\nimport type {Image as ImageType} from './storefront-api-types.js';\n\n/*\n * An optional prop you can use to change the\n * default srcSet generation behaviour\n */\ntype SrcSetOptions = {\n /** The number of sizes to generate */\n intervals: number;\n /** The smallest image size */\n startingWidth: number;\n /** The increment by which to increase for each size, in pixels */\n incrementSize: number;\n /** The size used for placeholder fallback images */\n placeholderWidth: number;\n};\n\ntype NormalizedProps = {\n alt: string;\n aspectRatio: string | undefined;\n height: string;\n src: string | undefined;\n width: string;\n};\n\nexport type LoaderParams = {\n /** The base URL of the image */\n src?: ImageType['url'];\n /** The URL param that controls width */\n width?: number;\n /** The URL param that controls height */\n height?: number;\n /** The URL param that controls the cropping region */\n crop?: Crop;\n};\n\nexport type Loader = (params: LoaderParams) => string;\n\n/*\n * @TODO: Expand to include focal point support; and/or switch this to be an SF API type\n */\ntype Crop = 'center' | 'top' | 'bottom' | 'left' | 'right';\n\nexport type HydrogenImageProps = React.ComponentPropsWithRef<'img'> &\n HydrogenImageBaseProps;\n\ntype HydrogenImageBaseProps = {\n /** The aspect ratio of the image, in the format of `width/height`.\n *\n * @example\n * ```\n * <Image data={productImage} aspectRatio=\"4/5\" />\n * ```\n */\n aspectRatio?: string;\n /** The crop position of the image.\n *\n * @remarks\n * In the event that AspectRatio is set, without specifying a crop,\n * the Shopify CDN won't return the expected image.\n *\n * @defaultValue `center`\n */\n crop?: Crop;\n /** Data mapping to the [Storefront API `Image`](https://shopify.dev/docs/api/storefront/2024-10/objects/Image) object. Must be an Image object.\n *\n * @example\n * ```\n * import {IMAGE_FRAGMENT, Image} from '@shopify/hydrogen';\n *\n * export const IMAGE_QUERY = `#graphql\n * ${IMAGE_FRAGMENT}\n * query {\n * product {\n * featuredImage {\n * ...Image\n * }\n * }\n * }`\n *\n * <Image\n * data={productImage}\n * sizes=\"(min-width: 45em) 50vw, 100vw\"\n * aspectRatio=\"4/5\"\n * />\n * ```\n *\n * Image: {@link https://shopify.dev/api/storefront/reference/common-objects/image}\n */\n data?: PartialDeep<ImageType, {recurseIntoArrays: true}>;\n /** A function that returns a URL string for an image.\n *\n * @remarks\n * By default, this uses Shopify’s CDN {@link https://cdn.shopify.com/} but you can provide\n * your own function to use a another provider, as long as they support URL based image transformations.\n */\n loader?: Loader;\n /** An optional prop you can use to change the default srcSet generation behaviour */\n srcSetOptions?: SrcSetOptions;\n};\n\n/**\n * A Storefront API GraphQL fragment that can be used to query for an image.\n */\nexport const IMAGE_FRAGMENT = `#graphql\n fragment Image on Image {\n altText\n url\n width\n height\n }\n`;\n\n/**\n * Hydrogen’s Image component is a wrapper around the HTML image element.\n * It supports the same props as the HTML `img` element, but automatically\n * generates the srcSet and sizes attributes for you. For most use cases,\n * you’ll want to set the `aspectRatio` prop to ensure the image is sized\n * correctly.\n *\n * @remarks\n * - `decoding` is set to `async` by default.\n * - `loading` is set to `lazy` by default.\n * - `alt` will automatically be set to the `altText` from the Storefront API if passed in the `data` prop\n * - `src` will automatically be set to the `url` from the Storefront API if passed in the `data` prop\n *\n * @example\n * A responsive image with a 4:5 aspect ratio:\n * ```\n * <Image\n * data={product.featuredImage}\n * aspectRatio=\"4/5\"\n * sizes=\"(min-width: 45em) 40vw, 100vw\"\n * />\n * ```\n * @example\n * A fixed size image:\n * ```\n * <Image\n * data={product.featuredImage}\n * width={100}\n * height={100}\n * />\n * ```\n *\n * {@link https://shopify.dev/docs/api/hydrogen-react/components/image}\n */\nexport const Image = React.forwardRef<HTMLImageElement, HydrogenImageProps>(\n (\n {\n alt,\n aspectRatio,\n crop = 'center',\n data,\n decoding = 'async',\n height = 'auto',\n loader = shopifyLoader,\n loading = 'lazy',\n sizes,\n src,\n srcSetOptions = {\n intervals: 15,\n startingWidth: 200,\n incrementSize: 200,\n placeholderWidth: 100,\n },\n width = '100%',\n ...passthroughProps\n },\n ref,\n ) => {\n /*\n * Gets normalized values for width, height from data prop\n */\n const normalizedData = React.useMemo(() => {\n /* Only use data width if height is also set */\n const dataWidth: number | undefined =\n data?.width && data?.height ? data?.width : undefined;\n\n const dataHeight: number | undefined =\n data?.width && data?.height ? data?.height : undefined;\n\n return {\n width: dataWidth,\n height: dataHeight,\n unitsMatch: Boolean(unitsMatch(dataWidth, dataHeight)),\n };\n }, [data]);\n\n /*\n * Gets normalized values for width, height, src, alt, and aspectRatio props\n * supporting the presence of `data` in addition to flat props.\n */\n const normalizedProps = React.useMemo(() => {\n const nWidthProp: string | number = width || '100%';\n const widthParts = getUnitValueParts(nWidthProp.toString());\n const nWidth = `${widthParts.number}${widthParts.unit}`;\n\n const autoHeight = height === undefined || height === null;\n const heightParts = autoHeight\n ? null\n : getUnitValueParts(height.toString());\n\n const fixedHeight = heightParts\n ? `${heightParts.number}${heightParts.unit}`\n : '';\n\n const nHeight = autoHeight ? 'auto' : fixedHeight;\n\n const nSrc: string | undefined = src || data?.url;\n\n if (__HYDROGEN_DEV__ && !nSrc) {\n console.warn(\n `No src or data.url provided to Image component.`,\n passthroughProps?.key || '',\n );\n }\n\n const nAlt: string = data?.altText && !alt ? data?.altText : alt || '';\n\n const nAspectRatio: string | undefined = aspectRatio\n ? aspectRatio\n : normalizedData.unitsMatch\n ? [\n getNormalizedFixedUnit(normalizedData.width),\n getNormalizedFixedUnit(normalizedData.height),\n ].join('/')\n : undefined;\n\n return {\n width: nWidth,\n height: nHeight,\n src: nSrc,\n alt: nAlt,\n aspectRatio: nAspectRatio,\n };\n }, [\n width,\n height,\n src,\n data,\n alt,\n aspectRatio,\n normalizedData,\n passthroughProps?.key,\n ]);\n\n const {intervals, startingWidth, incrementSize, placeholderWidth} =\n srcSetOptions;\n\n /*\n * This function creates an array of widths to be used in srcSet\n */\n const imageWidths = React.useMemo(() => {\n return generateImageWidths(\n width,\n intervals,\n startingWidth,\n incrementSize,\n );\n }, [width, intervals, startingWidth, incrementSize]);\n\n const fixedWidth = isFixedWidth(normalizedProps.width);\n\n if (__HYDROGEN_DEV__ && !sizes && !fixedWidth) {\n console.warn(\n [\n 'No sizes prop provided to Image component,',\n 'you may be loading unnecessarily large images.',\n `Image used is ${\n src || data?.url || passthroughProps?.key || 'unknown'\n }`,\n ].join(' '),\n );\n }\n\n /*\n * We check to see whether the image is fixed width or not,\n * if fixed, we still provide a srcSet, but only to account for\n * different pixel densities.\n */\n if (fixedWidth) {\n return (\n <FixedWidthImage\n aspectRatio={aspectRatio}\n crop={crop}\n decoding={decoding}\n height={height}\n imageWidths={imageWidths}\n loader={loader}\n loading={loading}\n normalizedProps={normalizedProps}\n passthroughProps={passthroughProps}\n ref={ref}\n width={width}\n data={data}\n />\n );\n } else {\n return (\n <FluidImage\n aspectRatio={aspectRatio}\n crop={crop}\n decoding={decoding}\n imageWidths={imageWidths}\n loader={loader}\n loading={loading}\n normalizedProps={normalizedProps}\n passthroughProps={passthroughProps}\n placeholderWidth={placeholderWidth}\n ref={ref}\n sizes={sizes}\n data={data}\n />\n );\n }\n },\n);\n\ntype FixedImageExludedProps =\n | 'data'\n | 'loader'\n | 'loaderOptions'\n | 'sizes'\n | 'srcSetOptions'\n | 'widths';\n\ntype FixedWidthImageProps = Omit<HydrogenImageProps, FixedImageExludedProps> &\n Pick<HydrogenImageBaseProps, 'data'> & {\n loader: Loader;\n passthroughProps: React.ImgHTMLAttributes<HTMLImageElement>;\n normalizedProps: NormalizedProps;\n imageWidths: number[];\n ref: React.Ref<HTMLImageElement>;\n };\n\nconst FixedWidthImage = React.forwardRef<\n HTMLImageElement,\n FixedWidthImageProps\n>(\n (\n {\n aspectRatio,\n crop,\n decoding,\n height,\n imageWidths,\n loader = shopifyLoader,\n loading,\n normalizedProps,\n passthroughProps,\n width,\n data,\n },\n ref,\n ) => {\n const fixed = React.useMemo(() => {\n const intWidth: number | undefined = getNormalizedFixedUnit(width);\n const intHeight: number | undefined = getNormalizedFixedUnit(height);\n\n /*\n * The aspect ratio for fixed width images is taken from the explicitly\n * set prop, but if that's not present, and both width and height are\n * set, we calculate the aspect ratio from the width and height—as\n * long as they share the same unit type (e.g. both are 'px').\n */\n const fixedAspectRatio = aspectRatio\n ? aspectRatio\n : unitsMatch(normalizedProps.width, normalizedProps.height)\n ? [intWidth, intHeight].join('/')\n : normalizedProps.aspectRatio\n ? normalizedProps.aspectRatio\n : undefined;\n\n /*\n * The Sizes Array generates an array of all the parts\n * that make up the srcSet, including the width, height, and crop\n */\n const sizesArray =\n imageWidths === undefined\n ? undefined\n : generateSizes(imageWidths, fixedAspectRatio, crop, {\n width: data?.width ?? undefined,\n height: data?.height ?? undefined,\n });\n\n const fixedHeight = intHeight\n ? intHeight\n : fixedAspectRatio && intWidth\n ? intWidth * (parseAspectRatio(fixedAspectRatio) ?? 1)\n : undefined;\n\n const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);\n const src = loader({\n src: normalizedProps.src,\n width: intWidth,\n height: fixedHeight,\n crop: normalizedProps.height === 'auto' ? undefined : crop,\n });\n\n return {\n width: intWidth,\n aspectRatio: fixedAspectRatio,\n height: fixedHeight,\n srcSet,\n src,\n };\n }, [\n aspectRatio,\n crop,\n data,\n height,\n imageWidths,\n loader,\n normalizedProps,\n width,\n ]);\n\n return (\n <img\n ref={ref}\n alt={normalizedProps.alt}\n decoding={decoding}\n height={fixed.height}\n loading={loading}\n src={fixed.src}\n srcSet={fixed.srcSet}\n width={fixed.width}\n style={{\n aspectRatio: fixed.aspectRatio,\n ...passthroughProps.style,\n }}\n {...passthroughProps}\n />\n );\n },\n);\n\ntype FluidImageExcludedProps =\n | 'data'\n | 'width'\n | 'height'\n | 'loader'\n | 'loaderOptions'\n | 'srcSetOptions';\n\ntype FluidImageProps = Omit<HydrogenImageProps, FluidImageExcludedProps> &\n Pick<HydrogenImageBaseProps, 'data'> & {\n imageWidths: number[];\n loader: Loader;\n normalizedProps: NormalizedProps;\n passthroughProps: React.ImgHTMLAttributes<HTMLImageElement>;\n placeholderWidth: number;\n ref: React.Ref<HTMLImageElement>;\n };\n\nconst FluidImage = React.forwardRef<HTMLImageElement, FluidImageProps>(\n (\n {\n crop,\n decoding,\n imageWidths,\n loader = shopifyLoader,\n loading,\n normalizedProps,\n passthroughProps,\n placeholderWidth,\n sizes,\n data,\n },\n ref,\n ) => {\n const fluid = React.useMemo(() => {\n const sizesArray =\n imageWidths === undefined\n ? undefined\n : generateSizes(imageWidths, normalizedProps.aspectRatio, crop, {\n width: data?.width ?? undefined,\n height: data?.height ?? undefined,\n });\n\n const placeholderHeight =\n normalizedProps.aspectRatio && placeholderWidth\n ? placeholderWidth *\n (parseAspectRatio(normalizedProps.aspectRatio) ?? 1)\n : undefined;\n\n const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);\n\n const src = loader({\n src: normalizedProps.src,\n width: placeholderWidth,\n height: placeholderHeight,\n crop,\n });\n\n return {\n placeholderHeight,\n srcSet,\n src,\n };\n }, [crop, data, imageWidths, loader, normalizedProps, placeholderWidth]);\n\n return (\n <img\n ref={ref}\n alt={normalizedProps.alt}\n decoding={decoding}\n height={fluid.placeholderHeight}\n loading={loading}\n sizes={sizes}\n src={fluid.src}\n srcSet={fluid.srcSet}\n width={placeholderWidth}\n {...passthroughProps}\n style={{\n width: normalizedProps.width,\n aspectRatio: normalizedProps.aspectRatio,\n ...passthroughProps.style,\n }}\n />\n );\n },\n);\n\n/**\n * The shopifyLoader function is a simple utility function that takes a src, width,\n * height, and crop and returns a string that can be used as the src for an image.\n * It can be used with the Hydrogen Image component or with the next/image component.\n * (or any others that accept equivalent configuration)\n * @param src - The source URL of the image, e.g. `https://cdn.shopify.com/static/sample-images/garnished.jpeg`\n * @param width - The width of the image, e.g. `100`\n * @param height - The height of the image, e.g. `100`\n * @param crop - The crop of the image, e.g. `center`\n * @returns A Shopify image URL with the correct query parameters, e.g. `https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=100&height=100&crop=center`\n *\n * @example\n * ```\n * shopifyLoader({\n * src: 'https://cdn.shopify.com/static/sample-images/garnished.jpeg',\n * width: 100,\n * height: 100,\n * crop: 'center',\n * })\n * ```\n */\nconst PLACEHOLDER_DOMAIN = 'https://placeholder.shopify.com';\nexport function shopifyLoader({src, width, height, crop}: LoaderParams) {\n if (!src) {\n return '';\n }\n\n const url = new URL(src, PLACEHOLDER_DOMAIN);\n\n if (width) {\n url.searchParams.append('width', Math.round(width).toString());\n }\n\n if (height) {\n url.searchParams.append('height', Math.round(height).toString());\n }\n\n if (crop) {\n url.searchParams.append('crop', crop);\n }\n return url.href.replace(PLACEHOLDER_DOMAIN, '');\n}\n\n/**\n * Checks whether the width and height share the same unit type\n * @param width - The width of the image, e.g. 100% | 10px\n * @param height - The height of the image, e.g. auto | 100px\n * @returns Whether the width and height share the same unit type (boolean)\n */\nfunction unitsMatch(\n width: string | number = '100%',\n height: string | number = 'auto',\n): boolean {\n return (\n getUnitValueParts(width.toString()).unit ===\n getUnitValueParts(height.toString()).unit\n );\n}\n\n/**\n * Given a CSS size, returns the unit and number parts of the value\n * @param value - The CSS size, e.g. 100px\n * @returns The unit and number parts of the value, e.g. \\{unit: 'px', number: 100\\}\n */\nfunction getUnitValueParts(value: string): {unit: string; number: number} {\n const unit = value.replace(/[0-9.]/g, '');\n const number = parseFloat(value.replace(unit, ''));\n\n return {\n unit: unit === '' ? (number === undefined ? 'auto' : 'px') : unit,\n number,\n };\n}\n\n/**\n * Given a value, returns the width of the image as an integer in pixels\n * @param value - The width of the image, e.g. 16px | 1rem | 1em | 16\n * @returns The width of the image in pixels, e.g. 16, or undefined if the value is not a fixed unit\n */\nfunction getNormalizedFixedUnit(value?: string | number): number | undefined {\n if (value === undefined) {\n return;\n }\n\n const {unit, number} = getUnitValueParts(value.toString());\n\n switch (unit) {\n case 'em':\n return number * 16;\n case 'rem':\n return number * 16;\n case 'px':\n return number;\n case '':\n return number;\n default:\n return;\n }\n}\n\n/**\n * This function checks whether a width is fixed or not.\n * @param width - The width of the image, e.g. 100 | '100px' | '100em' | '100rem'\n * @returns Whether the width is fixed or not\n */\nfunction isFixedWidth(width: string | number): boolean {\n const fixedEndings = /\\d(px|em|rem)$/;\n return typeof width === 'number' || fixedEndings.test(width);\n}\n\n/**\n * This function generates a srcSet for Shopify images.\n * @param src - The source URL of the image, e.g. https://cdn.shopify.com/static/sample-images/garnished.jpeg\n * @param sizesArray - An array of objects containing the `width`, `height`, and `crop` of the image, e.g. [\\{width: 200, height: 200, crop: 'center'\\}, \\{width: 400, height: 400, crop: 'center'\\}]\n * @param loader - A function that takes a Shopify image URL and returns a Shopify image URL with the correct query parameters\n * @returns A srcSet for Shopify images, e.g. 'https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=200&height=200&crop=center 200w, https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=400&height=400&crop=center 400w'\n */\nexport function generateSrcSet(\n src?: string,\n sizesArray?: Array<{width?: number; height?: number; crop?: Crop}>,\n loader: Loader = shopifyLoader,\n): string {\n if (!src) {\n return '';\n }\n\n if (sizesArray?.length === 0 || !sizesArray) {\n return src;\n }\n\n return sizesArray\n .map(\n (size, i) =>\n `${loader({\n src,\n width: size.width,\n height: size.height,\n crop: size.crop,\n })} ${sizesArray.length === 3 ? `${i + 1}x` : `${size.width ?? 0}w`}`,\n )\n .join(`, `);\n}\n\n/**\n * This function generates an array of sizes for Shopify images, for both fixed and responsive images.\n * @param width - The CSS width of the image\n * @param intervals - The number of intervals to generate\n * @param startingWidth - The starting width of the image\n * @param incrementSize - The size of each interval\n * @returns An array of widths\n */\nexport function generateImageWidths(\n width: string | number = '100%',\n intervals: number,\n startingWidth: number,\n incrementSize: number,\n): number[] {\n const responsive = Array.from(\n {length: intervals},\n (_, i) => i * incrementSize + startingWidth,\n );\n\n const fixed = Array.from(\n {length: 3},\n (_, i) => (i + 1) * (getNormalizedFixedUnit(width) ?? 0),\n );\n\n return isFixedWidth(width) ? fixed : responsive;\n}\n\n/**\n * Simple utility function to convert an aspect ratio CSS string to a decimal, currently only supports values like `1/1`, not `0.5`, or `auto`\n * @param aspectRatio - The aspect ratio of the image, e.g. `1/1`\n * @returns The aspect ratio as a number, e.g. `0.5`\n *\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio}\n */\nexport function parseAspectRatio(aspectRatio?: string): number | undefined {\n if (!aspectRatio) return;\n const [width, height] = aspectRatio.split('/');\n return 1 / (Number(width) / Number(height));\n}\n\n// Generate data needed for Imagery loader\nexport function generateSizes(\n imageWidths?: number[],\n aspectRatio?: string,\n crop: Crop = 'center',\n sourceDimensions?: {width?: number; height?: number},\n):\n | {\n width: number;\n height: number | undefined;\n crop: Crop;\n }[]\n | undefined {\n if (!imageWidths) return;\n return imageWidths\n .map((width: number) => {\n return {\n width,\n height: aspectRatio\n ? width * (parseAspectRatio(aspectRatio) ?? 1)\n : undefined,\n crop,\n };\n })\n .filter(({width, height}) => {\n if (sourceDimensions?.width && width > sourceDimensions.width) {\n return false;\n }\n\n if (\n sourceDimensions?.height &&\n height &&\n height > sourceDimensions.height\n ) {\n return false;\n }\n\n return true;\n });\n /*\n Given:\n ([100, 200], 1/1, 'center')\n Returns:\n [{width: 100, height: 100, crop: 'center'},\n {width: 200, height: 200, crop: 'center'}]\n */\n}\n","import {useState, useEffect} from 'react';\n\nconst SCRIPTS_LOADED: Record<string, Promise<boolean>> = {};\n\ntype LoadScriptOptions = {\n module?: boolean;\n in?: 'head' | 'body';\n attributes?: Record<string, string>;\n};\n\nexport function loadScript(\n src: string,\n options?: LoadScriptOptions,\n): Promise<boolean> {\n const isScriptLoaded = SCRIPTS_LOADED[src];\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n if (isScriptLoaded) {\n return isScriptLoaded;\n }\n\n const promise = new Promise<boolean>((resolve, reject) => {\n const script = document.createElement('script');\n if (options?.module) {\n script.type = 'module';\n } else {\n script.type = 'text/javascript';\n }\n script.src = src;\n script.onload = (): void => {\n resolve(true);\n };\n script.onerror = (): void => {\n reject(false);\n };\n if (options?.in === 'head') {\n document.head.appendChild(script);\n } else {\n document.body.appendChild(script);\n }\n\n const attributes = options?.attributes;\n if (attributes) {\n Object.keys(attributes).forEach((key) => {\n script.setAttribute(key, attributes[key]);\n });\n }\n });\n\n SCRIPTS_LOADED[src] = promise;\n\n return promise;\n}\n\ntype LoadScriptParams = Parameters<typeof loadScript>;\n\n/**\n * The `useLoadScript` hook loads an external script tag in the browser. It allows React components to lazy-load large third-party dependencies.\n */\nexport function useLoadScript(\n url: LoadScriptParams[0],\n options?: LoadScriptParams[1],\n): ScriptState {\n const [status, setStatus] = useState<ScriptState>('loading');\n\n useEffect(\n () => {\n loadScript(url, options)\n .then(() => setStatus('done'))\n .catch(() => setStatus('error'));\n },\n // Ignore options changes since it won't trigger a new load.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [url],\n );\n\n return status;\n}\n\ntype ScriptState = 'loading' | 'done' | 'error';\n","import {forwardRef, type HTMLAttributes} from 'react';\nimport {shopifyLoader} from './Image.js';\nimport type {Video as VideoType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nexport interface VideoProps {\n /** An object with fields that correspond to the Storefront API's [Video object](https://shopify.dev/api/storefront/2024-10/objects/video). */\n data: PartialDeep<VideoType, {recurseIntoArrays: true}>;\n /** An object of image size options for the video's `previewImage`. Uses `shopifyImageLoader` to generate the `poster` URL. */\n previewImageOptions?: Parameters<typeof shopifyLoader>[0];\n /** Props that will be passed to the `video` element's `source` children elements. */\n sourceProps?: HTMLAttributes<HTMLSourceElement> & {\n 'data-testid'?: string;\n };\n}\n\n/**\n * The `Video` component renders a `video` for the Storefront API's [Video object](https://shopify.dev/api/storefront/reference/products/video).\n */\nexport const Video = forwardRef<\n HTMLVideoElement,\n JSX.IntrinsicElements['video'] & VideoProps\n>((props, ref): JSX.Element => {\n const {\n data,\n previewImageOptions,\n id = data.id,\n playsInline = true,\n controls = true,\n sourceProps = {},\n ...passthroughProps\n } = props;\n\n const posterUrl = shopifyLoader({\n src: data.previewImage?.url ?? '',\n ...previewImageOptions,\n });\n\n if (!data.sources) {\n throw new Error(`<Video/> requires a 'data.sources' array`);\n }\n\n return (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n {...passthroughProps}\n id={id}\n playsInline={playsInline}\n controls={controls}\n poster={posterUrl}\n ref={ref}\n >\n {data.sources.map((source) => {\n if (!(source?.url && source?.mimeType)) {\n throw new Error(`<Video/> needs 'source.url' and 'source.mimeType'`);\n }\n return (\n <source\n {...sourceProps}\n key={source.url}\n src={source.url}\n type={source.mimeType}\n />\n );\n })}\n </video>\n );\n});\n","import {useState, useEffect, useCallback} from 'react';\nimport {useLoadScript} from './load-script.js';\nimport type {Model3d} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n interface IntrinsicElements {\n 'model-viewer': PartialDeep<\n ModelViewerElement,\n {recurseIntoArrays: true}\n >;\n }\n }\n}\n\ntype ModelViewerProps = Omit<\n PartialDeep<JSX.IntrinsicElements['model-viewer'], {recurseIntoArrays: true}>,\n 'src'\n> &\n ModelViewerBaseProps;\n\ntype ModelViewerBaseProps = {\n /** An object with fields that correspond to the Storefront API's [Model3D object](https://shopify.dev/api/storefront/2024-10/objects/model3d). */\n data: PartialDeep<Model3d, {recurseIntoArrays: true}>;\n /** The callback to invoke when the 'error' event is triggered. Refer to [error in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-error). */\n onError?: (event: Event) => void;\n /** The callback to invoke when the `load` event is triggered. Refer to [load in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-load). */\n onLoad?: (event: Event) => void;\n /** The callback to invoke when the 'preload' event is triggered. Refer to [preload in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-preload). */\n onPreload?: (event: Event) => void;\n /** The callback to invoke when the 'model-visibility' event is triggered. Refer to [model-visibility in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-modelVisibility). */\n onModelVisibility?: (event: Event) => void;\n /** The callback to invoke when the 'progress' event is triggered. Refer to [progress in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-progress). */\n onProgress?: (event: Event) => void;\n /** The callback to invoke when the 'ar-status' event is triggered. Refer to [ar-status in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-arStatus). */\n onArStatus?: (event: Event) => void;\n /** The callback to invoke when the 'ar-tracking' event is triggered. Refer to [ar-tracking in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-arTracking). */\n onArTracking?: (event: Event) => void;\n /** The callback to invoke when the 'quick-look-button-tapped' event is triggered. Refer to [quick-look-button-tapped in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-quickLookButtonTapped). */\n onQuickLookButtonTapped?: (event: Event) => void;\n /** The callback to invoke when the 'camera-change' event is triggered. Refer to [camera-change in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-stagingandcameras-events-cameraChange). */\n onCameraChange?: (event: Event) => void;\n /** The callback to invoke when the 'environment-change' event is triggered. Refer to [environment-change in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-lightingandenv-events-environmentChange). */\n onEnvironmentChange?: (event: Event) => void;\n /** The callback to invoke when the 'play' event is triggered. Refer to [play in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-animation-events-play). */\n onPlay?: (event: Event) => void;\n /** The callback to invoke when the 'pause' event is triggered. Refer to [pause in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-animation-events-pause). */\n onPause?: (event: Event) => void;\n /** The callback to invoke when the 'scene-graph-ready' event is triggered. Refer to [scene-graph-ready in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-scenegraph-events-sceneGraphReady). */\n onSceneGraphReady?: (event: Event) => void;\n};\n\n/**\n * The `ModelViewer` component renders a 3D model (with the `model-viewer` custom element) for\n * the Storefront API's [Model3d object](https://shopify.dev/api/storefront/reference/products/model3d).\n *\n * The `model-viewer` custom element is lazily downloaded through a dynamically-injected `<script type=\"module\">` tag when the `<ModelViewer />` component is rendered\n *\n * ModelViewer is using version `1.21.1` of the `@google/model-viewer` library.\n */\nexport function ModelViewer(props: ModelViewerProps): JSX.Element | null {\n const [modelViewer, setModelViewer] = useState<undefined | HTMLElement>(\n undefined,\n );\n const callbackRef = useCallback((node: HTMLElement) => {\n setModelViewer(node);\n }, []);\n const {data, children, className, ...passthroughProps} = props;\n\n const modelViewerLoadedStatus = useLoadScript(\n 'https://unpkg.com/@google/model-viewer@v1.12.1/dist/model-viewer.min.js',\n {\n module: true,\n },\n );\n\n useEffect(() => {\n const hydrogenEventListener = {\n error: passthroughProps.onError,\n load: passthroughProps.onLoad,\n preload: passthroughProps.onPreload,\n 'model-visibility': passthroughProps.onModelVisibility,\n progress: passthroughProps.onProgress,\n 'ar-status': passthroughProps.onArStatus,\n 'ar-tracking': passthroughProps.onArTracking,\n 'quick-look-button-tapped': passthroughProps.onQuickLookButtonTapped,\n 'camera-change': passthroughProps.onCameraChange,\n 'environment-change': passthroughProps.onEnvironmentChange,\n play: passthroughProps.onPlay,\n pause: passthroughProps.onPause,\n 'scene-graph-ready': passthroughProps.onSceneGraphReady,\n };\n\n if (!modelViewer) {\n return;\n }\n Object.entries(hydrogenEventListener).forEach(\n ([eventName, callbackFunc]) => {\n if (callbackFunc) {\n modelViewer.addEventListener(eventName, callbackFunc);\n }\n },\n );\n\n return () => {\n if (modelViewer == null) {\n return;\n }\n Object.entries(hydrogenEventListener).forEach(\n ([eventName, callbackFunc]) => {\n if (callbackFunc) {\n modelViewer.removeEventListener(eventName, callbackFunc);\n }\n },\n );\n };\n }, [\n modelViewer,\n passthroughProps.onArStatus,\n passthroughProps.onArTracking,\n passthroughProps.onCameraChange,\n passthroughProps.onEnvironmentChange,\n passthroughProps.onError,\n passthroughProps.onLoad,\n passthroughProps.onModelVisibility,\n passthroughProps.onPause,\n passthroughProps.onPlay,\n passthroughProps.onPreload,\n passthroughProps.onProgress,\n passthroughProps.onQuickLookButtonTapped,\n passthroughProps.onSceneGraphReady,\n ]);\n\n if (modelViewerLoadedStatus !== 'done') {\n // TODO: What do we want to display while the model-viewer library loads?\n return null;\n }\n\n if (!data.sources?.[0]?.url) {\n const sourcesUrlError = `<ModelViewer/> requires 'data.sources' prop to be an array, with an object that has a property 'url' on it. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(sourcesUrlError);\n } else {\n console.error(sourcesUrlError);\n return null;\n }\n }\n\n if (__HYDROGEN_DEV__ && !data.alt) {\n console.warn(\n `<ModelViewer/> requires the 'data.alt' prop for accessibility`,\n );\n }\n\n return (\n <model-viewer\n ref={callbackRef}\n {...passthroughProps}\n // @ts-expect-error src should exist\n // @eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n class={className}\n id={passthroughProps.id ?? data.id}\n src={data.sources[0].url}\n alt={data.alt ?? null}\n camera-controls={passthroughProps.cameraControls ?? true}\n poster={(passthroughProps.poster || data.previewImage?.url) ?? null}\n autoplay={passthroughProps.autoplay ?? true}\n loading={passthroughProps.loading}\n reveal={passthroughProps.reveal}\n ar={passthroughProps.ar}\n ar-modes={passthroughProps.arModes}\n ar-scale={passthroughProps.arScale}\n // @ts-expect-error arPlacement should exist as a type, not sure why it doesn't. https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-attributes-arPlacement\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ar-placement={passthroughProps.arPlacement}\n ios-src={passthroughProps.iosSrc}\n touch-action={passthroughProps.touchAction}\n disable-zoom={passthroughProps.disableZoom}\n orbit-sensitivity={passthroughProps.orbitSensitivity}\n auto-rotate={passthroughProps.autoRotate}\n auto-rotate-delay={passthroughProps.autoRotateDelay}\n // @ts-expect-error rotationPerSecond should exist as a type, not sure why it doesn't. https://modelviewer.dev/docs/index.html#entrydocs-stagingandcameras-attributes-rotationPerSecond\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n rotation-per-second={passthroughProps.rotationPerSecond}\n interaction-policy={passthroughProps.interactionPolicy}\n interaction-prompt={passthroughProps.interactionPrompt}\n interaction-prompt-style={passthroughProps.interactionPromptStyle}\n interaction-prompt-threshold={passthroughProps.interactionPromptThreshold}\n camera-orbit={passthroughProps.cameraOrbit}\n camera-target={passthroughProps.cameraTarget}\n field-of-view={passthroughProps.fieldOfView}\n max-camera-orbit={passthroughProps.maxCameraOrbit}\n min-camera-orbit={passthroughProps.minCameraOrbit}\n max-field-of-view={passthroughProps.maxFieldOfView}\n min-field-of-view={passthroughProps.minFieldOfView}\n bounds={passthroughProps.bounds}\n interpolation-decay={passthroughProps.interpolationDecay ?? 100}\n skybox-image={passthroughProps.skyboxImage}\n environment-image={passthroughProps.environmentImage}\n exposure={passthroughProps.exposure}\n shadow-intensity={passthroughProps.shadowIntensity ?? 0}\n shadow-softness={passthroughProps.shadowSoftness ?? 0}\n animation-name={passthroughProps.animationName}\n animation-crossfade-duration={passthroughProps.animationCrossfadeDuration}\n variant-name={passthroughProps.variantName}\n orientation={passthroughProps.orientation}\n scale={passthroughProps.scale}\n >\n {children}\n </model-viewer>\n );\n}\n","import {Image, type HydrogenImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ntype BaseProps = React.HTMLAttributes<\n HTMLImageElement | HTMLVideoElement | HTMLIFrameElement | ModelViewerElement\n>;\nexport interface MediaFileProps extends BaseProps {\n /** An object with fields that correspond to the Storefront API's [Media object](https://shopify.dev/api/storefront/reference/products/media). */\n data: PartialDeep<MediaEdgeType['node'], {recurseIntoArrays: true}>;\n /** The options for the `Image`, `Video`, `ExternalVideo`, or `ModelViewer` components. */\n mediaOptions?: MediaOptions;\n}\n\ntype MediaOptions = {\n /** Props that will only apply when an `<Image />` is rendered */\n image?: Omit<HydrogenImageProps, 'data'>;\n /** Props that will only apply when a `<Video />` is rendered */\n video?: Omit<React.ComponentProps<typeof Video>, 'data'>;\n /** Props that will only apply when an `<ExternalVideo />` is rendered */\n externalVideo?: Omit<\n React.ComponentProps<typeof ExternalVideo>['options'],\n 'data'\n >;\n /** Props that will only apply when a `<ModelViewer />` is rendered */\n modelViewer?: Omit<typeof ModelViewer, 'data'>;\n};\n\n/**\n * The `MediaFile` component renders the media for the Storefront API's\n * [Media object](https://shopify.dev/api/storefront/reference/products/media). It renders an `Image`, a\n * `Video`, an `ExternalVideo`, or a `ModelViewer` depending on the `__typename` of the `data` prop.\n */\nexport function MediaFile({\n data,\n mediaOptions,\n ...passthroughProps\n}: MediaFileProps): JSX.Element | null {\n switch (data.__typename) {\n case 'MediaImage': {\n if (!data.image) {\n const noDataImage = `<MediaFile/>: 'data.image' does not exist for __typename of 'MediaImage'; rendering 'null' by default.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataImage);\n } else {\n console.warn(noDataImage);\n return null;\n }\n }\n\n return (\n <Image\n {...passthroughProps}\n {...mediaOptions?.image}\n data={data.image}\n />\n );\n }\n case 'Video': {\n return (\n <Video {...passthroughProps} {...mediaOptions?.video} data={data} />\n );\n }\n case 'ExternalVideo': {\n return (\n <ExternalVideo\n {...passthroughProps}\n {...mediaOptions?.externalVideo}\n data={data}\n />\n );\n }\n case 'Model3d': {\n return (\n // @ts-expect-error There are issues with the inferred HTML attribute types here for ModelViewer (and contentEditable), but I think that's a little bit beyond me at the moment\n <ModelViewer\n {...passthroughProps}\n {...mediaOptions?.modelViewer}\n data={data}\n />\n );\n }\n default: {\n const typenameMissingMessage = `<MediaFile /> requires the '__typename' property to exist on the 'data' prop in order to render the matching sub-component for this type of media.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typenameMissingMessage);\n } else {\n console.error(`${typenameMissingMessage} Rendering 'null' by default`);\n return null;\n }\n }\n }\n}\n","import type {\n Collection,\n GenericFile,\n Metafield as MetafieldBaseType,\n MoneyV2,\n Page,\n Product,\n ProductVariant,\n} from './storefront-api-types.js';\nimport type {PartialDeep, Simplify} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\nimport {RootASTNode as RichTextRootASTNode} from './RichText.types.js';\n\n/**\n * A function that uses `metafield.type` to parse the Metafield's `value` or `reference` or `references` (depending on the `metafield.type`) and places the result in `metafield.parsedValue`\n *\n * TypeScript developers can use the type `ParsedMetafields` from this package to get the returned object's type correct. For example:\n *\n * ```\n * parseMetafield<ParsedMetafields['boolean']>({type: 'boolean', value: 'false'}\n * ```\n */\nexport function parseMetafield<ReturnGeneric>(\n metafield: PartialDeep<MetafieldBaseType, {recurseIntoArrays: true}>,\n): ReturnGeneric {\n if (!metafield.type) {\n const noTypeError = `parseMetafield(): The 'type' field is required in order to parse the Metafield.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noTypeError);\n } else {\n console.error(`${noTypeError} Returning 'parsedValue' of 'null'`);\n return {\n ...metafield,\n parsedValue: null,\n } as ReturnGeneric;\n }\n }\n\n switch (metafield.type) {\n case 'boolean':\n return {\n ...metafield,\n parsedValue: metafield.value === 'true',\n } as ReturnGeneric;\n\n case 'collection_reference':\n case 'file_reference':\n case 'page_reference':\n case 'product_reference':\n case 'variant_reference':\n return {\n ...metafield,\n parsedValue: metafield.reference,\n } as ReturnGeneric;\n\n case 'color':\n case 'multi_line_text_field':\n case 'single_line_text_field':\n case 'url':\n return {\n ...metafield,\n parsedValue: metafield.value,\n } as ReturnGeneric;\n\n // TODO: 'money' should probably be parsed even further to like `useMoney()`, but that logic needs to be extracted first so it's not a hook\n case 'dimension':\n case 'money':\n case 'json':\n case 'rating':\n case 'volume':\n case 'weight':\n case 'rich_text_field':\n case 'list.color':\n case 'list.dimension':\n case 'list.number_integer':\n case 'list.number_decimal':\n case 'list.rating':\n case 'list.single_line_text_field':\n case 'list.url':\n case 'list.volume':\n case 'list.weight': {\n let parsedValue = null;\n try {\n parsedValue = parseJSON(metafield.value ?? '');\n } catch (err) {\n const parseError = `parseMetafield(): attempted to JSON.parse the 'metafield.value' property, but failed.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(parseError);\n } else {\n console.error(`${parseError} Returning 'null' for 'parsedValue'`);\n }\n parsedValue = null;\n }\n return {\n ...metafield,\n parsedValue,\n } as ReturnGeneric;\n }\n\n case 'date':\n case 'date_time':\n return {\n ...metafield,\n parsedValue: new Date(metafield.value ?? ''),\n } as ReturnGeneric;\n\n case 'list.date':\n case 'list.date_time': {\n const jsonParseValue = parseJSON(metafield?.value ?? '') as string[];\n return {\n ...metafield,\n parsedValue: jsonParseValue.map((dateString) => new Date(dateString)),\n } as ReturnGeneric;\n }\n\n case 'number_decimal':\n case 'number_integer':\n return {\n ...metafield,\n parsedValue: Number(metafield.value),\n } as ReturnGeneric;\n\n case 'list.collection_reference':\n case 'list.file_reference':\n case 'list.page_reference':\n case 'list.product_reference':\n case 'list.variant_reference':\n return {\n ...metafield,\n parsedValue: flattenConnection(metafield.references ?? undefined),\n } as ReturnGeneric;\n\n default: {\n const typeNotFoundError = `parseMetafield(): the 'metafield.type' you passed in is not supported. Your type: \"${metafield.type}\". If you believe this is an error, please open an issue on GitHub.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typeNotFoundError);\n } else {\n console.error(\n `${typeNotFoundError} Returning 'parsedValue' of 'null'`,\n );\n return {\n ...metafield,\n parsedValue: null,\n } as ReturnGeneric;\n }\n }\n }\n}\n\n/**\n * Parses a JSON string while preventing prototype injection attacks.\n */\nexport function parseJSON(json: string): unknown {\n if (String(json).includes('__proto__')) {\n return JSON.parse(json, (k, v) => {\n if (k !== '__proto__') return v as unknown;\n }) as unknown;\n }\n return JSON.parse(json) as unknown;\n}\n\n// taken from https://shopify.dev/apps/metafields/types\nexport const allMetafieldTypesArray = [\n 'boolean',\n 'collection_reference',\n 'color',\n 'date',\n 'date_time',\n 'dimension',\n 'file_reference',\n 'json',\n 'money',\n 'rich_text_field',\n 'multi_line_text_field',\n 'number_decimal',\n 'number_integer',\n 'page_reference',\n 'product_reference',\n 'rating',\n 'single_line_text_field',\n 'url',\n 'variant_reference',\n 'volume',\n 'weight',\n // list metafields\n 'list.collection_reference',\n 'list.color',\n 'list.date',\n 'list.date_time',\n 'list.dimension',\n 'list.file_reference',\n 'list.number_integer',\n 'list.number_decimal',\n 'list.page_reference',\n 'list.product_reference',\n 'list.rating',\n 'list.single_line_text_field',\n 'list.url',\n 'list.variant_reference',\n 'list.volume',\n 'list.weight',\n] as const;\n\n/** A union of all the supported `metafield.type`s */\nexport type MetafieldTypeTypes = (typeof allMetafieldTypesArray)[number];\n\n/**\n * A mapping of a Metafield's `type` to the TypeScript type that is returned from `parseMetafield()`\n * For example, when using `parseMetafield()`, the type will be correctly returned when used like the following:\n *\n * ```\n * const parsedMetafield = parseMetafield<ParsedMetafields['boolean']>(metafield);`\n * ```\n * `parsedMetafield.parsedValue`'s type is now `boolean`\n */\nexport type ParsedMetafields<ExtraTypeGeneric = void> = {\n /** A Metafield that's been parsed, with a `parsedValue` of `boolean` */\n boolean: Simplify<BooleanParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Collection` object (as defined by the Storefront API) */\n collection_reference: Simplify<CollectionParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n color: Simplify<ColorParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Date` */\n date: Simplify<DatesParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Date` */\n date_time: Simplify<DatesParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n dimension: Simplify<MeasurementParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `GenericFile` object (as defined by the Storefront API) */\n file_reference: Simplify<FileRefParsedMetafield>;\n /**\n * A Metafield that's been parsed, with a `parsedValue` of type `unknown`, unless you pass in the type as a generic. For example:\n *\n * ```\n * ParsedMetafields<MyJsonType>['json']\n * ```\n */\n json: Simplify<JsonParsedMetafield<ExtraTypeGeneric>>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Money` */\n money: Simplify<MoneyParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n multi_line_text_field: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `number` */\n number_decimal: Simplify<NumberParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `number` */\n number_integer: Simplify<NumberParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Page` object (as defined by the Storefront API) */\n page_reference: Simplify<PageParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Product` object (as defined by the Storefront API) */\n product_reference: Simplify<ProductParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Rating` */\n rating: Simplify<RatingParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Rating` */\n rich_text_field: Simplify<RichTextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n single_line_text_field: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n url: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `ProductVariant` object (as defined by the Storefront API) */\n variant_reference: Simplify<VariantParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n volume: Simplify<MeasurementParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n weight: Simplify<MeasurementParsedMetafield>;\n // list metafields\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Collection` objects (as defined by the Storefront API) */\n 'list.collection_reference': Simplify<CollectionListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.color': Simplify<ColorListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of Date objects */\n 'list.date': Simplify<DatesListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of Date objects */\n 'list.date_time': Simplify<DatesListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement` objects */\n 'list.dimension': Simplify<MeasurementListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `GenericFile` objects (as defined by the Storefront API) */\n 'list.file_reference': Simplify<FileListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of numbers */\n 'list.number_integer': Simplify<NumberListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of numbers */\n 'list.number_decimal': Simplify<NumberListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Page` objects (as defined by the Storefront API) */\n 'list.page_reference': Simplify<PageListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Product` objects (as defined by the Storefront API) */\n 'list.product_reference': Simplify<ProductListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Rating`s */\n 'list.rating': Simplify<RatingListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.single_line_text_field': Simplify<TextListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.url': Simplify<TextListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `ProductVariant` objects (as defined by the Storefront API) */\n 'list.variant_reference': Simplify<VariantListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement`s */\n 'list.volume': Simplify<MeasurementListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement`s */\n 'list.weight': Simplify<MeasurementListParsedMetafield>;\n};\n\ninterface ParsedBase extends MetafieldBaseType {\n type: MetafieldTypeTypes;\n parsedValue: unknown;\n}\n\ninterface BooleanParsedMetafield extends ParsedBase {\n type: 'boolean';\n parsedValue: boolean | null;\n}\ntype CollectionParsedRefMetafield = MetafieldBaseType & {\n type: 'collection_reference';\n parsedValue: Collection | null;\n};\ntype ColorParsedMetafield = MetafieldBaseType & {\n type: 'color';\n parsedValue: string | null;\n};\ntype DatesParsedMetafield = MetafieldBaseType & {\n type: 'date' | 'date_time';\n parsedValue: Date | null;\n};\n\ntype MeasurementParsedMetafield = MetafieldBaseType & {\n type: 'dimension' | 'weight' | 'volume';\n parsedValue: Measurement | null;\n};\n\ntype FileRefParsedMetafield = MetafieldBaseType & {\n type: 'file_reference';\n parsedValue: GenericFile | null;\n};\n\ntype JsonParsedMetafield<JsonTypeGeneric = void> = MetafieldBaseType & {\n type: 'json';\n parsedValue: JsonTypeGeneric extends void ? unknown : JsonTypeGeneric | null;\n};\n\ntype MoneyParsedMetafield = MetafieldBaseType & {\n type: 'money';\n parsedValue: MoneyV2 | null;\n};\n\ntype TextParsedMetafield = MetafieldBaseType & {\n type: 'single_line_text_field' | 'multi_line_text_field' | 'url';\n parsedValue: string | null;\n};\n\ntype NumberParsedMetafield = MetafieldBaseType & {\n type: 'number_decimal' | 'number_integer';\n parsedValue: number | null;\n};\n\ntype PageParsedRefMetafield = MetafieldBaseType & {\n type: 'page_reference';\n parsedValue: Page | null;\n};\n\ntype ProductParsedRefMetafield = MetafieldBaseType & {\n type: 'product_reference';\n parsedValue: Product | null;\n};\n\ntype RatingParsedMetafield = MetafieldBaseType & {\n type: 'rating';\n parsedValue: Rating | null;\n};\n\ntype RichTextParsedMetafield = MetafieldBaseType & {\n type: 'rich_text_field';\n parsedValue: RichTextRootASTNode | null;\n};\n\ntype VariantParsedRefMetafield = MetafieldBaseType & {\n type: 'variant_reference';\n parsedValue: ProductVariant | null;\n};\n\ntype CollectionListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.collection_reference';\n parsedValue: Array<Collection> | null;\n};\n\ntype ColorListParsedMetafield = MetafieldBaseType & {\n type: 'list.color';\n parsedValue: Array<string> | null;\n};\n\ntype DatesListParsedMetafield = MetafieldBaseType & {\n type: 'list.date' | 'list.date_time';\n parsedValue: Array<Date> | null;\n};\n\ntype MeasurementListParsedMetafield = MetafieldBaseType & {\n type: 'list.dimension' | 'list.weight' | 'list.volume';\n parsedValue: Array<Measurement> | null;\n};\n\ntype FileListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.file_reference';\n parsedValue: Array<GenericFile> | null;\n};\n\ntype TextListParsedMetafield = MetafieldBaseType & {\n type: 'list.single_line_text_field' | 'list.url';\n parsedValue: Array<string> | null;\n};\n\ntype NumberListParsedMetafield = MetafieldBaseType & {\n type: 'list.number_decimal' | 'list.number_integer';\n parsedValue: Array<number> | null;\n};\n\ntype PageListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.page_reference';\n parsedValue: Array<Page> | null;\n};\n\ntype ProductListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.product_reference';\n parsedValue: Array<Product> | null;\n};\n\ntype RatingListParsedMetafield = MetafieldBaseType & {\n type: 'list.rating';\n parsedValue: Array<Rating> | null;\n};\n\ntype VariantListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.variant_reference';\n parsedValue: Array<ProductVariant> | null;\n};\n\nexport type Measurement = {\n unit: string;\n value: number;\n};\n\nexport interface Rating {\n value: number;\n scale_min: number;\n scale_max: number;\n}\n","import type {\n MoneyV2,\n UnitPriceMeasurement,\n Product,\n} from './storefront-api-types.js';\nimport {Money, type MoneyProps, type MoneyPropsBase} from './Money.js';\nimport type {PartialDeep} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\n\nexport interface ProductPriceProps {\n /** A Storefront API [Product object](https://shopify.dev/api/storefront/reference/products/product). */\n data: PartialDeep<Product, {recurseIntoArrays: true}>;\n /** The type of price. Valid values: `regular` (default) or `compareAt`. */\n priceType?: 'regular' | 'compareAt';\n /** The type of value. Valid values: `min` (default), `max` or `unit`. */\n valueType?: 'max' | 'min' | 'unit';\n /** The ID of the variant. */\n variantId?: string;\n}\n\n/**\n * The `ProductPrice` component renders a `Money` component with the product\n * [`priceRange`](https://shopify.dev/api/storefront/reference/products/productpricerange)'s `maxVariantPrice` or `minVariantPrice`, for either the regular price or compare at price range.\n */\nexport function ProductPrice<\n ComponentGeneric extends React.ElementType = 'div',\n>(\n props: ProductPriceProps &\n Omit<MoneyProps<ComponentGeneric>, 'data' | 'measurement'>,\n): JSX.Element | null {\n const {\n priceType = 'regular',\n variantId,\n valueType = 'min',\n data: product,\n ...passthroughProps\n } = props;\n\n if (product == null) {\n throw new Error(`<ProductPrice/> requires a product as the 'data' prop`);\n }\n\n let price: Partial<MoneyV2> | undefined | null;\n let measurement: Partial<UnitPriceMeasurement> | undefined | null;\n\n const variant = variantId\n ? flattenConnection(product?.variants ?? {}).find(\n (variant) => variant?.id === variantId,\n ) ?? null\n : null;\n\n const variantPriceProperty =\n valueType === 'max' ? 'maxVariantPrice' : 'minVariantPrice';\n\n if (priceType === 'compareAt') {\n if (variantId && variant) {\n price = variant.compareAtPrice;\n } else {\n price = product?.compareAtPriceRange?.[variantPriceProperty];\n }\n\n let priceAsNumber: number;\n if (variantId && variant) {\n priceAsNumber = parseFloat(variant.price?.amount ?? '0');\n } else {\n priceAsNumber = parseFloat(\n product?.priceRange?.[variantPriceProperty]?.amount ?? '0',\n );\n }\n\n const compareAtPriceAsNumber = parseFloat(price?.amount ?? '0');\n\n if (priceAsNumber >= compareAtPriceAsNumber) {\n return null;\n }\n } else {\n if (variantId && variant) {\n price = variant.price;\n if (valueType === 'unit') {\n price = variant.unitPrice;\n measurement = variant.unitPriceMeasurement;\n }\n } else if (valueType === 'max') {\n price = product.priceRange?.maxVariantPrice;\n } else {\n price = product.priceRange?.minVariantPrice;\n }\n }\n\n if (!price) {\n return null;\n }\n\n if (measurement) {\n return (\n <Money {...passthroughProps} data={price} measurement={measurement} />\n );\n }\n\n return <Money {...passthroughProps} data={price} />;\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface ProductPricePropsForDocs<\n AsType extends React.ElementType = 'div',\n> extends Omit<MoneyPropsBase<AsType>, 'data' | 'measurement'>,\n ProductPriceProps {}\n","import {createElement, type ReactNode} from 'react';\n\nexport type CustomComponents = {\n /** The root node of the rich text. Defaults to `<div>` */\n root?: typeof Root;\n /** Customize the headings. Each heading has a `level` property from 1-6. Defaults to `<h1>` to `<h6>` */\n heading?: typeof Heading;\n /** Customize paragraphs. Defaults to `<p>` */\n paragraph?: typeof Paragraph;\n /** Customize how text nodes. They can either be bold or italic. Defaults to `<em>`, `<strong>` or text. */\n text?: typeof Text;\n /** Customize links. Defaults to a React Router `<Link>` component in Hydrogen and a `<a>` in Hydrogen React. */\n link?: typeof RichTextLink;\n /** Customize lists. They can be either ordered or unordered. Defaults to `<ol>` or `<ul>` */\n list?: typeof List;\n /** Customize list items. Defaults to `<li>`. */\n listItem?: typeof ListItem;\n};\n\nexport const RichTextComponents = {\n root: Root,\n heading: Heading,\n paragraph: Paragraph,\n text: Text,\n link: RichTextLink,\n list: List,\n 'list-item': ListItem,\n};\n\nfunction Root({\n node,\n}: {\n node: {\n type: 'root';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <div>{node.children}</div>;\n}\n\nfunction Heading({\n node,\n}: {\n node: {\n type: 'heading';\n level: number;\n children?: ReactNode[];\n };\n}): ReactNode {\n return createElement(`h${node.level ?? '1'}`, null, node.children);\n}\n\nfunction Paragraph({\n node,\n}: {\n node: {\n type: 'paragraph';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <p>{node.children}</p>;\n}\n\nfunction Text({\n node,\n}: {\n node: {\n type: 'text';\n italic?: boolean;\n bold?: boolean;\n value?: string;\n };\n}): ReactNode {\n if (node.bold && node.italic)\n return (\n <em>\n <strong>{node.value}</strong>\n </em>\n );\n\n if (node.bold) return <strong>{node.value}</strong>;\n if (node.italic) return <em>{node.value}</em>;\n\n return node.value;\n}\n\nfunction RichTextLink({\n node,\n}: {\n node: {\n type: 'link';\n url: string;\n title?: string;\n target?: string;\n children?: ReactNode[];\n };\n}): ReactNode {\n return (\n <a href={node.url} title={node.title} target={node.target}>\n {node.children}\n </a>\n );\n}\n\nfunction List({\n node,\n}: {\n node: {\n type: 'list';\n listType: 'unordered' | 'ordered';\n children?: ReactNode[];\n };\n}): ReactNode {\n const List = node.listType === 'unordered' ? 'ul' : 'ol';\n return <List>{node.children}</List>;\n}\n\nfunction ListItem({\n node,\n}: {\n node: {\n type: 'list-item';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <li>{node.children}</li>;\n}\n","import {createElement, Fragment, type ReactNode, useMemo} from 'react';\nimport type {RichTextASTNode} from './RichText.types.js';\nimport {\n type CustomComponents,\n RichTextComponents,\n} from './RichText.components.js';\n\nexport interface RichTextPropsBase<ComponentGeneric extends React.ElementType> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `div`. */\n as?: ComponentGeneric;\n /** The JSON string that correspond to the Storefront API's [RichText format](https://shopify.dev/docs/apps/custom-data/metafields/types#rich-text-formatting). */\n data: string;\n /** Customize how rich text components are rendered */\n components?: CustomComponents;\n /** Remove rich text formatting and render plain text */\n plain?: boolean;\n}\n\nexport function RichText<ComponentGeneric extends React.ElementType = 'div'>({\n as,\n data,\n plain,\n components,\n ...passthroughProps\n}: RichTextProps<ComponentGeneric>): JSX.Element {\n try {\n const Wrapper = as ?? 'div';\n const parsedData = useMemo(\n () => JSON.parse(data) as RichTextASTNode,\n [data],\n );\n\n return (\n <Wrapper {...passthroughProps}>\n {plain\n ? richTextToString(parsedData)\n : serializeRichTextASTNode(components, parsedData)}\n </Wrapper>\n );\n } catch (e) {\n throw new Error(\n '[h2:error:RichText] Parsing error. Make sure to pass a JSON string of rich text metafield',\n {\n cause: e,\n },\n );\n }\n}\n\n// This article helps understand the typing here https://www.benmvp.com/blog/polymorphic-react-components-typescript/ Ben is the best :)\nexport type RichTextProps<ComponentGeneric extends React.ElementType> =\n RichTextPropsBase<ComponentGeneric> &\n Omit<\n React.ComponentPropsWithoutRef<ComponentGeneric>,\n keyof RichTextPropsBase<ComponentGeneric>\n >;\n\nfunction serializeRichTextASTNode(\n components: CustomComponents = {},\n node: RichTextASTNode,\n index = 0,\n): ReactNode {\n let children;\n if ('children' in node) {\n children = node.children.map((child, childIndex) =>\n serializeRichTextASTNode(components, child, childIndex),\n );\n }\n\n const Component =\n components[node.type === 'list-item' ? 'listItem' : node.type] ??\n RichTextComponents[node.type];\n\n switch (node.type) {\n case 'root':\n return createElement(\n Component as Exclude<CustomComponents['root'], undefined>,\n {\n key: index,\n node: {\n type: 'root',\n children,\n },\n },\n );\n case 'heading':\n return createElement(\n Component as Exclude<CustomComponents['heading'], undefined>,\n {\n key: index,\n node: {\n type: 'heading',\n level: node.level,\n children,\n },\n },\n );\n case 'paragraph':\n return createElement(\n Component as Exclude<CustomComponents['paragraph'], undefined>,\n {\n key: index,\n node: {\n type: 'paragraph',\n children,\n },\n },\n );\n case 'text': {\n const elements = (node.value ?? '')\n .split('\\n')\n .flatMap((value, subindex) => {\n const key = `${index}-${value}-${subindex}`;\n const textElement = createElement(\n Component as Exclude<CustomComponents['text'], undefined>,\n {\n key,\n node: {\n type: 'text',\n italic: node.italic,\n bold: node.bold,\n value,\n },\n },\n );\n\n // Add a `<br>` before each substring except the first one\n return subindex === 0\n ? textElement\n : [createElement('br', {key: `${key}-br`}), textElement];\n });\n\n return elements.length > 1\n ? createElement(Fragment, {key: index}, elements)\n : elements[0];\n }\n case 'link':\n return createElement(\n Component as Exclude<CustomComponents['link'], undefined>,\n {\n key: index,\n node: {\n type: 'link',\n url: node.url,\n title: node.title,\n target: node.target,\n children,\n },\n },\n );\n case 'list':\n return createElement(\n Component as Exclude<CustomComponents['list'], undefined>,\n {\n key: index,\n node: {\n type: 'list',\n listType: node.listType,\n children,\n },\n },\n );\n case 'list-item':\n return createElement(\n Component as Exclude<CustomComponents['listItem'], undefined>,\n {\n key: index,\n node: {\n type: 'list-item',\n children,\n },\n },\n );\n }\n}\n\nfunction richTextToString(\n node: RichTextASTNode,\n result: string[] = [],\n): string {\n switch (node.type) {\n case 'root':\n node.children.forEach((child) => richTextToString(child, result));\n break;\n case 'heading':\n case 'paragraph':\n node.children.forEach((child) => richTextToString(child, result));\n result.push(' ');\n break;\n case 'text':\n result.push(node.value || '');\n break;\n case 'link':\n node.children.forEach((child) => richTextToString(child, result));\n break;\n case 'list':\n node.children.forEach((item) => {\n if (item.children) {\n item.children.forEach((child) => richTextToString(child, result));\n }\n result.push(' ');\n });\n break;\n default:\n throw new Error(`Unknown node encountered ${node.type}`);\n }\n\n return result.join('').trim();\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport type RichTextPropsForDocs<AsType extends React.ElementType = 'div'> =\n RichTextPropsBase<AsType>;\n","import {defaultShopifyContext, useShop} from './ShopifyProvider.js';\nimport {useLoadScript} from './load-script.js';\nimport {parseGid} from './analytics-utils.js';\n\n// By using 'never' in the \"or\" cases below, it makes these props \"exclusive\" and means that you cannot pass both of them; you must pass either one OR the other.\ntype ShopPayButtonProps = ShopPayButtonStyleProps &\n ShopPayDomainProps &\n ShopPayChannelAttribution &\n (ShopPayVariantIds | ShopPayVariantAndQuantities);\n\ntype ShopPayButtonStyleProps = {\n /** A string of classes to apply to the `div` that wraps the Shop Pay button. */\n className?: string;\n /** A string that's applied to the [CSS custom property (variable)](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) `--shop-pay-button-width` for the [Buy with Shop Pay component](https://shopify.dev/custom-storefronts/tools/web-components#buy-with-shop-pay-component). */\n width?: string;\n};\n\ntype ShopPayDomainProps = {\n /** The domain of your Shopify storefront URL (eg: `your-store.myshopify.com`). */\n storeDomain?: string;\n};\n\ntype ShopPayVariantIds = {\n /** An array of IDs of the variants to purchase with Shop Pay. This will only ever have a quantity of 1 for each variant. If you want to use other quantities, then use `variantIdsAndQuantities`. */\n variantIds: string[];\n /** An array of variant IDs and quantities to purchase with Shop Pay. */\n variantIdsAndQuantities?: never;\n};\n\ntype ShopPayVariantAndQuantities = {\n /** An array of IDs of the variants to purchase with Shop Pay. This will only ever have a quantity of 1 for each variant. If you want to use other quantities, then use `variantIdsAndQuantities`. */\n variantIds?: never;\n /** An array of variant IDs and quantities to purchase with Shop Pay. */\n variantIdsAndQuantities: Array<{\n id: string;\n quantity: number;\n }>;\n};\n\ntype ShopPayChannelAttribution = {\n /** A string that adds channel attribution to the order. Can be either `headless` or `hydrogen` */\n channel?: 'headless' | 'hydrogen';\n};\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n interface IntrinsicElements {\n 'shop-pay-button': {\n channel?: string;\n variants: string;\n 'store-url': string;\n };\n }\n }\n}\n\nconst SHOPJS_URL =\n 'https://cdn.shopify.com/shopifycloud/shop-js/v1.0/client.js';\n\nfunction isChannel(\n channel: string,\n): channel is Exclude<ShopPayChannelAttribution['channel'], undefined> {\n return channel === 'headless' || channel === 'hydrogen';\n}\n\n/**\n * The `ShopPayButton` component renders a button that redirects to the Shop Pay checkout.\n * It renders a [`<shop-pay-button>`](https://shopify.dev/custom-storefronts/tools/web-components) custom element, for which it will lazy-load the source code automatically.\n * It relies on the `<ShopProvider>` context provider.\n */\nexport function ShopPayButton({\n channel,\n variantIds,\n className,\n variantIdsAndQuantities,\n width,\n storeDomain: _storeDomain,\n}: ShopPayButtonProps): JSX.Element {\n const shop = useShop();\n const storeDomain = _storeDomain || shop?.storeDomain;\n const shopPayLoadedStatus = useLoadScript(SHOPJS_URL);\n\n let ids: string[] = [];\n let channelAttribution: string | undefined;\n\n if (!storeDomain || storeDomain === defaultShopifyContext.storeDomain) {\n throw new Error(MissingStoreDomainErrorMessage);\n }\n\n if (variantIds && variantIdsAndQuantities) {\n throw new Error(DoublePropsErrorMessage);\n }\n\n if (!variantIds && !variantIdsAndQuantities) {\n throw new Error(MissingPropsErrorMessage);\n }\n\n if (channel) {\n if (isChannel(channel)) {\n channelAttribution = channel;\n } else {\n throw new Error(InvalidChannelErrorMessage);\n }\n }\n\n if (variantIds) {\n ids = variantIds.reduce<string[]>((prev, curr) => {\n const bareId = parseGid(curr).id;\n if (bareId) {\n prev.push(bareId);\n }\n return prev;\n }, []);\n } else if (variantIdsAndQuantities) {\n ids = variantIdsAndQuantities.reduce<string[]>((prev, curr) => {\n const bareId = parseGid(curr?.id).id;\n if (bareId) {\n prev.push(`${bareId}:${curr?.quantity ?? 1}`);\n }\n return prev;\n }, []);\n } else {\n throw new Error(MissingPropsErrorMessage);\n }\n\n if (ids.length === 0) {\n throw new Error(InvalidPropsErrorMessage);\n }\n\n const style = width\n ? ({\n '--shop-pay-button-width': width,\n } as React.CSSProperties)\n : undefined;\n\n return (\n <div className={className} style={style}>\n {shopPayLoadedStatus === 'done' && (\n <shop-pay-button\n {...(channelAttribution ? {channel: channelAttribution} : {})}\n store-url={storeDomain}\n variants={ids.join(',')}\n />\n )}\n </div>\n );\n}\n\nexport const MissingStoreDomainErrorMessage =\n 'You must pass a \"storeDomain\" prop to the \"ShopPayButton\" component, or wrap it in a \"ShopifyProvider\" component.';\nexport const InvalidPropsErrorMessage = `You must pass in \"variantIds\" in the form of [\"gid://shopify/ProductVariant/1\"]`;\nexport const MissingPropsErrorMessage = `You must pass in either \"variantIds\" or \"variantIdsAndQuantities\" to ShopPayButton`;\nexport const DoublePropsErrorMessage = `You must provide either a variantIds or variantIdsAndQuantities prop, but not both in the ShopPayButton component`;\nexport const InvalidChannelErrorMessage = `Invalid channel attribution value. Must be either \"headless\" or \"hydrogen\"`;\n","import {useEffect} from 'react';\nimport {mapSelectedProductOptionToObject} from './getProductOptions.js';\nimport {SelectedOption} from './storefront-api-types.js';\n\nexport function useSelectedOptionInUrlParam(\n selectedOptions: Pick<SelectedOption, 'name' | 'value'>[],\n): null {\n useEffect(() => {\n const optionsSearchParams = new URLSearchParams(\n mapSelectedProductOptionToObject(selectedOptions || []),\n );\n const currentSearchParams = new URLSearchParams(window.location.search);\n\n // ts ignoring the URLSearchParams not iterable error for now\n // https://stackoverflow.com/questions/72522489/urlsearchparams-not-accepting-string#answer-72522838\n // TODO: update ts lib\n const combinedSearchParams = new URLSearchParams({\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...Object.fromEntries(currentSearchParams),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...Object.fromEntries(optionsSearchParams),\n });\n\n if (combinedSearchParams.size > 0) {\n window.history.replaceState(\n {},\n '',\n `${window.location.pathname}?${combinedSearchParams.toString()}`,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(selectedOptions)]);\n\n return null;\n}\n","import {useEffect} from 'react';\nimport {stringify} from 'worktop/cookie';\nimport {SHOPIFY_Y, SHOPIFY_S} from './cart-constants.js';\nimport {buildUUID, getShopifyCookies} from './cookies-utils.js';\n\nconst longTermLength = 60 * 60 * 24 * 360 * 1; // ~1 year expiry\nconst shortTermLength = 60 * 30; // 30 mins\n\ntype UseShopifyCookiesOptions = {\n /**\n * If set to `false`, Shopify cookies will be removed.\n * If set to `true`, Shopify unique user token cookie will have cookie expiry of 1 year.\n * Defaults to false.\n **/\n hasUserConsent?: boolean;\n /**\n * The domain scope of the cookie. Defaults to empty string.\n **/\n domain?: string;\n /**\n * The checkout domain of the shop. Defaults to empty string. If set, the cookie domain will check if it can be set with the checkout domain.\n */\n checkoutDomain?: string;\n};\n\nexport function useShopifyCookies(options?: UseShopifyCookiesOptions): void {\n const {\n hasUserConsent = false,\n domain = '',\n checkoutDomain = '',\n } = options || {};\n useEffect(() => {\n const cookies = getShopifyCookies(document.cookie);\n\n /**\n * Setting cookie with domain\n *\n * If no domain is provided, the cookie will be set for the current host.\n * For Shopify, we need to ensure this domain is set with a leading dot.\n */\n\n // Use override domain or current host\n let currentDomain = domain || window.document.location.host;\n\n if (checkoutDomain) {\n const checkoutDomainParts = checkoutDomain.split('.').reverse();\n const currentDomainParts = currentDomain.split('.').reverse();\n const sameDomainParts: Array<string> = [];\n checkoutDomainParts.forEach((part, index) => {\n if (part === currentDomainParts[index]) {\n sameDomainParts.push(part);\n }\n });\n\n currentDomain = sameDomainParts.reverse().join('.');\n }\n\n // Reset domain if localhost\n if (/^localhost/.test(currentDomain)) currentDomain = '';\n\n // Shopify checkout only consumes cookies set with leading dot domain\n const domainWithLeadingDot = currentDomain\n ? /^\\./.test(currentDomain)\n ? currentDomain\n : `.${currentDomain}`\n : '';\n\n /**\n * Set user and session cookies and refresh the expiry time\n */\n if (hasUserConsent) {\n setCookie(\n SHOPIFY_Y,\n cookies[SHOPIFY_Y] || buildUUID(),\n longTermLength,\n domainWithLeadingDot,\n );\n setCookie(\n SHOPIFY_S,\n cookies[SHOPIFY_S] || buildUUID(),\n shortTermLength,\n domainWithLeadingDot,\n );\n } else {\n setCookie(SHOPIFY_Y, '', 0, domainWithLeadingDot);\n setCookie(SHOPIFY_S, '', 0, domainWithLeadingDot);\n }\n }, [options, hasUserConsent, domain, checkoutDomain]);\n}\n\nfunction setCookie(\n name: string,\n value: string,\n maxage: number,\n domain: string,\n): void {\n document.cookie = stringify(name, value, {\n maxage,\n domain,\n samesite: 'Lax',\n path: '/',\n });\n}\n"],"names":["t","n","e","r","i","o","a","u","c","f","s","l","v","y","p","g","x","m","h","S","j","E","R","N","O","_","k","T","z","A","B","C","index","useLayoutEffect","require$$0","b","q","d","useSyncExternalStoreShim_production_min","shimModule","require$$1","w","withSelector_production_min","withSelectorModule","useConstant","fn","ref","React","__read","ar","error","identity","getServiceState","service","currentValue","state","useMachine","stateMachine","options","persistedStateRef","useRef","_b","queue","interpret","createMachine","send","event","InterpreterStatus","useIsomorphicLayoutEffect","useServiceResult","useService","useEffect","isEqual","_prevState","nextState","getSnapshot","useCallback","subscribe","handleStoreChange","unsubscribe","storeSnapshot","useSyncExternalStoreWithSelector","flattenConnection","connection","noConnectionErr","edge","CartLineAdd","cartFragment","CartCreate","CartLineRemove","CartLineUpdate","CartNoteUpdate","CartBuyerIdentityUpdate","CartAttributesUpdate","CartDiscountCodesUpdate","CartQuery","defaultCartFragment","SFAPI_VERSION","MOCK_SHOP_DOMAIN","isMockShop","domain","createStorefrontClient","storeDomain","privateStorefrontToken","publicStorefrontToken","storefrontApiVersion","contentType","H2_PREFIX_ERROR","warnOnce","getShopifyDomain","overrideProps","apiUrl","finalContentType","getPublicTokenHeadersRaw","accessToken","warnings","string","type","defaultShopifyContext","ShopifyContext","createContext","ShopifyProvider","children","shopifyConfig","finalConfig","useMemo","finalDomainUrl","useShop","shopContext","useContext","CART_ID_STORAGE_KEY","SHOPIFY_STOREFRONT_ID_HEADER","SHOPIFY_STOREFRONT_Y_HEADER","SHOPIFY_STOREFRONT_S_HEADER","SHOPIFY_Y","SHOPIFY_S","tokenHash","buildUUID","hash","crypto","randomValuesArray","hexTime","dateNumber","perfNumber","getShopifyCookies","cookies","cookieData","parse","useCartFetch","storefrontId","getPublicTokenHeaders","getStorefrontApiUrl","query","variables","headers","res","useCartActions","numCartLines","countryCode","languageCode","fetchCart","cartFetch","cartId","cartCreate","cart","cartLineAdd","lines","cartLineUpdate","cartLineRemove","noteUpdate","note","buyerIdentityUpdate","buyerIdentity","cartAttributesUpdate","attributes","discountCodesUpdate","discountCodes","invokeCart","action","assign","context","_a","INITIALIZING_CART_EVENTS","cartFromGraphQL","UPDATING_CART_EVENTS","createCartMachine","initialCart","useCartAPIStateMachine","onCartActionEntry","onCartActionOptimisticUI","onCartActionComplete","cartMachine","data","errors","resultEvent","eventFromFetchResult","isCartActionEvent","isCartFetchResultEvent","cartActionEvent","CartContext","useCart","CartProvider","onCreate","onLineAdd","onLineRemove","onLineUpdate","onNoteUpdate","onBuyerIdentityUpdate","onAttributesUpdate","onDiscountCodesUpdate","onCreateComplete","onLineAddComplete","onLineRemoveComplete","onLineUpdateComplete","onNoteUpdateComplete","onBuyerIdentityUpdateComplete","onAttributesUpdateComplete","onDiscountCodesUpdateComplete","customerAccessToken","shop","prevCountryCode","setPrevCountryCode","useState","prevCustomerAccessToken","setPrevCustomerAccessToken","customerOverridesCountryCode","cartState","cartSend","line","_d","_c","updatedLine","id","countryCodeNotUpdated","cartReady","isCartReady","setIsCartReady","cartCompleted","countryChanged","fetchingFromStorage","storageAvailable","onCartReadySend","cartEvent","_e","cartInput","cartDisplayState","useDelayedStateUntilHydration","cartContextValue","transposeStatus","_f","_g","status","isPending","startTransition","useTransition","delayedState","setDelayedState","firstTimePending","firstTimePendingFinished","storage","ProductOptionsContext","ProductProvider","product","explicitVariantId","variants","isProductVariantArray","getOptions","selectedVariant","setSelectedVariant","getVariantBasedOnIdProp","selectedOptions","setSelectedOptions","getSelectedOptions","newSelectedVariant","setSelectedOption","name","value","opts","getSelectedVariant","isOptionInStock","option","proposedVariant","sellingPlanGroups","sellingPlanGroup","selectedSellingPlan","setSelectedSellingPlan","selectedSellingPlanAllocation","allocation","useProduct","choices","variant","map","memo","opt","foundVariant","optionSet","maybeVariantArray","BaseButton","props","as","onClick","defaultOnClick","buttonRef","passthroughProps","handleOnClick","clickShouldContinue","Component","AddToCartButton","addingItem","setAddingItem","quantity","sellingPlanId","accessibleAddingToCartLabel","linesAdd","variantId","disabled","handleAddItem","AnalyticsEventName","AnalyticsPageType","ShopifySalesChannel","ShopifyAppId","schemaWrapper","schemaId","payload","parseGid","gid","defaultReturn","search","searchParams","pathname","pathnameParts","lastPathnamePart","resourcePart","addDataIf","keyValuePairs","formattedData","key","errorIfServer","fnName","SCHEMA_ID","OXYGEN_DOMAIN","pageView","pageViewPayload","resource","resourceType","formatPayload","isMerchantRequest","url","hostname","PAGE_RENDERED_EVENT_NAME","COLLECTION_PAGE_RENDERED_EVENT_NAME","PRODUCT_PAGE_RENDERED_EVENT_NAME","PRODUCT_ADDED_TO_CART_EVENT_NAME","SEARCH_SUBMITTED_EVENT_NAME","prepareAdditionalPayload","additionalPayload","pageType","pageViewEvents","formatProductPayload","pageView2","collectionView","productView","searchView","addToCart","addToCartPayload","cartToken","cart_token","version","products","sendShopifyAnalytics","shopDomain","eventName","events","trekkiePageView","customerPageView","customerAddToCart","customerPageView2","customerCollectionView","customerProductView","customerSearchView","sendToShopify","isLighthouseUserAgent","ERROR_MESSAGE","eventsToBeSent","response","eventResponse","err","getClientBrowserParameters","navigationType","navigationApi","getNavigationType","getNavigationTypeExperimental","navigationEntries","rawType","getNavigationTypeLegacy","navApi","navType","BuyNowButton","checkoutUrl","loading","setLoading","handleBuyNow","CartCheckoutButton","requestedCheckout","setRequestedCheckout","useMoney","money","countryIsoCode","languageIsoCode","locale","amount","defaultFormatter","nameFormatter","narrowSymbolFormatter","withoutTrailingZerosFormatter","withoutCurrencyFormatter","withoutTrailingZerosOrCurrencyFormatter","getLazyFormatter","isPartCurrency","part","lazyFormatters","target","formatterCache","formatter","Money","withoutCurrency","withoutTrailingZeros","measurement","measurementSeparator","isMoney","moneyObject","Wrapper","output","maybeMoney","CartCost","cost","amountType","CartLineContext","useCartLine","CartLineProvider","CartLineQuantity","cartLine","CartLineQuantityAdjustButton","linesRemove","linesUpdate","adjust","handleAdjust","lineUpdate","disabledAttr","storefrontApiCustomScalars","customerAccountApiCustomScalars","ExternalVideo","forwardRef","frameBorder","allow","allowFullScreen","finalUrl","urlObject","OPTION_VALUE_SEPARATOR","V1_CONTROL_CHARS","isOptionValueCombinationInEncodedVariant","decodedOptionValues","targetOptionValueCombination","encodedVariantField","decodedOptionValuesSet","optionValue","decodeEncodedVariant","v1Decoder","stripVersion","tokenizer","token","currentOptionValue","depth","rangeStart","operation","optionValueIndex","lastRangeStartIndex","finalValueIndex","mapProductOptions","mapSelectedProductOptionToObject","mapSelectedProductOptionToObjectAsString","encodeSelectedProductOptionAsKey","selectedOption","productOptionMappings","mapVariants","PRODUCT_INPUTS","PRODUCT_INPUTS_EXTRA","logErrorAndReturnFalse","checkProductParam","checkAll","validParam","productKeys","firstOption","firstOptionValues","checkProductVariantParam","currentValidParamState","firstSelectedOption","getAdjacentAndFirstAvailableVariants","checkedProduct","availableVariants","variantKey","getProductOptions","adjacentVariants","encodedVariantExistence","encodedVariantAvailability","productHandle","optionIndex","targetOptionParams","targetKey","topDownKey","exists","available","variantOptionParam","handle","IMAGE_FRAGMENT","Image","alt","aspectRatio","crop","decoding","height","loader","shopifyLoader","sizes","src","srcSetOptions","width","normalizedData","dataWidth","dataHeight","unitsMatch","normalizedProps","widthParts","getUnitValueParts","nWidth","autoHeight","heightParts","fixedHeight","nHeight","nSrc","nAlt","nAspectRatio","getNormalizedFixedUnit","intervals","startingWidth","incrementSize","placeholderWidth","imageWidths","generateImageWidths","isFixedWidth","FixedWidthImage","FluidImage","fixed","intWidth","intHeight","fixedAspectRatio","sizesArray","generateSizes","parseAspectRatio","srcSet","generateSrcSet","fluid","placeholderHeight","PLACEHOLDER_DOMAIN","unit","number","size","responsive","sourceDimensions","SCRIPTS_LOADED","loadScript","isScriptLoaded","promise","resolve","reject","script","useLoadScript","setStatus","Video","previewImageOptions","playsInline","controls","sourceProps","posterUrl","source","ModelViewer","modelViewer","setModelViewer","callbackRef","node","className","modelViewerLoadedStatus","hydrogenEventListener","callbackFunc","MediaFile","mediaOptions","parseMetafield","metafield","parsedValue","parseJSON","jsonParseValue","dateString","typeNotFoundError","json","ProductPrice","priceType","valueType","price","variantPriceProperty","priceAsNumber","compareAtPriceAsNumber","RichTextComponents","Root","Heading","Paragraph","Text","RichTextLink","List","ListItem","createElement","RichText","plain","components","parsedData","richTextToString","serializeRichTextASTNode","child","childIndex","elements","subindex","textElement","Fragment","result","item","SHOPJS_URL","isChannel","channel","ShopPayButton","variantIds","variantIdsAndQuantities","_storeDomain","shopPayLoadedStatus","ids","channelAttribution","MissingStoreDomainErrorMessage","DoublePropsErrorMessage","MissingPropsErrorMessage","InvalidChannelErrorMessage","prev","curr","bareId","InvalidPropsErrorMessage","style","useSelectedOptionInUrlParam","optionsSearchParams","currentSearchParams","combinedSearchParams","longTermLength","shortTermLength","useShopifyCookies","hasUserConsent","checkoutDomain","currentDomain","checkoutDomainParts","currentDomainParts","sameDomainParts","domainWithLeadingDot","setCookie","maxage","stringify"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,14]}
|
|
1
|
+
{"version":3,"file":"hydrogen-react.prod.js","sources":["../../../../node_modules/@xstate/fsm/es/index.js","../../../../node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js","../../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js","../../../../node_modules/use-sync-external-store/shim/index.js","../../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js","../../../../node_modules/use-sync-external-store/shim/with-selector.js","../../../../node_modules/@xstate/react/es/useConstant.js","../../../../node_modules/@xstate/react/es/fsm.js","../../src/flatten-connection.ts","../../src/cart-queries.ts","../../src/storefront-api-constants.ts","../../src/storefront-client.ts","../../src/ShopifyProvider.tsx","../../src/cart-constants.ts","../../../../node_modules/worktop/cookie/index.mjs","../../src/cookies-utils.tsx","../../src/cart-hooks.tsx","../../src/useCartActions.tsx","../../src/useCartAPIStateMachine.tsx","../../src/CartProvider.tsx","../../src/ProductProvider.tsx","../../src/BaseButton.tsx","../../src/AddToCartButton.tsx","../../src/analytics-constants.ts","../../src/analytics-utils.ts","../../src/analytics-schema-trekkie-storefront-page-view.ts","../../src/analytics-schema-custom-storefront-customer-tracking.ts","../../src/analytics.ts","../../src/BuyNowButton.tsx","../../src/CartCheckoutButton.tsx","../../src/useMoney.tsx","../../src/Money.tsx","../../src/CartCost.tsx","../../src/CartLineProvider.tsx","../../src/CartLineQuantity.tsx","../../src/CartLineQuantityAdjustButton.tsx","../../src/codegen.helpers.ts","../../src/ExternalVideo.tsx","../../src/optionValueDecoder.ts","../../src/getProductOptions.ts","../../src/Image.tsx","../../src/load-script.tsx","../../src/Video.tsx","../../src/ModelViewer.tsx","../../src/MediaFile.tsx","../../src/parse-metafield.ts","../../src/ProductPrice.tsx","../../src/RichText.components.tsx","../../src/RichText.tsx","../../src/ShopPayButton.tsx","../../src/useSelectedOptionInUrlParam.tsx","../../src/useShopifyCookies.tsx"],"sourcesContent":["/*! *****************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\nfunction t(t,n){var e=\"function\"==typeof Symbol&&t[Symbol.iterator];if(!e)return t;var r,i,o=e.call(t),a=[];try{for(;(void 0===n||n-- >0)&&!(r=o.next()).done;)a.push(r.value)}catch(t){i={error:t}}finally{try{r&&!r.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return a}var n;!function(t){t[t.NotStarted=0]=\"NotStarted\",t[t.Running=1]=\"Running\",t[t.Stopped=2]=\"Stopped\"}(n||(n={}));var e={type:\"xstate.init\"};function r(t){return void 0===t?[]:[].concat(t)}function i(t){return{type:\"xstate.assign\",assignment:t}}function o(t,n){return\"string\"==typeof(t=\"string\"==typeof t&&n&&n[t]?n[t]:t)?{type:t}:\"function\"==typeof t?{type:t.name,exec:t}:t}function a(t){return function(n){return t===n}}function u(t){return\"string\"==typeof t?{type:t}:t}function c(t,n){return{value:t,context:n,actions:[],changed:!1,matches:a(t)}}function f(t,n,e){var r=n,i=!1;return[t.filter((function(t){if(\"xstate.assign\"===t.type){i=!0;var n=Object.assign({},r);return\"function\"==typeof t.assignment?n=t.assignment(r,e):Object.keys(t.assignment).forEach((function(i){n[i]=\"function\"==typeof t.assignment[i]?t.assignment[i](r,e):t.assignment[i]})),r=n,!1}return!0})),r,i]}function s(n,i){void 0===i&&(i={});var s=t(f(r(n.states[n.initial].entry).map((function(t){return o(t,i.actions)})),n.context,e),2),l=s[0],v=s[1],y={config:n,_options:i,initialState:{value:n.initial,actions:l,context:v,matches:a(n.initial)},transition:function(e,i){var s,l,v=\"string\"==typeof e?{value:e,context:n.context}:e,p=v.value,g=v.context,d=u(i),x=n.states[p];if(x.on){var m=r(x.on[d.type]);try{for(var h=function(t){var n=\"function\"==typeof Symbol&&Symbol.iterator,e=n&&t[n],r=0;if(e)return e.call(t);if(t&&\"number\"==typeof t.length)return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(n?\"Object is not iterable.\":\"Symbol.iterator is not defined.\")}(m),b=h.next();!b.done;b=h.next()){var S=b.value;if(void 0===S)return c(p,g);var w=\"string\"==typeof S?{target:S}:S,j=w.target,E=w.actions,R=void 0===E?[]:E,N=w.cond,O=void 0===N?function(){return!0}:N,_=void 0===j,k=null!=j?j:p,T=n.states[k];if(O(g,d)){var q=t(f((_?r(R):[].concat(x.exit,R,T.entry).filter((function(t){return t}))).map((function(t){return o(t,y._options.actions)})),g,d),3),z=q[0],A=q[1],B=q[2],C=null!=j?j:p;return{value:C,context:A,actions:z,changed:j!==p||z.length>0||B,matches:a(C)}}}}catch(t){s={error:t}}finally{try{b&&!b.done&&(l=h.return)&&l.call(h)}finally{if(s)throw s.error}}}return c(p,g)}};return y}var l=function(t,n){return t.actions.forEach((function(e){var r=e.exec;return r&&r(t.context,n)}))};function v(t){var r=t.initialState,i=n.NotStarted,o=new Set,c={_machine:t,send:function(e){i===n.Running&&(r=t.transition(r,e),l(r,u(e)),o.forEach((function(t){return t(r)})))},subscribe:function(t){return o.add(t),t(r),{unsubscribe:function(){return o.delete(t)}}},start:function(o){if(o){var u=\"object\"==typeof o?o:{context:t.config.context,value:o};r={value:u.value,actions:[],context:u.context,matches:a(u.value)}}else r=t.initialState;return i=n.Running,l(r,e),c},stop:function(){return i=n.Stopped,o.clear(),c},get state(){return r},get status(){return i}};return c}export{n as InterpreterStatus,i as assign,s as createMachine,v as interpret};\n","import { useLayoutEffect } from 'react';\n\nvar index = useLayoutEffect ;\n\nexport default index;\n","/**\n * @license React\n * use-sync-external-store-shim.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var e=require(\"react\");function h(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var k=\"function\"===typeof Object.is?Object.is:h,l=e.useState,m=e.useEffect,n=e.useLayoutEffect,p=e.useDebugValue;function q(a,b){var d=b(),f=l({inst:{value:d,getSnapshot:b}}),c=f[0].inst,g=f[1];n(function(){c.value=d;c.getSnapshot=b;r(c)&&g({inst:c})},[a,d,b]);m(function(){r(c)&&g({inst:c});return a(function(){r(c)&&g({inst:c})})},[a]);p(d);return d}\nfunction r(a){var b=a.getSnapshot;a=a.value;try{var d=b();return!k(a,d)}catch(f){return!0}}function t(a,b){return b()}var u=\"undefined\"===typeof window||\"undefined\"===typeof window.document||\"undefined\"===typeof window.document.createElement?t:q;exports.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:u;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('../cjs/use-sync-external-store-shim.production.min.js');\n} else {\n module.exports = require('../cjs/use-sync-external-store-shim.development.js');\n}\n","/**\n * @license React\n * use-sync-external-store-shim/with-selector.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var h=require(\"react\"),n=require(\"use-sync-external-store/shim\");function p(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var q=\"function\"===typeof Object.is?Object.is:p,r=n.useSyncExternalStore,t=h.useRef,u=h.useEffect,v=h.useMemo,w=h.useDebugValue;\nexports.useSyncExternalStoreWithSelector=function(a,b,e,l,g){var c=t(null);if(null===c.current){var f={hasValue:!1,value:null};c.current=f}else f=c.current;c=v(function(){function a(a){if(!c){c=!0;d=a;a=l(a);if(void 0!==g&&f.hasValue){var b=f.value;if(g(b,a))return k=b}return k=a}b=k;if(q(d,a))return b;var e=l(a);if(void 0!==g&&g(b,e))return b;d=a;return k=e}var c=!1,d,k,m=void 0===e?null:e;return[function(){return a(b())},null===m?void 0:function(){return a(m())}]},[b,e,l,g]);var d=r(a,c[0],c[1]);\nu(function(){f.hasValue=!0;f.value=d},[d]);w(d);return d};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('../cjs/use-sync-external-store-shim/with-selector.production.min.js');\n} else {\n module.exports = require('../cjs/use-sync-external-store-shim/with-selector.development.js');\n}\n","import * as React from 'react';\nexport default function useConstant(fn) {\n var ref = React.useRef();\n if (!ref.current) {\n ref.current = { v: fn() };\n }\n return ref.current.v;\n}\n","var __read = (this && this.__read) || function (o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n};\nimport { createMachine, interpret, InterpreterStatus } from '@xstate/fsm';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';\nimport useConstant from './useConstant';\nfunction identity(a) {\n return a;\n}\nvar getServiceState = function (service) {\n var currentValue;\n service\n .subscribe(function (state) {\n currentValue = state;\n })\n .unsubscribe();\n return currentValue;\n};\nexport function useMachine(stateMachine, options) {\n var persistedStateRef = useRef();\n if (process.env.NODE_ENV !== 'production') {\n var _a = __read(useState(stateMachine), 1), initialMachine = _a[0];\n if (stateMachine !== initialMachine) {\n console.warn('Machine given to `useMachine` has changed between renders. This is not supported and might lead to unexpected results.\\n' +\n 'Please make sure that you pass the same Machine as argument each time.');\n }\n }\n var _b = __read(useConstant(function () {\n var queue = [];\n var service = interpret(createMachine(stateMachine.config, options ? options : stateMachine._options));\n var send = service.send;\n service.send = function (event) {\n if (service.status === InterpreterStatus.NotStarted) {\n queue.push(event);\n return;\n }\n send(event);\n persistedStateRef.current = service.state;\n };\n return [service, queue];\n }), 2), service = _b[0], queue = _b[1];\n useIsomorphicLayoutEffect(function () {\n if (options) {\n service._machine._options = options;\n }\n });\n var useServiceResult = useService(service);\n useEffect(function () {\n service.start(persistedStateRef.current);\n queue.forEach(service.send);\n persistedStateRef.current = service.state;\n return function () {\n service.stop();\n };\n }, []);\n return useServiceResult;\n}\nvar isEqual = function (_prevState, nextState) { return nextState.changed === false; };\nexport function useService(service) {\n var getSnapshot = useCallback(function () { return getServiceState(service); }, [service]);\n var subscribe = useCallback(function (handleStoreChange) {\n var unsubscribe = service.subscribe(handleStoreChange).unsubscribe;\n return unsubscribe;\n }, [service]);\n var storeSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);\n return [storeSnapshot, service.send, service];\n}\n","import type {PartialDeep} from 'type-fest';\n\n/**\n * The `flattenConnection` utility transforms a connection object from the Storefront API (for example, [Product-related connections](https://shopify.dev/api/storefront/reference/products/product)) into a flat array of nodes.\n * The utility works with either `nodes` or `edges.node`.\n *\n * If `connection` is null or undefined, will return an empty array instead in production. In development, an error will be thrown.\n */\nexport function flattenConnection<\n ConnectionGeneric extends\n | PartialDeep<ConnectionEdges, {recurseIntoArrays: true}>\n | PartialDeep<ConnectionNodes, {recurseIntoArrays: true}>\n | ConnectionEdges\n | ConnectionNodes,\n>(\n connection?: ConnectionGeneric,\n): ConnectionGeneric extends\n | {\n edges: Array<{node: infer ConnectionBaseType}>;\n }\n | {\n nodes: Array<infer ConnectionBaseType>;\n }\n ? // if it's not a PartialDeep, then return the infered type\n ConnectionBaseType[]\n : ConnectionGeneric extends\n | PartialDeep<\n {edges: {node: Array<infer ConnectionBaseType>}},\n {recurseIntoArrays: true}\n >\n | PartialDeep<\n {\n nodes: Array<infer ConnectionBaseType>;\n },\n {recurseIntoArrays: true}\n >\n ? // if it is a PartialDeep, return a PartialDeep inferred type\n PartialDeep<ConnectionBaseType[], {recurseIntoArrays: true}>\n : never {\n if (!connection) {\n const noConnectionErr = `flattenConnection(): needs a 'connection' to flatten, but received '${\n connection ?? ''\n }' instead.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noConnectionErr);\n } else {\n console.error(noConnectionErr + ` Returning an empty array`);\n // @ts-expect-error We don't want to crash prod, so return an empty array\n return [];\n }\n }\n\n if ('nodes' in connection) {\n // @ts-expect-error return type is failing\n return connection.nodes;\n }\n\n if ('edges' in connection && Array.isArray(connection.edges)) {\n // @ts-expect-error return type is failing\n return connection.edges.map((edge) => {\n if (!edge?.node) {\n throw new Error(\n 'flattenConnection(): Connection edges must contain nodes',\n );\n }\n return edge.node;\n }) as Array<unknown>;\n }\n\n if (__HYDROGEN_DEV__) {\n console.warn(\n `flattenConnection(): The connection did not contain either \"nodes\" or \"edges.node\". Returning an empty array.`,\n );\n }\n\n // @ts-expect-error We don't want to crash prod, so return an empty array\n return [];\n}\n\ntype ConnectionEdges = {\n edges: Array<{node: unknown}>;\n};\n\ntype ConnectionNodes = {\n nodes: Array<unknown>;\n};\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface ConnectionGenericForDoc {\n connection?: ConnectionEdges | ConnectionNodes;\n}\nexport type FlattenConnectionReturnForDoc = Array<unknown>;\n","export const CartLineAdd = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineAdd(\n $cartId: ID!\n $lines: [CartLineInput!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesAdd(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartCreate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartCreate(\n $input: CartInput!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartCreate(input: $input) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartLineRemove = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineRemove(\n $cartId: ID!\n $lines: [ID!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesRemove(cartId: $cartId, lineIds: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartLineUpdate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartLineUpdate(\n $cartId: ID!\n $lines: [CartLineUpdateInput!]!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartLinesUpdate(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartNoteUpdate = (cartFragment: string): string => /* GraphQL */ `\n mutation CartNoteUpdate(\n $cartId: ID!\n $note: String!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartNoteUpdate(cartId: $cartId, note: $note) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartBuyerIdentityUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartBuyerIdentityUpdate(\n $cartId: ID!\n $buyerIdentity: CartBuyerIdentityInput!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartBuyerIdentityUpdate(cartId: $cartId, buyerIdentity: $buyerIdentity) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartAttributesUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartAttributesUpdate(\n $attributes: [AttributeInput!]!\n $cartId: ID!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartAttributesUpdate(attributes: $attributes, cartId: $cartId) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartDiscountCodesUpdate = (\n cartFragment: string,\n): string => /* GraphQL */ `\n mutation CartDiscountCodesUpdate(\n $cartId: ID!\n $discountCodes: [String!]\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {\n cart {\n ...CartFragment\n }\n }\n }\n\n ${cartFragment}\n`;\n\nexport const CartQuery = (cartFragment: string): string => /* GraphQL */ `\n query CartQuery(\n $id: ID!\n $numCartLines: Int = 250\n $country: CountryCode = ZZ\n $language: LanguageCode\n ) @inContext(country: $country, language: $language) {\n cart(id: $id) {\n ...CartFragment\n }\n }\n\n ${cartFragment}\n`;\n\nexport const defaultCartFragment = /* GraphQL */ `\n fragment CartFragment on Cart {\n id\n checkoutUrl\n totalQuantity\n buyerIdentity {\n countryCode\n customer {\n id\n email\n firstName\n lastName\n displayName\n }\n email\n phone\n }\n lines(first: $numCartLines) {\n edges {\n node {\n id\n quantity\n attributes {\n key\n value\n }\n cost {\n totalAmount {\n amount\n currencyCode\n }\n compareAtAmountPerQuantity {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n availableForSale\n compareAtPrice {\n ...MoneyFragment\n }\n price {\n ...MoneyFragment\n }\n requiresShipping\n title\n image {\n ...ImageFragment\n }\n product {\n handle\n title\n id\n }\n selectedOptions {\n name\n value\n }\n }\n }\n }\n }\n }\n cost {\n subtotalAmount {\n ...MoneyFragment\n }\n totalAmount {\n ...MoneyFragment\n }\n totalDutyAmount {\n ...MoneyFragment\n }\n totalTaxAmount {\n ...MoneyFragment\n }\n }\n note\n attributes {\n key\n value\n }\n discountCodes {\n code\n applicable\n }\n }\n\n fragment MoneyFragment on MoneyV2 {\n currencyCode\n amount\n }\n fragment ImageFragment on Image {\n id\n url\n altText\n width\n height\n }\n`;\n","export const SFAPI_VERSION = '2025-01';\n","import {SFAPI_VERSION} from './storefront-api-constants.js';\n\nexport type StorefrontClientProps = {\n /** The host name of the domain (eg: `{shop}.myshopify.com`). */\n storeDomain?: string;\n /** The Storefront API delegate access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) and [delegate access token](https://shopify.dev/apps/auth/oauth/delegate-access-tokens) documentation for more details. */\n privateStorefrontToken?: string;\n /** The Storefront API access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n publicStorefrontToken?: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen React was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion?: string;\n /**\n * Customizes which `\"content-type\"` header is added when using `getPrivateTokenHeaders()` and `getPublicTokenHeaders()`. When fetching with a `JSON.stringify()`-ed `body`, use `\"json\"`. When fetching with a `body` that is a plain string, use `\"graphql\"`. Defaults to `\"json\"`\n *\n * Can also be customized on a call-by-call basis by passing in `'contentType'` to both `getPrivateTokenHeaders({...})` and `getPublicTokenHeaders({...})`, for example: `getPublicTokenHeaders({contentType: 'graphql'})`\n */\n contentType?: 'json' | 'graphql';\n};\n\nconst MOCK_SHOP_DOMAIN = 'mock.shop';\nconst isMockShop = (domain: string): boolean =>\n domain.includes(MOCK_SHOP_DOMAIN);\n\n/**\n * The `createStorefrontClient()` function creates helpers that enable you to quickly query the Shopify Storefront API.\n *\n * When used on the server, it is recommended to use the `privateStorefrontToken` prop. When used on the client, it is recommended to use the `publicStorefrontToken` prop.\n */\nexport function createStorefrontClient({\n storeDomain,\n privateStorefrontToken,\n publicStorefrontToken,\n storefrontApiVersion = SFAPI_VERSION,\n contentType,\n}: StorefrontClientProps): StorefrontClientReturn {\n if (!storeDomain) {\n if (__HYDROGEN_DEV__) {\n storeDomain = MOCK_SHOP_DOMAIN;\n warnOnce(\n `storeDomain missing, defaulting to ${MOCK_SHOP_DOMAIN}`,\n 'info',\n );\n } else {\n throw new Error(\n H2_PREFIX_ERROR +\n `\\`storeDomain\\` is required when creating a new Storefront client in production.`,\n );\n }\n }\n\n if (storefrontApiVersion !== SFAPI_VERSION) {\n warnOnce(\n `The Storefront API version that you're using is different than the version this build of Hydrogen React is targeting.` +\n `\\nYou may run into unexpected errors if these versions don't match. Received version: \"${storefrontApiVersion}\"; expected version \"${SFAPI_VERSION}\"`,\n );\n }\n\n // only warn if not in a browser environment\n if (\n __HYDROGEN_DEV__ &&\n !privateStorefrontToken &&\n !globalThis.document &&\n !isMockShop(storeDomain)\n ) {\n warnOnce(\n `Using a private storefront token is recommended for server environments.` +\n `\\nRefer to the authentication https://shopify.dev/api/storefront#authentication documentation for more details.`,\n );\n }\n\n // only warn if in a browser environment and you're using the privateStorefrontToken\n if (__HYDROGEN_DEV__ && privateStorefrontToken && globalThis.document) {\n warnOnce(\n 'You are attempting to use a private token in an environment where it can be easily accessed by anyone.' +\n '\\nThis is a security risk; please use the public token and the `publicStorefrontToken` prop',\n );\n }\n\n const getShopifyDomain: StorefrontClientReturn['getShopifyDomain'] = (\n overrideProps,\n ) => {\n const domain = overrideProps?.storeDomain ?? storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n };\n\n return {\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const domain = getShopifyDomain(overrideProps);\n const apiUrl = domain + (domain.endsWith('/') ? 'api' : '/api');\n\n if (isMockShop(domain)) return apiUrl;\n\n return `${apiUrl}/${\n overrideProps?.storefrontApiVersion ?? storefrontApiVersion\n }/graphql.json`;\n },\n getPrivateTokenHeaders(overrideProps): Record<string, string> {\n if (\n !privateStorefrontToken &&\n !overrideProps?.privateStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `privateStorefrontToken` while using `createStorefrontClient()` or `getPrivateTokenHeaders()`',\n );\n }\n\n if (__HYDROGEN_DEV__ && !overrideProps?.buyerIp) {\n warnOnce(\n 'It is recommended to pass in the `buyerIp` property which improves analytics and data in the admin.',\n );\n }\n\n const finalContentType = overrideProps?.contentType ?? contentType;\n\n return {\n // default to json\n 'content-type':\n finalContentType === 'graphql'\n ? 'application/graphql'\n : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'Shopify-Storefront-Private-Token':\n overrideProps?.privateStorefrontToken ?? privateStorefrontToken ?? '',\n ...(overrideProps?.buyerIp\n ? {'Shopify-Storefront-Buyer-IP': overrideProps.buyerIp}\n : {}),\n };\n },\n getPublicTokenHeaders(overrideProps): Record<string, string> {\n if (\n !publicStorefrontToken &&\n !overrideProps?.publicStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `publicStorefrontToken` while using `createStorefrontClient()` or `getPublicTokenHeaders()`',\n );\n }\n\n const finalContentType =\n overrideProps?.contentType ?? contentType ?? 'json';\n\n return getPublicTokenHeadersRaw(\n finalContentType,\n storefrontApiVersion,\n overrideProps?.publicStorefrontToken ?? publicStorefrontToken ?? '',\n );\n },\n };\n}\n\nexport function getPublicTokenHeadersRaw(\n contentType: 'graphql' | 'json',\n storefrontApiVersion: string,\n accessToken: string,\n): {\n 'content-type': string;\n 'X-SDK-Variant': string;\n 'X-SDK-Variant-Source': string;\n 'X-SDK-Version': string;\n 'X-Shopify-Storefront-Access-Token': string;\n} {\n return {\n // default to json\n 'content-type':\n contentType === 'graphql' ? 'application/graphql' : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'X-Shopify-Storefront-Access-Token': accessToken,\n };\n}\n\nconst warnings = new Set<string>();\nconst H2_PREFIX_ERROR = '[h2:error:createStorefrontClient] ';\nconst warnOnce = (string: string, type: 'warn' | 'info' = 'warn'): void => {\n if (!warnings.has(string)) {\n console[type](`[h2:${type}:createStorefrontClient] ` + string);\n warnings.add(string);\n }\n};\n\ntype OverrideTokenHeaderProps = Partial<\n Pick<StorefrontClientProps, 'contentType'>\n>;\n\ntype StorefrontClientReturn = {\n /**\n * Creates the fully-qualified URL to your myshopify.com domain.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getShopifyDomain({...})`:\n *\n * - `storeDomain`\n */\n getShopifyDomain: (\n props?: Partial<Pick<StorefrontClientProps, 'storeDomain'>>,\n ) => string;\n /**\n * Creates the fully-qualified URL to your store's GraphQL endpoint.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getStorefrontApiUrl({...})`:\n *\n * - `storeDomain`\n * - `storefrontApiVersion`\n */\n getStorefrontApiUrl: (\n props?: Partial<\n Pick<StorefrontClientProps, 'storeDomain' | 'storefrontApiVersion'>\n >,\n ) => string;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This method uses the private Server-to-Server token which reduces the chance of throttling but must not be exposed to clients. Server-side calls should prefer using this over `getPublicTokenHeaders()`.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getPrivateTokenHeaders({...})`:\n *\n * - `contentType`\n * - `privateStorefrontToken`\n * - `buyerIp`\n *\n * Note that `contentType` defaults to what you configured in `createStorefrontClient({...})` and defaults to `'json'`, but a specific call may require using `graphql`. When using `JSON.stringify()` on the `body`, use `'json'`; otherwise, use `'graphql'`.\n */\n getPrivateTokenHeaders: (\n props?: OverrideTokenHeaderProps &\n Pick<StorefrontClientProps, 'privateStorefrontToken'> & {\n /**\n * The client's IP address. Passing this to the Storefront API when using a server-to-server token will help improve your store's analytics data.\n */\n buyerIp?: string;\n },\n ) => Record<string, string>;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This method uses the public token which increases the chance of throttling but also can be exposed to clients. Server-side calls should prefer using `getPublicTokenHeaders()`.\n *\n * By default, it will use the config you passed in when calling `createStorefrontClient()`. However, you can override the following settings on each invocation of `getPublicTokenHeaders({...})`:\n *\n * - `contentType`\n * - `publicStorefrontToken`\n *\n * Note that `contentType` defaults to what you configured in `createStorefrontClient({...})` and defaults to `'json'`, but a specific call may require using `graphql`. When using `JSON.stringify()` on the `body`, use `'json'`; otherwise, use `'graphql'`.\n */\n getPublicTokenHeaders: (\n props?: OverrideTokenHeaderProps &\n Pick<StorefrontClientProps, 'publicStorefrontToken'>,\n ) => Record<string, string>;\n};\n","import {createContext, useContext, useMemo, type ReactNode} from 'react';\nimport type {LanguageCode, CountryCode} from './storefront-api-types.js';\nimport {SFAPI_VERSION} from './storefront-api-constants.js';\nimport {getPublicTokenHeadersRaw} from './storefront-client.js';\n\nexport const defaultShopifyContext: ShopifyContextValue = {\n storeDomain: 'test',\n storefrontToken: 'abc123',\n storefrontApiVersion: SFAPI_VERSION,\n countryIsoCode: 'US',\n languageIsoCode: 'EN',\n getStorefrontApiUrl() {\n return '';\n },\n getPublicTokenHeaders() {\n return {};\n },\n getShopifyDomain() {\n return '';\n },\n};\n\nconst ShopifyContext = createContext<ShopifyContextValue>(\n defaultShopifyContext,\n);\n\n/**\n * The `<ShopifyProvider/>` component enables use of the `useShop()` hook. The component should wrap your app.\n */\nexport function ShopifyProvider({\n children,\n ...shopifyConfig\n}: ShopifyProviderProps): JSX.Element {\n if (\n !shopifyConfig.countryIsoCode ||\n !shopifyConfig.languageIsoCode ||\n !shopifyConfig.storeDomain ||\n !shopifyConfig.storefrontToken ||\n !shopifyConfig.storefrontApiVersion\n ) {\n throw new Error(\n `Please provide the necessary props to '<ShopifyProvider/>'`,\n );\n }\n\n if (shopifyConfig.storefrontApiVersion !== SFAPI_VERSION) {\n console.warn(\n `<ShopifyProvider/>: This version of Hydrogen React is built for Shopify's Storefront API version ${SFAPI_VERSION}, but it looks like you're using version ${shopifyConfig.storefrontApiVersion}. There may be issues or bugs if you use a mismatched version of Hydrogen React and the Storefront API.`,\n );\n }\n\n const finalConfig = useMemo<ShopifyContextValue>(() => {\n function getShopifyDomain(overrideProps?: {storeDomain?: string}): string {\n const domain = overrideProps?.storeDomain ?? shopifyConfig.storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n }\n\n return {\n ...shopifyConfig,\n getPublicTokenHeaders(overrideProps): Record<string, string> {\n return getPublicTokenHeadersRaw(\n overrideProps.contentType,\n shopifyConfig.storefrontApiVersion,\n overrideProps.storefrontToken ?? shopifyConfig.storefrontToken,\n );\n },\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const finalDomainUrl = getShopifyDomain({\n storeDomain: overrideProps?.storeDomain ?? shopifyConfig.storeDomain,\n });\n return `${finalDomainUrl}${\n finalDomainUrl.endsWith('/') ? '' : '/'\n }api/${\n overrideProps?.storefrontApiVersion ??\n shopifyConfig.storefrontApiVersion\n }/graphql.json`;\n },\n };\n }, [shopifyConfig]);\n\n return (\n <ShopifyContext.Provider value={finalConfig}>\n {children}\n </ShopifyContext.Provider>\n );\n}\n\n/**\n * Provides access to the `shopifyConfig` prop of `<ShopifyProvider/>`. Must be a descendent of `<ShopifyProvider/>`.\n */\nexport function useShop(): ShopifyContextValue {\n const shopContext = useContext(ShopifyContext);\n if (!shopContext) {\n throw new Error(`'useShop()' must be a descendent of <ShopifyProvider/>`);\n }\n return shopContext;\n}\n\nexport interface ShopifyProviderBase {\n /** The globally-unique identifier for the Shop */\n storefrontId?: string;\n /** The full domain of your Shopify storefront URL (eg: the complete string of `{subdomain}.myshopify.com`). */\n storeDomain: string;\n /** The Storefront API public access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n storefrontToken: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen React was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion: string;\n /**\n * The code designating a country, which generally follows ISO 3166-1 alpha-2 guidelines. If a territory doesn't have a country code value in the `CountryCode` enum, it might be considered a subdivision of another country. For example, the territories associated with Spain are represented by the country code `ES`, and the territories associated with the United States of America are represented by the country code `US`.\n */\n countryIsoCode: CountryCode;\n /**\n * `ISO 369` language codes supported by Shopify.\n */\n languageIsoCode: LanguageCode;\n}\n\n/**\n * Shopify-specific values that are used in various Hydrogen React components and hooks.\n */\nexport interface ShopifyProviderProps extends ShopifyProviderBase {\n /** React children to render. */\n children?: ReactNode;\n}\n\nexport interface ShopifyContextValue\n extends ShopifyProviderBase,\n ShopifyContextReturn {}\n\ntype ShopifyContextReturn = {\n /**\n * Creates the fully-qualified URL to your store's GraphQL endpoint.\n *\n * By default, it will use the config you passed in when creating `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getStorefrontApiUrl({...})`:\n *\n * - `storeDomain`\n * - `storefrontApiVersion`\n */\n getStorefrontApiUrl: (props?: GetStorefrontApiUrlProps) => string;\n /**\n * Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. This uses the public Storefront API token.\n *\n * By default, it will use the config you passed in when creating `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getPublicTokenHeaders({...})`:\n *\n * - `contentType`\n * - `storefrontToken`\n *\n */\n getPublicTokenHeaders: (\n props: GetPublicTokenHeadersProps,\n ) => Record<string, string>;\n /**\n * Creates the fully-qualified URL to your myshopify.com domain.\n *\n * By default, it will use the config you passed in when calling `<ShopifyProvider/>`. However, you can override the following settings on each invocation of `getShopifyDomain({...})`:\n *\n * - `storeDomain`\n */\n getShopifyDomain: (props?: GetShopifyDomainProps) => string;\n};\n\ntype GetStorefrontApiUrlProps = {\n /** The host name of the domain (eg: `{shop}.myshopify.com`). */\n storeDomain?: string;\n /** The Storefront API version. This should almost always be the same as the version Hydrogen-UI was built for. Learn more about Shopify [API versioning](https://shopify.dev/api/usage/versioning) for more details. */\n storefrontApiVersion?: string;\n};\n\ntype GetPublicTokenHeadersProps = {\n /**\n * Customizes which `\"content-type\"` header is added when using `getPrivateTokenHeaders()` and `getPublicTokenHeaders()`. When fetching with a `JSON.stringify()`-ed `body`, use `\"json\"`. When fetching with a `body` that is a plain string, use `\"graphql\"`. Defaults to `\"json\"`\n */\n contentType: 'json' | 'graphql';\n /** The Storefront API access token. Refer to the [authentication](https://shopify.dev/api/storefront#authentication) documentation for more details. */\n storefrontToken?: string;\n};\n\ntype GetShopifyDomainProps = {storeDomain?: string};\n","export const CART_ID_STORAGE_KEY = 'shopifyCartId';\nexport const CART_COOKIE_TTL_DAYS = 14;\n\n// Needed for cart analytics within Shopify\nexport const SHOPIFY_STOREFRONT_ID_HEADER = 'Shopify-Storefront-Id';\nexport const SHOPIFY_STOREFRONT_Y_HEADER = 'Shopify-Storefront-Y';\nexport const SHOPIFY_STOREFRONT_S_HEADER = 'Shopify-Storefront-S';\nexport const SHOPIFY_Y = '_shopify_y';\nexport const SHOPIFY_S = '_shopify_s';\n","// src/cookie.ts\nvar g = new Set([\n \"domain\",\n \"path\",\n \"max-age\",\n \"expires\",\n \"samesite\",\n \"secure\",\n \"httponly\"\n]);\nfunction u(a) {\n let r = {}, e, t, n = 0, m = a.split(/;\\s*/g), s, i;\n for (; n < m.length; n++)\n if (t = m[n], e = t.indexOf(\"=\"), ~e) {\n if (s = t.substring(0, e++).trim(), i = t.substring(e).trim(), i[0] === '\"' && (i = i.substring(1, i.length - 1)), ~i.indexOf(\"%\"))\n try {\n i = decodeURIComponent(i);\n } catch (f) {\n }\n g.has(t = s.toLowerCase()) ? t === \"expires\" ? r.expires = new Date(i) : t === \"max-age\" ? r.maxage = +i : r[t] = i : r[s] = i;\n } else\n (s = t.trim().toLowerCase()) && (s === \"httponly\" || s === \"secure\") && (r[s] = !0);\n return r;\n}\nfunction l(a, r, e = {}) {\n let t = a + \"=\" + encodeURIComponent(r);\n return e.expires && (t += \"; Expires=\" + new Date(e.expires).toUTCString()), e.maxage != null && e.maxage >= 0 && (t += \"; Max-Age=\" + (e.maxage | 0)), e.domain && (t += \"; Domain=\" + e.domain), e.path && (t += \"; Path=\" + e.path), e.samesite && (t += \"; SameSite=\" + e.samesite), (e.secure || e.samesite === \"None\") && (t += \"; Secure\"), e.httponly && (t += \"; HttpOnly\"), t;\n}\nexport {\n u as parse,\n l as stringify\n};\n","import {parse} from 'worktop/cookie';\nimport {ShopifyCookies} from './analytics-types.js';\nimport {SHOPIFY_Y, SHOPIFY_S} from './cart-constants.js';\n\nconst tokenHash = 'xxxx-4xxx-xxxx-xxxxxxxxxxxx';\n\nexport function buildUUID(): string {\n let hash = '';\n\n try {\n const crypto: Crypto = window.crypto;\n const randomValuesArray = new Uint16Array(31);\n crypto.getRandomValues(randomValuesArray);\n\n // Generate a strong UUID\n let i = 0;\n hash = tokenHash\n .replace(/[x]/g, (c: string): string => {\n const r = randomValuesArray[i] % 16;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n i++;\n return v.toString(16);\n })\n .toUpperCase();\n } catch (err) {\n // crypto not available, generate weak UUID\n hash = tokenHash\n .replace(/[x]/g, (c: string): string => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n })\n .toUpperCase();\n }\n\n return `${hexTime()}-${hash}`;\n}\n\nexport function hexTime(): string {\n // 32 bit representations of new Date().getTime() and performance.now()\n let dateNumber = 0;\n let perfNumber = 0;\n\n // Result of zero-fill right shift is always positive\n dateNumber = new Date().getTime() >>> 0;\n\n try {\n perfNumber = performance.now() >>> 0;\n } catch (err) {\n perfNumber = 0;\n }\n\n const output = Math.abs(dateNumber + perfNumber)\n .toString(16)\n .toLowerCase();\n\n // Ensure the output is exactly 8 characters\n return output.padStart(8, '0');\n}\n\nexport function getShopifyCookies(cookies: string): ShopifyCookies {\n const cookieData = parse(cookies);\n return {\n [SHOPIFY_Y]: cookieData[SHOPIFY_Y] || '',\n [SHOPIFY_S]: cookieData[SHOPIFY_S] || '',\n };\n}\n","import {useState, useCallback} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport {CartInput, Cart as CartType} from './storefront-api-types.js';\nimport {CartCreate, defaultCartFragment} from './cart-queries.js';\nimport {Cart} from './cart-types.js';\nimport {\n SHOPIFY_STOREFRONT_ID_HEADER,\n SHOPIFY_STOREFRONT_Y_HEADER,\n SHOPIFY_STOREFRONT_S_HEADER,\n SHOPIFY_Y,\n SHOPIFY_S,\n} from './cart-constants.js';\nimport type {StorefrontApiResponseOkPartial} from './storefront-api-response.types.js';\nimport {getShopifyCookies} from './cookies-utils.js';\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartFetch() {\n const {storefrontId, getPublicTokenHeaders, getStorefrontApiUrl} = useShop();\n\n return useCallback(\n <ReturnDataGeneric,>({\n query,\n variables,\n }: {\n query: string;\n variables: Record<string, unknown>;\n }): Promise<StorefrontApiResponseOkPartial<ReturnDataGeneric>> => {\n const headers = getPublicTokenHeaders({contentType: 'json'});\n\n if (storefrontId) {\n headers[SHOPIFY_STOREFRONT_ID_HEADER] = storefrontId;\n }\n\n // Find Shopify cookies\n const cookieData = getShopifyCookies(document.cookie);\n headers[SHOPIFY_STOREFRONT_Y_HEADER] = cookieData[SHOPIFY_Y];\n headers[SHOPIFY_STOREFRONT_S_HEADER] = cookieData[SHOPIFY_S];\n\n return fetch(getStorefrontApiUrl(), {\n method: 'POST',\n headers,\n body: JSON.stringify({\n query: query.toString(),\n variables,\n }),\n })\n .then(\n (res) =>\n res.json() as StorefrontApiResponseOkPartial<ReturnDataGeneric>,\n )\n .catch((error) => {\n return {\n data: undefined,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n errors: error?.toString(),\n };\n });\n },\n [getPublicTokenHeaders, storefrontId, getStorefrontApiUrl],\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useInstantCheckout() {\n const [cart, updateCart] = useState<Cart | undefined>();\n const [checkoutUrl, updateCheckoutUrl] = useState<Cart['checkoutUrl']>();\n const [error, updateError] = useState<string | undefined>();\n\n const fetch = useCartFetch();\n\n const createInstantCheckout = useCallback(\n async (cartInput: CartInput) => {\n const {data, errors} = await fetch<{\n cartCreate: {cart: CartType};\n }>({\n query: CartCreate(defaultCartFragment),\n variables: {\n input: cartInput,\n },\n });\n\n if (errors) {\n updateError(errors.toString());\n updateCart(undefined);\n updateCheckoutUrl(undefined);\n }\n\n if (data?.cartCreate?.cart) {\n const dataCart = data.cartCreate.cart;\n updateCart({\n ...dataCart,\n lines: flattenConnection(dataCart.lines),\n note: dataCart.note ?? undefined,\n });\n updateCheckoutUrl(dataCart.checkoutUrl);\n }\n },\n [fetch],\n );\n\n return {cart, checkoutUrl, error, createInstantCheckout};\n}\n","import {useCallback, useMemo} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n LanguageCode,\n Cart as CartType,\n MutationCartDiscountCodesUpdateArgs,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n CartAttributesUpdate,\n CartBuyerIdentityUpdate,\n CartCreate,\n CartDiscountCodesUpdate,\n CartLineAdd,\n CartLineRemove,\n CartLineUpdate,\n CartNoteUpdate,\n CartQuery,\n} from './cart-queries.js';\nimport {useCartFetch} from './cart-hooks.js';\nimport {PartialDeep} from 'type-fest';\n\ntype CartResponse = PartialDeep<CartType, {recurseIntoArrays: true}>;\n\n/**\n * The `useCartActions` hook returns helper graphql functions for Storefront Cart API\n *\n * See [cart API graphql mutations](https://shopify.dev/api/storefront/2025-01/objects/Cart)\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartActions({\n numCartLines,\n cartFragment,\n countryCode = 'US',\n languageCode = 'EN',\n}: {\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2025-01/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment: string;\n /** The ISO country code for i18n. Default to `US` */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. Default to `EN` */\n languageCode?: LanguageCode;\n}) {\n const fetchCart = useCartFetch();\n\n const cartFetch = useCallback(\n (cartId: string) => {\n return fetchCart<{cart: CartResponse}>({\n query: CartQuery(cartFragment),\n variables: {\n id: cartId,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [fetchCart, cartFragment, numCartLines, countryCode, languageCode],\n );\n\n const cartCreate = useCallback(\n (cart: CartInput) => {\n return fetchCart<{cartCreate: {cart: CartResponse}}>({\n query: CartCreate(cartFragment),\n variables: {\n input: cart,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineAdd = useCallback(\n (cartId: string, lines: CartLineInput[]) => {\n return fetchCart<{cartLinesAdd: {cart: CartResponse}}>({\n query: CartLineAdd(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineUpdate = useCallback(\n (cartId: string, lines: CartLineUpdateInput[]) => {\n return fetchCart<{cartLinesUpdate: {cart: CartResponse}}>({\n query: CartLineUpdate(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartLineRemove = useCallback(\n (cartId: string, lines: string[]) => {\n return fetchCart<{cartLinesRemove: {cart: CartResponse}}>({\n query: CartLineRemove(cartFragment),\n variables: {\n cartId,\n lines,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const noteUpdate = useCallback(\n (cartId: string, note: MutationCartNoteUpdateArgs['note']) => {\n return fetchCart<{cartNoteUpdate: {cart: CartResponse}}>({\n query: CartNoteUpdate(cartFragment),\n variables: {\n cartId,\n note,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [fetchCart, cartFragment, numCartLines, countryCode, languageCode],\n );\n\n const buyerIdentityUpdate = useCallback(\n (cartId: string, buyerIdentity: CartBuyerIdentityInput) => {\n return fetchCart<{cartBuyerIdentityUpdate: {cart: CartResponse}}>({\n query: CartBuyerIdentityUpdate(cartFragment),\n variables: {\n cartId,\n buyerIdentity,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const cartAttributesUpdate = useCallback(\n (cartId: string, attributes: AttributeInput[]) => {\n return fetchCart<{cartAttributesUpdate: {cart: CartResponse}}>({\n query: CartAttributesUpdate(cartFragment),\n variables: {\n cartId,\n attributes,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n const discountCodesUpdate = useCallback(\n (\n cartId: string,\n discountCodes: MutationCartDiscountCodesUpdateArgs['discountCodes'],\n ) => {\n return fetchCart<{cartDiscountCodesUpdate: {cart: CartResponse}}>({\n query: CartDiscountCodesUpdate(cartFragment),\n variables: {\n cartId,\n discountCodes,\n numCartLines,\n country: countryCode,\n language: languageCode,\n },\n });\n },\n [cartFragment, countryCode, fetchCart, numCartLines, languageCode],\n );\n\n return useMemo(\n () => ({\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n cartFragment,\n }),\n [\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n cartFragment,\n ],\n );\n}\n","import {useMachine} from '@xstate/react/fsm';\nimport {createMachine, assign, StateMachine} from '@xstate/fsm';\nimport {\n Cart,\n CartMachineActionEvent,\n CartMachineActions,\n CartMachineContext,\n CartMachineEvent,\n CartMachineFetchResultEvent,\n CartMachineTypeState,\n} from './cart-types.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport {useCartActions} from './useCartActions.js';\nimport {useMemo} from 'react';\nimport {InitEvent} from '@xstate/fsm/lib/types.js';\nimport {\n CountryCode,\n Cart as CartType,\n LanguageCode,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nfunction invokeCart(\n action: keyof CartMachineActions,\n options?: {\n entryActions?: [keyof CartMachineActions];\n resolveTarget?: CartMachineTypeState['value'];\n errorTarget?: CartMachineTypeState['value'];\n exitActions?: [keyof CartMachineActions];\n },\n): StateMachine.Config<CartMachineContext, CartMachineEvent>['states']['on'] {\n return {\n entry: [\n ...(options?.entryActions || []),\n assign({\n lastValidCart: (context) => context?.cart,\n }),\n 'onCartActionEntry',\n 'onCartActionOptimisticUI',\n action,\n ],\n on: {\n RESOLVE: {\n target: options?.resolveTarget || 'idle',\n actions: [\n assign({\n prevCart: (context) => context?.lastValidCart,\n cart: (_, event) => event?.payload?.cart,\n rawCartResult: (_, event) => event?.payload?.rawCartResult,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n errors: (_) => undefined,\n }),\n ],\n },\n ERROR: {\n target: options?.errorTarget || 'error',\n actions: [\n assign({\n prevCart: (context) => context?.lastValidCart,\n cart: (context) => context?.lastValidCart,\n errors: (_, event) => event?.payload?.errors,\n }),\n ],\n },\n CART_COMPLETED: {\n target: 'cartCompleted',\n actions: assign({\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n prevCart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n cart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n lastValidCart: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n rawCartResult: (_) => undefined,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n errors: (_) => undefined,\n }),\n },\n },\n exit: ['onCartActionComplete', ...(options?.exitActions || [])],\n };\n}\n\nconst INITIALIZING_CART_EVENTS: StateMachine.Machine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n>['config']['states']['uninitialized']['on'] = {\n CART_FETCH: {\n target: 'cartFetching',\n },\n CART_CREATE: {\n target: 'cartCreating',\n },\n CART_SET: {\n target: 'idle',\n actions: [\n assign({\n rawCartResult: (_, event) => event.payload.cart,\n cart: (_, event) => cartFromGraphQL(event.payload.cart),\n }),\n ],\n },\n};\n\nconst UPDATING_CART_EVENTS: StateMachine.Machine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n>['config']['states']['idle']['on'] = {\n CARTLINE_ADD: {\n target: 'cartLineAdding',\n },\n CARTLINE_UPDATE: {\n target: 'cartLineUpdating',\n },\n CARTLINE_REMOVE: {\n target: 'cartLineRemoving',\n },\n NOTE_UPDATE: {\n target: 'noteUpdating',\n },\n BUYER_IDENTITY_UPDATE: {\n target: 'buyerIdentityUpdating',\n },\n CART_ATTRIBUTES_UPDATE: {\n target: 'cartAttributesUpdating',\n },\n DISCOUNT_CODES_UPDATE: {\n target: 'discountCodesUpdating',\n },\n};\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction createCartMachine(\n initialCart?: PartialDeep<CartType, {recurseIntoArrays: true}>,\n) {\n return createMachine<\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState\n >({\n id: 'Cart',\n initial: initialCart ? 'idle' : 'uninitialized',\n context: {\n cart: initialCart && cartFromGraphQL(initialCart),\n },\n states: {\n uninitialized: {\n on: INITIALIZING_CART_EVENTS,\n },\n cartCompleted: {\n on: INITIALIZING_CART_EVENTS,\n },\n initializationError: {\n on: INITIALIZING_CART_EVENTS,\n },\n idle: {\n on: {...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS},\n },\n error: {\n on: {...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS},\n },\n cartFetching: invokeCart('cartFetchAction', {\n errorTarget: 'initializationError',\n }),\n cartCreating: invokeCart('cartCreateAction', {\n errorTarget: 'initializationError',\n }),\n cartLineRemoving: invokeCart('cartLineRemoveAction'),\n cartLineUpdating: invokeCart('cartLineUpdateAction'),\n cartLineAdding: invokeCart('cartLineAddAction'),\n noteUpdating: invokeCart('noteUpdateAction'),\n buyerIdentityUpdating: invokeCart('buyerIdentityUpdateAction'),\n cartAttributesUpdating: invokeCart('cartAttributesUpdateAction'),\n discountCodesUpdating: invokeCart('discountCodesUpdateAction'),\n },\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function useCartAPIStateMachine({\n numCartLines,\n onCartActionEntry,\n onCartActionOptimisticUI,\n onCartActionComplete,\n data: cart,\n cartFragment,\n countryCode,\n languageCode,\n}: {\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked just before a Cart API action executes. */\n onCartActionEntry?: (\n context: CartMachineContext,\n event: CartMachineActionEvent,\n ) => void;\n /** A callback that is invoked after executing the entry actions for optimistic UI changes. */\n onCartActionOptimisticUI?: (\n context: CartMachineContext,\n event: CartMachineEvent,\n ) => Partial<CartMachineContext>;\n /** A callback that is invoked after a Cart API completes. */\n onCartActionComplete?: (\n context: CartMachineContext,\n event: CartMachineFetchResultEvent,\n ) => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/2025-01/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2025-01/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment: string;\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. */\n languageCode?: LanguageCode;\n}) {\n const {\n cartFetch,\n cartCreate,\n cartLineAdd,\n cartLineUpdate,\n cartLineRemove,\n noteUpdate,\n buyerIdentityUpdate,\n cartAttributesUpdate,\n discountCodesUpdate,\n } = useCartActions({\n numCartLines,\n cartFragment,\n countryCode,\n languageCode,\n });\n\n const cartMachine = useMemo(() => createCartMachine(cart), [cart]);\n\n const [state, send, service] = useMachine(cartMachine, {\n actions: {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartFetchAction: async (_, event) => {\n if (event.type !== 'CART_FETCH') return;\n\n const {data, errors} = await cartFetch(event?.payload?.cartId);\n const resultEvent = eventFromFetchResult(event, data?.cart, errors);\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartCreateAction: async (_, event) => {\n if (event.type !== 'CART_CREATE') return;\n\n const {data, errors} = await cartCreate(event?.payload);\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartCreate?.cart,\n errors,\n );\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineAddAction: async (context, event) => {\n if (event.type !== 'CARTLINE_ADD' || !context?.cart?.id) return;\n\n const {data, errors} = await cartLineAdd(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesAdd?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineUpdateAction: async (context, event) => {\n if (event.type !== 'CARTLINE_UPDATE' || !context?.cart?.id) return;\n const {data, errors} = await cartLineUpdate(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartLineRemoveAction: async (context, event) => {\n if (event.type !== 'CARTLINE_REMOVE' || !context?.cart?.id) return;\n const {data, errors} = await cartLineRemove(\n context.cart.id,\n event.payload.lines,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartLinesRemove?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n noteUpdateAction: async (context, event) => {\n if (event.type !== 'NOTE_UPDATE' || !context?.cart?.id) return;\n const {data, errors} = await noteUpdate(\n context.cart.id,\n event.payload.note,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartNoteUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n buyerIdentityUpdateAction: async (context, event) => {\n if (event.type !== 'BUYER_IDENTITY_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await buyerIdentityUpdate(\n context.cart.id,\n event.payload.buyerIdentity,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartBuyerIdentityUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n cartAttributesUpdateAction: async (context, event) => {\n if (event.type !== 'CART_ATTRIBUTES_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await cartAttributesUpdate(\n context.cart.id,\n event.payload.attributes,\n );\n\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartAttributesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n discountCodesUpdateAction: async (context, event) => {\n if (event.type !== 'DISCOUNT_CODES_UPDATE' || !context?.cart?.id)\n return;\n const {data, errors} = await discountCodesUpdate(\n context.cart.id,\n event.payload.discountCodes,\n );\n const resultEvent = eventFromFetchResult(\n event,\n data?.cartDiscountCodesUpdate?.cart,\n errors,\n );\n\n send(resultEvent);\n },\n ...(onCartActionEntry && {\n onCartActionEntry: (context, event): void => {\n if (isCartActionEvent(event)) {\n onCartActionEntry(context, event);\n }\n },\n }),\n ...(onCartActionOptimisticUI && {\n onCartActionOptimisticUI: assign((context, event) => {\n return onCartActionOptimisticUI(context, event);\n }),\n }),\n ...(onCartActionComplete && {\n onCartActionComplete: (context, event): void => {\n if (isCartFetchResultEvent(event)) {\n onCartActionComplete(context, event);\n }\n },\n }),\n } as CartMachineActions,\n });\n\n return useMemo(() => [state, send, service] as const, [state, send, service]);\n}\n\nexport function cartFromGraphQL(\n cart: PartialDeep<CartType, {recurseIntoArrays: true}>,\n): Cart {\n return {\n ...cart,\n lines: flattenConnection(cart?.lines),\n note: cart.note ?? undefined,\n };\n}\n\nfunction eventFromFetchResult(\n cartActionEvent: CartMachineActionEvent,\n cart?: PartialDeep<CartType, {recurseIntoArrays: true}> | null,\n errors?: unknown,\n): CartMachineFetchResultEvent {\n if (errors) {\n return {type: 'ERROR', payload: {errors, cartActionEvent}};\n }\n\n if (!cart) {\n return {\n type: 'CART_COMPLETED',\n payload: {\n cartActionEvent,\n },\n };\n }\n\n return {\n type: 'RESOLVE',\n payload: {\n cart: cartFromGraphQL(cart),\n rawCartResult: cart,\n cartActionEvent,\n },\n };\n}\n\nfunction isCartActionEvent(\n event: CartMachineEvent | InitEvent,\n): event is CartMachineActionEvent {\n return (\n event.type === 'CART_CREATE' ||\n event.type === 'CARTLINE_ADD' ||\n event.type === 'CARTLINE_UPDATE' ||\n event.type === 'CARTLINE_REMOVE' ||\n event.type === 'NOTE_UPDATE' ||\n event.type === 'BUYER_IDENTITY_UPDATE' ||\n event.type === 'CART_ATTRIBUTES_UPDATE' ||\n event.type === 'DISCOUNT_CODES_UPDATE'\n );\n}\n\nfunction isCartFetchResultEvent(\n event: CartMachineEvent | InitEvent,\n): event is CartMachineFetchResultEvent {\n return (\n event.type === 'RESOLVE' ||\n event.type === 'ERROR' ||\n event.type === 'CART_COMPLETED'\n );\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n createContext,\n useContext,\n} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n LanguageCode,\n Cart as CartType,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n BuyerIdentityUpdateEvent,\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState,\n CartWithActions,\n CartWithActionsDocs,\n} from './cart-types.js';\nimport {useCartAPIStateMachine} from './useCartAPIStateMachine.js';\nimport {CART_ID_STORAGE_KEY} from './cart-constants.js';\nimport {PartialDeep} from 'type-fest';\nimport {defaultCartFragment} from './cart-queries.js';\nimport {useShop} from './ShopifyProvider.js';\n\nexport const CartContext = createContext<CartWithActions | null>(null);\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype UseCartDocs = () => CartWithActionsDocs;\n\n/**\n * The `useCart` hook provides access to the cart object. It must be a descendent of a `CartProvider` component.\n */\nexport function useCart(): CartWithActions {\n const context = useContext(CartContext);\n\n if (!context) {\n throw new Error('Expected a Cart Context, but no Cart Context was found');\n }\n\n return context;\n}\n\ntype CartProviderProps = {\n /** Any `ReactNode` elements. */\n children: React.ReactNode;\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. */\n onCreate?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. */\n onLineAdd?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. */\n onLineRemove?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. */\n onLineUpdate?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. */\n onNoteUpdate?: () => void;\n /** A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. */\n onBuyerIdentityUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. */\n onAttributesUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. */\n onDiscountCodesUpdate?: () => void;\n /** A callback that is invoked when the process to create a cart completes */\n onCreateComplete?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart completes */\n onLineAddComplete?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart completes */\n onLineRemoveComplete?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart completes */\n onLineUpdateComplete?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart completes */\n onNoteUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the buyer identity completes */\n onBuyerIdentityUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart attributes completes */\n onAttributesUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes completes */\n onDiscountCodesUpdateComplete?: () => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/2025-01/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2025-01/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment?: string;\n /** A customer access token that's accessible on the server if there's a customer login. */\n customerAccessToken?: CartBuyerIdentityInput['customerAccessToken'];\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n /** The ISO language code for i18n. */\n languageCode?: LanguageCode;\n};\n\n/**\n * The `CartProvider` component synchronizes the state of the Storefront API Cart and a customer's cart,\n * and allows you to more easily manipulate the cart by adding, removing, and updating it.\n * It could be placed at the root of your app so that your whole app is able to use the `useCart()` hook anywhere.\n *\n * There are props that trigger when a call to the Storefront API is made, such as `onLineAdd={}` when a line is added to the cart.\n * There are also props that trigger when a call to the Storefront API is completed, such as `onLineAddComplete={}` when the fetch request for adding a line to the cart completes.\n *\n * The `CartProvider` component must be a descendant of the `ShopifyProvider` component.\n */\nexport function CartProvider({\n children,\n numCartLines,\n onCreate,\n onLineAdd,\n onLineRemove,\n onLineUpdate,\n onNoteUpdate,\n onBuyerIdentityUpdate,\n onAttributesUpdate,\n onDiscountCodesUpdate,\n onCreateComplete,\n onLineAddComplete,\n onLineRemoveComplete,\n onLineUpdateComplete,\n onNoteUpdateComplete,\n onBuyerIdentityUpdateComplete,\n onAttributesUpdateComplete,\n onDiscountCodesUpdateComplete,\n data: cart,\n cartFragment = defaultCartFragment,\n customerAccessToken,\n countryCode,\n languageCode,\n}: CartProviderProps): JSX.Element {\n const shop = useShop();\n\n if (!shop)\n throw new Error(\n '<CartProvider> needs to be a descendant of <ShopifyProvider>',\n );\n\n countryCode = (\n (countryCode as string) ??\n shop.countryIsoCode ??\n 'US'\n ).toUpperCase() as CountryCode;\n\n languageCode = (\n (languageCode as string) ??\n shop.languageIsoCode ??\n 'EN'\n ).toUpperCase() as LanguageCode;\n\n if (countryCode) countryCode = countryCode.toUpperCase() as CountryCode;\n\n const [prevCountryCode, setPrevCountryCode] = useState(countryCode);\n const [prevCustomerAccessToken, setPrevCustomerAccessToken] =\n useState(customerAccessToken);\n const customerOverridesCountryCode = useRef(false);\n\n if (\n prevCountryCode !== countryCode ||\n prevCustomerAccessToken !== customerAccessToken\n ) {\n setPrevCountryCode(countryCode);\n setPrevCustomerAccessToken(customerAccessToken);\n customerOverridesCountryCode.current = false;\n }\n\n const [cartState, cartSend] = useCartAPIStateMachine({\n numCartLines,\n data: cart,\n cartFragment,\n countryCode,\n languageCode,\n onCartActionEntry(_, event) {\n try {\n switch (event.type) {\n case 'CART_CREATE':\n return onCreate?.();\n case 'CARTLINE_ADD':\n return onLineAdd?.();\n case 'CARTLINE_REMOVE':\n return onLineRemove?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdate?.();\n case 'NOTE_UPDATE':\n return onNoteUpdate?.();\n case 'BUYER_IDENTITY_UPDATE':\n return onBuyerIdentityUpdate?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdate?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdate?.();\n }\n } catch (error) {\n console.error('Cart entry action failed', error);\n }\n },\n onCartActionOptimisticUI(context, event) {\n if (!context.cart) return {...context};\n switch (event.type) {\n case 'CARTLINE_REMOVE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.filter(\n (line) => line?.id && !event.payload.lines.includes(line?.id),\n ),\n },\n };\n case 'CARTLINE_UPDATE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.map((line) => {\n const updatedLine = event.payload.lines.find(\n ({id}) => id === line?.id,\n );\n\n if (updatedLine && updatedLine.quantity) {\n return {\n ...line,\n quantity: updatedLine.quantity,\n };\n }\n\n return line;\n }),\n },\n };\n }\n return {...context};\n },\n onCartActionComplete(context, event) {\n const cartActionEvent = event.payload.cartActionEvent;\n try {\n switch (event.type) {\n case 'RESOLVE':\n switch (cartActionEvent.type) {\n case 'CART_CREATE':\n return onCreateComplete?.();\n case 'CARTLINE_ADD':\n return onLineAddComplete?.();\n case 'CARTLINE_REMOVE':\n return onLineRemoveComplete?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdateComplete?.();\n case 'NOTE_UPDATE':\n return onNoteUpdateComplete?.();\n case 'BUYER_IDENTITY_UPDATE':\n if (countryCodeNotUpdated(context, cartActionEvent)) {\n customerOverridesCountryCode.current = true;\n }\n return onBuyerIdentityUpdateComplete?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdateComplete?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdateComplete?.();\n }\n }\n } catch (error) {\n console.error('onCartActionComplete failed', error);\n }\n },\n });\n\n const cartReady = useRef(false);\n const [isCartReady, setIsCartReady] = useState(false);\n const cartCompleted = cartState.matches('cartCompleted');\n\n const countryChanged =\n (cartState.value === 'idle' ||\n cartState.value === 'error' ||\n cartState.value === 'cartCompleted') &&\n countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&\n !cartState.context.errors;\n\n const fetchingFromStorage = useRef(false);\n\n /**\n * Initializes cart with priority in this order:\n * 1. cart props\n * 2. localStorage cartId\n */\n useEffect(() => {\n if (!cartReady.current && !fetchingFromStorage.current) {\n if (!cart && storageAvailable('localStorage')) {\n fetchingFromStorage.current = true;\n try {\n const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);\n if (cartId) {\n cartSend({type: 'CART_FETCH', payload: {cartId}});\n }\n } catch (error) {\n console.warn('error fetching cartId');\n console.warn(error);\n }\n }\n cartReady.current = true;\n // Providing a separate cart ready state variable to avoid re-renders in this logic while still being able to pass the reactive status through context.\n setIsCartReady(true);\n }\n }, [cart, cartReady, cartSend]);\n\n // Update cart country code if cart and props countryCode's as different\n useEffect(() => {\n if (!countryChanged || customerOverridesCountryCode.current) return;\n cartSend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {buyerIdentity: {countryCode, customerAccessToken}},\n });\n }, [\n countryCode,\n customerAccessToken,\n countryChanged,\n customerOverridesCountryCode,\n cartSend,\n ]);\n\n // send cart events when ready\n const onCartReadySend = useCallback(\n (cartEvent: CartMachineEvent) => {\n if (!cartReady.current) {\n return console.warn(\"Cart isn't ready yet\");\n }\n cartSend(cartEvent);\n },\n [cartSend],\n );\n\n // save cart id to local storage\n useEffect(() => {\n if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {\n try {\n window.localStorage.setItem(\n CART_ID_STORAGE_KEY,\n cartState.context.cart?.id,\n );\n } catch (error) {\n console.warn('Failed to save cartId to localStorage', error);\n }\n }\n }, [cartState?.context?.cart?.id]);\n\n // delete cart from local storage if cart fetched has been completed\n useEffect(() => {\n if (cartCompleted && storageAvailable('localStorage')) {\n try {\n window.localStorage.removeItem(CART_ID_STORAGE_KEY);\n } catch (error) {\n console.warn('Failed to delete cartId from localStorage', error);\n }\n }\n }, [cartCompleted]);\n\n const cartCreate = useCallback(\n (cartInput: CartInput) => {\n if (countryCode && !cartInput.buyerIdentity?.countryCode) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.countryCode = countryCode;\n }\n\n if (\n customerAccessToken &&\n !cartInput.buyerIdentity?.customerAccessToken\n ) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.customerAccessToken = customerAccessToken;\n }\n onCartReadySend({\n type: 'CART_CREATE',\n payload: cartInput,\n });\n },\n [countryCode, customerAccessToken, onCartReadySend],\n );\n\n // Delays the cart state in the context if the page is hydrating\n // preventing suspense boundary errors.\n const cartDisplayState = useDelayedStateUntilHydration(cartState);\n\n const cartContextValue = useMemo<CartWithActions>(() => {\n return {\n ...(cartDisplayState?.context?.cart ?? {lines: [], attributes: []}),\n status: transposeStatus(cartDisplayState.value),\n error: cartDisplayState?.context?.errors,\n totalQuantity: cartDisplayState?.context?.cart?.totalQuantity ?? 0,\n cartCreate,\n cartReady: isCartReady,\n linesAdd(lines: CartLineInput[]): void {\n if (cartDisplayState?.context?.cart?.id) {\n onCartReadySend({\n type: 'CARTLINE_ADD',\n payload: {lines},\n });\n } else {\n cartCreate({lines});\n }\n },\n linesRemove(lines: string[]): void {\n onCartReadySend({\n type: 'CARTLINE_REMOVE',\n payload: {\n lines,\n },\n });\n },\n linesUpdate(lines: CartLineUpdateInput[]): void {\n onCartReadySend({\n type: 'CARTLINE_UPDATE',\n payload: {\n lines,\n },\n });\n },\n noteUpdate(note: MutationCartNoteUpdateArgs['note']): void {\n onCartReadySend({\n type: 'NOTE_UPDATE',\n payload: {\n note,\n },\n });\n },\n buyerIdentityUpdate(buyerIdentity: CartBuyerIdentityInput): void {\n onCartReadySend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {\n buyerIdentity,\n },\n });\n },\n cartAttributesUpdate(attributes: AttributeInput[]): void {\n onCartReadySend({\n type: 'CART_ATTRIBUTES_UPDATE',\n payload: {\n attributes,\n },\n });\n },\n discountCodesUpdate(discountCodes: string[]): void {\n onCartReadySend({\n type: 'DISCOUNT_CODES_UPDATE',\n payload: {\n discountCodes,\n },\n });\n },\n cartFragment,\n };\n }, [\n cartCreate,\n isCartReady,\n cartDisplayState?.context?.cart,\n cartDisplayState?.context?.errors,\n cartDisplayState.value,\n cartFragment,\n onCartReadySend,\n ]);\n\n return (\n <CartContext.Provider value={cartContextValue}>\n {children}\n </CartContext.Provider>\n );\n}\n\nfunction transposeStatus(\n status: CartMachineTypeState['value'],\n): CartWithActions['status'] {\n switch (status) {\n case 'uninitialized':\n case 'initializationError':\n return 'uninitialized';\n case 'idle':\n case 'cartCompleted':\n case 'error':\n return 'idle';\n case 'cartFetching':\n return 'fetching';\n case 'cartCreating':\n return 'creating';\n case 'cartLineAdding':\n case 'cartLineRemoving':\n case 'cartLineUpdating':\n case 'noteUpdating':\n case 'buyerIdentityUpdating':\n case 'cartAttributesUpdating':\n case 'discountCodesUpdating':\n return 'updating';\n }\n}\n\n/**\n * Delays a state update until hydration finishes. Useful for preventing suspense boundaries errors when updating a context\n * @remarks this uses startTransition and waits for it to finish.\n */\nfunction useDelayedStateUntilHydration<T>(state: T): T {\n const [isPending, startTransition] = useTransition();\n const [delayedState, setDelayedState] = useState(state);\n\n const firstTimePending = useRef(false);\n if (isPending) {\n firstTimePending.current = true;\n }\n\n const firstTimePendingFinished = useRef(false);\n if (!isPending && firstTimePending.current) {\n firstTimePendingFinished.current = true;\n }\n\n useEffect(() => {\n startTransition(() => {\n if (!firstTimePendingFinished.current) {\n setDelayedState(state);\n }\n });\n }, [state]);\n\n const displayState = firstTimePendingFinished.current ? state : delayedState;\n\n return displayState;\n}\n\n/**\n * Check for storage availability function obtained from\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API\n */\nexport function storageAvailable(\n type: 'localStorage' | 'sessionStorage',\n): boolean {\n let storage;\n try {\n storage = window[type];\n const x = '__storage_test__';\n storage.setItem(x, x);\n storage.removeItem(x);\n return true;\n } catch (e) {\n return !!(\n e instanceof DOMException &&\n // everything except Firefox\n (e.code === 22 ||\n // Firefox\n e.code === 1014 ||\n // test name field too, because code might not be present\n // everything except Firefox\n e.name === 'QuotaExceededError' ||\n // Firefox\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&\n // acknowledge QuotaExceededError only if there's something already stored\n storage &&\n storage.length !== 0\n );\n }\n}\n\nfunction countryCodeNotUpdated(\n context: CartMachineContext,\n event: BuyerIdentityUpdateEvent,\n): boolean {\n return !!(\n event.payload.buyerIdentity.countryCode &&\n context.cart?.buyerIdentity?.countryCode !==\n event.payload.buyerIdentity.countryCode\n );\n}\n","import {\n useMemo,\n useState,\n useEffect,\n useCallback,\n createContext,\n useContext,\n} from 'react';\nimport type {\n SelectedOption as SelectedOptionType,\n SellingPlan,\n SellingPlanAllocation,\n Product,\n ProductVariant as ProductVariantType,\n ProductVariantConnection,\n SellingPlan as SellingPlanType,\n SellingPlanAllocation as SellingPlanAllocationType,\n SellingPlanGroup as SellingPlanGroupType,\n SellingPlanGroupConnection,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\n\nconst ProductOptionsContext = createContext<ProductHookValue | null>(null);\n\ntype InitialVariantId = ProductVariantType['id'] | null;\n\ninterface ProductProviderProps {\n /** A Storefront API [Product object](https://shopify.dev/api/storefront/reference/products/product). */\n data: PartialDeep<Product, {recurseIntoArrays: true}>;\n /** A `ReactNode` element. */\n children: React.ReactNode;\n /**\n * The initially selected variant.\n * The following logic applies to `initialVariantId`:\n * 1. If `initialVariantId` is provided, then it's used even if it's out of stock.\n * 2. If `initialVariantId` is provided but is `null`, then no variant is used.\n * 3. If nothing is passed to `initialVariantId` then the first available / in-stock variant is used.\n * 4. If nothing is passed to `initialVariantId` and no variants are in stock, then the first variant is used.\n */\n initialVariantId?: InitialVariantId;\n}\n\n/**\n * `<ProductProvider />` is a context provider that enables use of the `useProduct()` hook.\n *\n * It helps manage selected options and variants for a product.\n */\nexport function ProductProvider({\n children,\n data: product,\n initialVariantId: explicitVariantId,\n}: ProductProviderProps): JSX.Element {\n // The flattened variants\n const variants = useMemo(\n () => flattenConnection(product.variants ?? {}),\n [product.variants],\n );\n\n if (!isProductVariantArray(variants)) {\n throw new Error(\n `<ProductProvider/> requires 'product.variants.nodes' or 'product.variants.edges'`,\n );\n }\n\n // All the options available for a product, based on all the variants\n const options = useMemo(() => getOptions(variants), [variants]);\n\n /**\n * Track the selectedVariant within the provider.\n */\n const [selectedVariant, setSelectedVariant] = useState<\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null\n >(() => getVariantBasedOnIdProp(explicitVariantId, variants));\n\n /**\n * Track the selectedOptions within the provider. If a `initialVariantId`\n * is passed, use that to select initial options.\n */\n const [selectedOptions, setSelectedOptions] = useState<SelectedOptions>(() =>\n getSelectedOptions(selectedVariant),\n );\n\n /**\n * When the initialVariantId changes, we need to make sure we\n * update the selected variant and selected options. If not,\n * then the selected variant and options will reference incorrect\n * values.\n */\n useEffect(() => {\n const newSelectedVariant = getVariantBasedOnIdProp(\n explicitVariantId,\n variants,\n );\n setSelectedVariant(newSelectedVariant);\n setSelectedOptions(getSelectedOptions(newSelectedVariant));\n }, [explicitVariantId, variants]);\n\n /**\n * Allow the developer to select an option.\n */\n const setSelectedOption = useCallback(\n (name: string, value: string) => {\n setSelectedOptions((selectedOptions) => {\n const opts = {...selectedOptions, [name]: value};\n setSelectedVariant(getSelectedVariant(variants, opts));\n return opts;\n });\n },\n [setSelectedOptions, variants],\n );\n\n const isOptionInStock = useCallback(\n (option: string, value: string) => {\n const proposedVariant = getSelectedVariant(variants, {\n ...selectedOptions,\n ...{[option]: value},\n });\n\n return proposedVariant?.availableForSale ?? true;\n },\n [selectedOptions, variants],\n );\n\n const sellingPlanGroups = useMemo(\n () =>\n flattenConnection(product.sellingPlanGroups ?? {}).map(\n (sellingPlanGroup) => ({\n ...sellingPlanGroup,\n sellingPlans: flattenConnection(sellingPlanGroup?.sellingPlans ?? {}),\n }),\n ),\n [product.sellingPlanGroups],\n );\n\n /**\n * Track the selectedSellingPlan within the hook. If `initialSellingPlanId`\n * is passed, use that as an initial value. Look it up from the `selectedVariant`, since\n * that is also a requirement.\n */\n const [selectedSellingPlan, setSelectedSellingPlan] = useState<\n PartialDeep<SellingPlan, {recurseIntoArrays: true}> | undefined\n >(undefined);\n\n const selectedSellingPlanAllocation = useMemo<\n PartialDeep<SellingPlanAllocation, {recurseIntoArrays: true}> | undefined\n >(() => {\n if (!selectedVariant || !selectedSellingPlan) {\n return;\n }\n\n if (\n !selectedVariant.sellingPlanAllocations?.nodes &&\n !selectedVariant.sellingPlanAllocations?.edges\n ) {\n throw new Error(\n `<ProductProvider/>: You must include 'sellingPlanAllocations.nodes' or 'sellingPlanAllocations.edges' in your variants in order to calculate selectedSellingPlanAllocation`,\n );\n }\n\n return flattenConnection(selectedVariant.sellingPlanAllocations).find(\n (allocation) => allocation?.sellingPlan?.id === selectedSellingPlan.id,\n );\n }, [selectedVariant, selectedSellingPlan]);\n\n const value = useMemo<ProductHookValue>(\n () => ({\n product,\n variants,\n variantsConnection: product.variants,\n options,\n selectedVariant,\n setSelectedVariant,\n selectedOptions,\n setSelectedOption,\n setSelectedOptions,\n isOptionInStock,\n selectedSellingPlan,\n setSelectedSellingPlan,\n selectedSellingPlanAllocation,\n sellingPlanGroups,\n sellingPlanGroupsConnection: product.sellingPlanGroups,\n }),\n [\n product,\n isOptionInStock,\n options,\n selectedOptions,\n selectedSellingPlan,\n selectedSellingPlanAllocation,\n selectedVariant,\n sellingPlanGroups,\n setSelectedOption,\n variants,\n ],\n );\n\n return (\n <ProductOptionsContext.Provider value={value}>\n {children}\n </ProductOptionsContext.Provider>\n );\n}\n\n/**\n * Provides access to the context value provided by `<ProductProvider />`. Must be a descendent of `<ProductProvider />`.\n */\nexport function useProduct(): ProductHookValue {\n const context = useContext(ProductOptionsContext);\n\n if (!context) {\n throw new Error(`'useProduct' must be a child of <ProductProvider />`);\n }\n\n return context;\n}\n\nfunction getSelectedVariant(\n variants: PartialDeep<ProductVariantType, {recurseIntoArrays: true}>[],\n choices: SelectedOptions,\n): PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined {\n /**\n * Ensure the user has selected all the required options, not just some.\n */\n if (\n !variants.length ||\n variants?.[0]?.selectedOptions?.length !== Object.keys(choices).length\n ) {\n return;\n }\n\n return variants?.find((variant) => {\n return Object.entries(choices).every(([name, value]) => {\n return variant?.selectedOptions?.some(\n (option) => option?.name === name && option?.value === value,\n );\n });\n });\n}\n\nfunction getOptions(\n variants: PartialDeep<ProductVariantType, {recurseIntoArrays: true}>[],\n): OptionWithValues[] {\n const map = variants.reduce((memo, variant) => {\n if (!variant.selectedOptions) {\n throw new Error(`'getOptions' requires 'variant.selectedOptions'`);\n }\n variant?.selectedOptions?.forEach((opt) => {\n memo[opt?.name ?? ''] = memo[opt?.name ?? ''] || new Set();\n memo[opt?.name ?? ''].add(opt?.value ?? '');\n });\n\n return memo;\n }, {} as Record<string, Set<string>>);\n\n return Object.keys(map).map((option) => {\n return {\n name: option,\n values: Array.from(map[option]),\n };\n });\n}\n\nfunction getVariantBasedOnIdProp(\n explicitVariantId: InitialVariantId | undefined,\n variants: Array<\n PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined\n >,\n):\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null {\n // get the initial variant based on the logic outlined in the comments for 'initialVariantId' above\n // * 1. If `initialVariantId` is provided, then it's used even if it's out of stock.\n if (explicitVariantId) {\n const foundVariant = variants.find(\n (variant) => variant?.id === explicitVariantId,\n );\n if (!foundVariant) {\n console.warn(\n `<ProductProvider/> received a 'initialVariantId' prop, but could not actually find a variant with that ID`,\n );\n }\n return foundVariant;\n }\n // * 2. If `initialVariantId` is provided but is `null`, then no variant is used.\n if (explicitVariantId === null) {\n return null;\n }\n // * 3. If nothing is passed to `initialVariantId` then the first available / in-stock variant is used.\n // * 4. If nothing is passed to `initialVariantId` and no variants are in stock, then the first variant is used.\n if (explicitVariantId === undefined) {\n return variants.find((variant) => variant?.availableForSale) || variants[0];\n }\n}\n\nfunction getSelectedOptions(\n selectedVariant:\n | PartialDeep<ProductVariantType, {recurseIntoArrays: true}>\n | undefined\n | null,\n): SelectedOptions {\n return selectedVariant?.selectedOptions\n ? selectedVariant.selectedOptions.reduce<SelectedOptions>(\n (memo, optionSet) => {\n memo[optionSet?.name ?? ''] = optionSet?.value ?? '';\n return memo;\n },\n {},\n )\n : {};\n}\n\nfunction isProductVariantArray(\n maybeVariantArray:\n | (PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | undefined)[]\n | undefined,\n): maybeVariantArray is PartialDeep<\n ProductVariantType,\n {recurseIntoArrays: true}\n>[] {\n if (!maybeVariantArray || !Array.isArray(maybeVariantArray)) {\n return false;\n }\n\n return true;\n}\n\nexport interface OptionWithValues {\n name: SelectedOptionType['name'];\n values: SelectedOptionType['value'][];\n}\n\ntype UseProductObjects = {\n /** The raw product from the Storefront API */\n product: Product;\n /** An array of the variant `nodes` from the `VariantConnection`. */\n variants: ProductVariantType[];\n variantsConnection?: ProductVariantConnection;\n /** An array of the product's options and values. */\n options: OptionWithValues[];\n /** The selected variant. */\n selectedVariant?: ProductVariantType | null;\n selectedOptions: SelectedOptions;\n /** The selected selling plan. */\n selectedSellingPlan?: SellingPlanType;\n /** The selected selling plan allocation. */\n selectedSellingPlanAllocation?: SellingPlanAllocationType;\n /** The selling plan groups. */\n sellingPlanGroups?: (Omit<SellingPlanGroupType, 'sellingPlans'> & {\n sellingPlans: SellingPlanType[];\n })[];\n sellingPlanGroupsConnection?: SellingPlanGroupConnection;\n};\n\ntype UseProductFunctions = {\n /** A callback to set the selected variant to the variant passed as an argument. */\n setSelectedVariant: (\n variant: PartialDeep<ProductVariantType, {recurseIntoArrays: true}> | null,\n ) => void;\n /** A callback to set the selected option. */\n setSelectedOption: (\n name: SelectedOptionType['name'],\n value: SelectedOptionType['value'],\n ) => void;\n /** A callback to set multiple selected options at once. */\n setSelectedOptions: (options: SelectedOptions) => void;\n /** A callback to set the selected selling plan to the one passed as an argument. */\n setSelectedSellingPlan: (\n sellingPlan: PartialDeep<SellingPlanType, {recurseIntoArrays: true}>,\n ) => void;\n /** A callback that returns a boolean indicating if the option is in stock. */\n isOptionInStock: (\n name: SelectedOptionType['name'],\n value: SelectedOptionType['value'],\n ) => boolean;\n};\n\ntype ProductHookValue = PartialDeep<\n UseProductObjects,\n {recurseIntoArrays: true}\n> &\n UseProductFunctions;\n\nexport type SelectedOptions = {\n [key: string]: string;\n};\n","import {ReactNode, Ref, useCallback} from 'react';\n\nexport interface CustomBaseButtonProps<AsType> {\n /** Provide a React element or component to render as the underlying button. Note: for accessibility compliance, almost always you should use a `button` element, or a component that renders an underlying button. */\n as?: AsType;\n /** Any ReactNode elements. */\n children: ReactNode;\n /** Click event handler. Default behaviour triggers unless prevented */\n onClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => void | boolean;\n /** A default `onClick` behavior */\n defaultOnClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => void | boolean;\n /** A `ref` to the underlying button */\n buttonRef?: Ref<HTMLButtonElement>;\n}\n\nexport type BaseButtonProps<AsType extends React.ElementType> =\n CustomBaseButtonProps<AsType> &\n (AsType extends keyof React.JSX.IntrinsicElements\n ? Omit<\n React.ComponentPropsWithoutRef<AsType>,\n keyof CustomBaseButtonProps<AsType>\n >\n : React.ComponentPropsWithoutRef<AsType>);\n\nexport function BaseButton<AsType extends React.ElementType = 'button'>(\n props: BaseButtonProps<AsType>,\n): JSX.Element {\n const {\n as,\n onClick,\n defaultOnClick,\n children,\n buttonRef,\n ...passthroughProps\n } = props;\n\n const handleOnClick = useCallback(\n (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (onClick) {\n const clickShouldContinue = onClick(event);\n if (\n (typeof clickShouldContinue === 'boolean' &&\n clickShouldContinue === false) ||\n event?.defaultPrevented\n )\n return;\n }\n\n defaultOnClick?.(event);\n },\n [defaultOnClick, onClick],\n );\n\n const Component = as || 'button';\n\n return (\n <Component ref={buttonRef} onClick={handleOnClick} {...passthroughProps}>\n {children}\n </Component>\n );\n}\n","import {useCallback, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {useProduct} from './ProductProvider.js';\nimport {\n BaseButton,\n type CustomBaseButtonProps,\n type BaseButtonProps,\n} from './BaseButton.js';\nimport * as React from 'react';\n\nexport interface AddToCartButtonPropsBase {\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n /** The ID of the variant. */\n variantId?: string | null;\n /** The item quantity. */\n quantity?: number;\n /** The text that is announced by the screen reader when the item is being added to the cart. Used for accessibility purposes only and not displayed on the page. */\n accessibleAddingToCartLabel?: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n}\n\nexport type AddToCartButtonProps<AsType extends React.ElementType = 'button'> =\n AddToCartButtonPropsBase & BaseButtonProps<AsType>;\n\n/**\n * The `AddToCartButton` component renders a button that adds an item to the cart when pressed.\n * It must be a descendent of the `CartProvider` component.\n */\nexport function AddToCartButton<AsType extends React.ElementType = 'button'>(\n props: AddToCartButtonProps<AsType>,\n): JSX.Element {\n const [addingItem, setAddingItem] = useState<boolean>(false);\n const {\n variantId: explicitVariantId,\n quantity = 1,\n attributes,\n sellingPlanId,\n onClick,\n children,\n accessibleAddingToCartLabel,\n ...passthroughProps\n } = props;\n const {status, linesAdd} = useCart();\n const {selectedVariant} = useProduct();\n const variantId = explicitVariantId ?? selectedVariant?.id ?? '';\n const disabled =\n explicitVariantId === null ||\n variantId === '' ||\n selectedVariant === null ||\n addingItem ||\n // Only certain 'as' types such as 'button' contain `disabled`\n (passthroughProps as {disabled?: boolean}).disabled;\n\n useEffect(() => {\n if (addingItem && status === 'idle') {\n setAddingItem(false);\n }\n }, [status, addingItem]);\n\n const handleAddItem = useCallback(() => {\n setAddingItem(true);\n linesAdd([\n {\n quantity,\n merchandiseId: variantId || '',\n attributes,\n sellingPlanId,\n },\n ]);\n }, [linesAdd, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <>\n <BaseButton\n {...passthroughProps}\n disabled={disabled}\n onClick={onClick}\n defaultOnClick={handleAddItem}\n >\n {children}\n </BaseButton>\n {accessibleAddingToCartLabel ? (\n <p\n style={{\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n }}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n {addingItem ? accessibleAddingToCartLabel : null}\n </p>\n ) : null}\n </>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface AddToCartButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends AddToCartButtonPropsBase,\n CustomBaseButtonProps<AsType> {}\n","export const AnalyticsEventName = {\n PAGE_VIEW: 'PAGE_VIEW',\n ADD_TO_CART: 'ADD_TO_CART',\n PAGE_VIEW_2: 'PAGE_VIEW_2',\n COLLECTION_VIEW: 'COLLECTION_VIEW',\n PRODUCT_VIEW: 'PRODUCT_VIEW',\n SEARCH_VIEW: 'SEARCH_VIEW',\n} as const;\n\nexport const AnalyticsPageType: AnalyticsPageType = {\n article: 'article',\n blog: 'blog',\n captcha: 'captcha',\n cart: 'cart',\n collection: 'collection',\n customersAccount: 'customers/account',\n customersActivateAccount: 'customers/activate_account',\n customersAddresses: 'customers/addresses',\n customersLogin: 'customers/login',\n customersOrder: 'customers/order',\n customersRegister: 'customers/register',\n customersResetPassword: 'customers/reset_password',\n giftCard: 'gift_card',\n home: 'index',\n listCollections: 'list-collections',\n forbidden: '403',\n notFound: '404',\n page: 'page',\n password: 'password',\n product: 'product',\n policy: 'policy',\n search: 'search',\n} as const;\n\nexport const ShopifySalesChannel: ShopifySalesChannel = {\n hydrogen: 'hydrogen',\n headless: 'headless',\n} as const;\n\nexport const ShopifyAppId = {\n hydrogen: '6167201',\n headless: '12875497473',\n} as const;\n\n/**\n * These duplicated interface declaration is so that we can generate proper documentation\n * for these public facing constants\n */\nexport interface AnalyticsEventName {\n /** Page view */\n PAGE_VIEW: 'PAGE_VIEW';\n /** Add to cart */\n ADD_TO_CART: 'ADD_TO_CART';\n}\n\nexport interface AnalyticsPageType {\n article: 'article';\n blog: 'blog';\n captcha: 'captcha';\n cart: 'cart';\n collection: 'collection';\n customersAccount: 'customers/account';\n customersActivateAccount: 'customers/activate_account';\n customersAddresses: 'customers/addresses';\n customersLogin: 'customers/login';\n customersOrder: 'customers/order';\n customersRegister: 'customers/register';\n customersResetPassword: 'customers/reset_password';\n giftCard: 'gift_card';\n home: 'index';\n listCollections: 'list-collections';\n forbidden: '403';\n notFound: '404';\n page: 'page';\n password: 'password';\n product: 'product';\n policy: 'policy';\n search: 'search';\n}\n\nexport interface ShopifySalesChannel {\n /** Shopify Hydrogen sales channel */\n hydrogen: 'hydrogen';\n /** Shopify Headless sales channel */\n headless: 'headless';\n}\n","import type {\n ShopifyMonorailPayload,\n ShopifyMonorailEvent,\n ShopifyGid,\n} from './analytics-types.js';\n\n/**\n * Builds a Shopify Monorail event from a Shopify Monorail payload and a schema ID.\n * @param payload - The Monorail payload\n * @param schemaId - The schema ID to use\n * @returns The formatted payload\n **/\nexport function schemaWrapper(\n schemaId: string,\n payload: ShopifyMonorailPayload,\n): ShopifyMonorailEvent {\n return {\n schema_id: schemaId,\n payload,\n metadata: {\n event_created_at_ms: Date.now(),\n },\n };\n}\n\n/**\n * Parses global id (gid) and returns the resource type and id.\n * @see https://shopify.dev/api/usage/gids\n * @param gid - A shopify GID (string)\n *\n * @example\n * ```ts\n * const {id, resource} = parseGid('gid://shopify/Order/123')\n * // => id = \"123\", resource = 'Order'\n *\n * * const {id, resource} = parseGid('gid://shopify/Cart/abc123')\n * // => id = \"abc123\", resource = 'Cart'\n * ```\n **/\nexport function parseGid(gid: string | undefined): ShopifyGid {\n const defaultReturn: ShopifyGid = {\n id: '',\n resource: null,\n resourceId: null,\n search: '',\n searchParams: new URLSearchParams(),\n hash: '',\n };\n\n if (typeof gid !== 'string') {\n return defaultReturn;\n }\n\n try {\n const {search, searchParams, pathname, hash} = new URL(gid);\n const pathnameParts = pathname.split('/');\n const lastPathnamePart = pathnameParts[pathnameParts.length - 1];\n const resourcePart = pathnameParts[pathnameParts.length - 2];\n\n if (!lastPathnamePart || !resourcePart) {\n return defaultReturn;\n }\n\n const id = `${lastPathnamePart}${search}${hash}` || '';\n const resourceId = lastPathnamePart || null;\n const resource = resourcePart ?? null;\n\n return {id, resource, resourceId, search, searchParams, hash};\n } catch {\n return defaultReturn;\n }\n}\n\n/**\n * Filters properties from an object and returns a new object with only the properties that have a truthy value.\n * @param keyValuePairs - An object of key-value pairs\n * @param formattedData - An object which will hold the truthy values\n * @returns The formatted object\n **/\nexport function addDataIf(\n keyValuePairs: ShopifyMonorailPayload,\n formattedData: ShopifyMonorailPayload,\n): ShopifyMonorailPayload {\n if (typeof keyValuePairs !== 'object') {\n return {};\n }\n Object.entries(keyValuePairs).forEach(([key, value]) => {\n if (value) {\n formattedData[key] = value;\n }\n });\n return formattedData;\n}\n\n/**\n * Utility that errors if a function is called on the server.\n * @param fnName - The name of the function\n * @returns A boolean\n **/\nexport function errorIfServer(fnName: string): boolean {\n if (typeof document === 'undefined') {\n console.error(\n `${fnName} should only be used within the useEffect callback or event handlers`,\n );\n return true;\n }\n return false;\n}\n","import {\n ShopifyPageViewPayload,\n ShopifyMonorailPayload,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {ShopifyAppId} from './analytics-constants.js';\nimport {addDataIf, schemaWrapper, parseGid} from './analytics-utils.js';\nimport {buildUUID} from './cookies-utils.js';\n\nconst SCHEMA_ID = 'trekkie_storefront_page_view/1.4';\nconst OXYGEN_DOMAIN = 'myshopify.dev';\n\nexport function pageView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const {id, resource} = parseGid(pageViewPayload.resourceId);\n const resourceType = resource ? resource.toLowerCase() : undefined;\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n pageType: pageViewPayload.pageType,\n customerId: parseInt(parseGid(pageViewPayload.customerId).id || '0'),\n resourceType,\n resourceId: parseInt(id),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\nfunction formatPayload(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailPayload {\n return {\n appClientId: payload.shopifySalesChannel\n ? ShopifyAppId[payload.shopifySalesChannel]\n : ShopifyAppId.headless,\n isMerchantRequest: isMerchantRequest(payload.url),\n hydrogenSubchannelId:\n payload.storefrontId || payload.hydrogenSubchannelId || '0',\n\n isPersistentCookie: payload.hasUserConsent,\n uniqToken: payload.uniqueToken,\n visitToken: payload.visitToken,\n microSessionId: buildUUID(),\n microSessionCount: 1,\n\n url: payload.url,\n path: payload.path,\n search: payload.search,\n referrer: payload.referrer,\n title: payload.title,\n\n shopId: parseInt(parseGid(payload.shopId).id),\n currency: payload.currency,\n contentLanguage: payload.acceptedLanguage || 'en',\n };\n}\n\nfunction isMerchantRequest(url: string): boolean {\n if (typeof url !== 'string') {\n return false;\n }\n const hostname = new URL(url).hostname;\n if (hostname.indexOf(OXYGEN_DOMAIN) !== -1 || hostname === 'localhost') {\n return true;\n }\n return false;\n}\n","import {\n ShopifyAnalyticsPayload,\n ShopifyPageViewPayload,\n ShopifyAddToCartPayload,\n ShopifyMonorailPayload,\n ShopifyAnalyticsProduct,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {AnalyticsPageType, ShopifySalesChannel} from './analytics-constants.js';\nimport {addDataIf, schemaWrapper, parseGid} from './analytics-utils.js';\nimport {buildUUID} from './cookies-utils.js';\nimport {version} from '../package.json';\n\nconst SCHEMA_ID = 'custom_storefront_customer_tracking/1.2';\nconst PAGE_RENDERED_EVENT_NAME = 'page_rendered';\nconst COLLECTION_PAGE_RENDERED_EVENT_NAME = 'collection_page_rendered';\nconst PRODUCT_PAGE_RENDERED_EVENT_NAME = 'product_page_rendered';\nconst PRODUCT_ADDED_TO_CART_EVENT_NAME = 'product_added_to_cart';\nconst SEARCH_SUBMITTED_EVENT_NAME = 'search_submitted';\n\nfunction prepareAdditionalPayload(\n payload: ShopifyPageViewPayload,\n): Pick<ShopifyMonorailPayload, 'canonical_url' | 'customer_id'> {\n return {\n canonical_url: payload.canonicalUrl || payload.url,\n customer_id: parseInt(parseGid(payload.customerId).id || '0'),\n };\n}\n\n// Send the page view event to the Monorail server.\n// It also sends additional page view events based on the page type.\nexport function pageView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n const pageType = pageViewPayload.pageType;\n const pageViewEvents = [];\n\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n\n switch (pageType) {\n case AnalyticsPageType.collection:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: COLLECTION_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n collection_name: pageViewPayload.collectionHandle,\n collection_id: parseInt(\n parseGid(pageViewPayload.collectionId).id,\n ),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n case AnalyticsPageType.product:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n products: formatProductPayload(pageViewPayload.products),\n total_value: pageViewPayload.totalValue,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n case AnalyticsPageType.search:\n pageViewEvents.push(\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: SEARCH_SUBMITTED_EVENT_NAME,\n ...additionalPayload,\n search_string: pageViewPayload.searchString,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n );\n break;\n }\n\n return pageViewEvents;\n}\n\n// Sends page view event to the Monorail server.\nexport function pageView2(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends collection view event to the Monorail server.\nexport function collectionView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: COLLECTION_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n collection_name: pageViewPayload.collectionHandle,\n collection_id: parseInt(parseGid(pageViewPayload.collectionId).id),\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends product view event to the Monorail server.\nexport function productView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_PAGE_RENDERED_EVENT_NAME,\n ...additionalPayload,\n products: formatProductPayload(pageViewPayload.products),\n total_value: pageViewPayload.totalValue,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\n// Sends search view event to the Monorail server.\nexport function searchView(\n payload: ShopifyPageViewPayload,\n): ShopifyMonorailEvent[] {\n const pageViewPayload = payload;\n const additionalPayload = prepareAdditionalPayload(pageViewPayload);\n\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: SEARCH_SUBMITTED_EVENT_NAME,\n ...additionalPayload,\n search_string: pageViewPayload.searchString,\n },\n formatPayload(pageViewPayload),\n ),\n ),\n ];\n}\n\nexport function addToCart(\n payload: ShopifyAddToCartPayload,\n): ShopifyMonorailEvent[] {\n const addToCartPayload = payload;\n const cartToken = parseGid(addToCartPayload.cartId);\n const cart_token = cartToken?.id ? `${cartToken.id}` : null;\n return [\n schemaWrapper(\n SCHEMA_ID,\n addDataIf(\n {\n event_name: PRODUCT_ADDED_TO_CART_EVENT_NAME,\n customerId: addToCartPayload.customerId,\n cart_token,\n total_value: addToCartPayload.totalValue,\n products: formatProductPayload(addToCartPayload.products),\n customer_id: parseInt(\n parseGid(addToCartPayload.customerId).id || '0',\n ),\n },\n formatPayload(addToCartPayload),\n ),\n ),\n ];\n}\n\nfunction formatPayload(\n payload: ShopifyAnalyticsPayload,\n): ShopifyMonorailPayload {\n return {\n source: payload.shopifySalesChannel || ShopifySalesChannel.headless,\n asset_version_id: payload.assetVersionId || version,\n hydrogenSubchannelId:\n payload.storefrontId || payload.hydrogenSubchannelId || '0',\n\n is_persistent_cookie: payload.hasUserConsent,\n deprecated_visit_token: payload.visitToken,\n unique_token: payload.uniqueToken,\n event_time: Date.now(),\n event_id: buildUUID(),\n\n event_source_url: payload.url,\n referrer: payload.referrer,\n user_agent: payload.userAgent,\n navigation_type: payload.navigationType,\n navigation_api: payload.navigationApi,\n\n shop_id: parseInt(parseGid(payload.shopId).id),\n currency: payload.currency,\n\n ccpa_enforced: payload.ccpaEnforced || false,\n gdpr_enforced: payload.gdprEnforced || false,\n gdpr_enforced_as_string: payload.gdprEnforced ? 'true' : 'false',\n analytics_allowed: payload.analyticsAllowed || false,\n marketing_allowed: payload.marketingAllowed || false,\n sale_of_data_allowed: payload.saleOfDataAllowed || false,\n };\n}\n\nfunction formatProductPayload(products?: ShopifyAnalyticsProduct[]): string[] {\n return products\n ? products.map((p: ShopifyAnalyticsProduct) => {\n const product = addDataIf(\n {\n variant_gid: p.variantGid,\n category: p.category,\n sku: p.sku,\n product_id: parseInt(parseGid(p.productGid).id),\n variant_id: parseInt(parseGid(p.variantGid).id),\n },\n {\n product_gid: p.productGid,\n name: p.name,\n variant: p.variantName || '',\n brand: p.brand,\n price: parseFloat(p.price),\n quantity: Number(p.quantity || 0),\n },\n );\n return JSON.stringify(product);\n })\n : [];\n}\n","import {SHOPIFY_S, SHOPIFY_Y} from './cart-constants.js';\nimport type {\n ClientBrowserParameters,\n ShopifyAddToCartPayload,\n ShopifyAnalytics,\n ShopifyPageViewPayload,\n ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {AnalyticsEventName} from './analytics-constants.js';\nimport {errorIfServer} from './analytics-utils.js';\nimport {getShopifyCookies} from './cookies-utils.js';\n\nimport {pageView as trekkiePageView} from './analytics-schema-trekkie-storefront-page-view.js';\nimport {\n pageView as customerPageView,\n pageView2 as customerPageView2,\n collectionView as customerCollectionView,\n productView as customerProductView,\n searchView as customerSearchView,\n addToCart as customerAddToCart,\n} from './analytics-schema-custom-storefront-customer-tracking.js';\n\n/**\n * Set user and session cookies and refresh the expiry time\n * @param event - The analytics event.\n * @param shopDomain - The Online Store domain to sent Shopify analytics under the same\n * top level domain.\n */\nexport function sendShopifyAnalytics(\n event: ShopifyAnalytics,\n shopDomain?: string,\n): Promise<void> {\n const {eventName, payload} = event;\n if (!payload.hasUserConsent) return Promise.resolve();\n\n let events: ShopifyMonorailEvent[] = [];\n const pageViewPayload = payload as ShopifyPageViewPayload;\n\n if (eventName === AnalyticsEventName.PAGE_VIEW) {\n events = events.concat(\n trekkiePageView(pageViewPayload),\n customerPageView(pageViewPayload),\n );\n } else if (eventName === AnalyticsEventName.ADD_TO_CART) {\n events = events.concat(\n customerAddToCart(payload as ShopifyAddToCartPayload),\n );\n } else if (eventName === AnalyticsEventName.PAGE_VIEW_2) {\n events = events.concat(\n trekkiePageView(pageViewPayload),\n customerPageView2(pageViewPayload),\n );\n } else if (eventName === AnalyticsEventName.COLLECTION_VIEW) {\n events = events.concat(customerCollectionView(pageViewPayload));\n } else if (eventName === AnalyticsEventName.PRODUCT_VIEW) {\n events = events.concat(customerProductView(pageViewPayload));\n } else if (eventName === AnalyticsEventName.SEARCH_VIEW) {\n events = events.concat(customerSearchView(pageViewPayload));\n }\n\n if (events.length) {\n return sendToShopify(events, shopDomain);\n } else {\n return Promise.resolve();\n }\n}\n\n// Shopify monorail return invalid agent for Lighthouse userAgents\nfunction isLighthouseUserAgent(): boolean {\n if (typeof window === 'undefined' || !window.navigator) return false;\n return /Chrome-Lighthouse/.test(window.navigator.userAgent);\n}\n\ntype MonorailResponse = {\n status: number;\n message: string;\n};\n\nconst ERROR_MESSAGE = 'sendShopifyAnalytics request is unsuccessful';\n\nfunction sendToShopify(\n events: ShopifyMonorailEvent[],\n shopDomain?: string,\n): Promise<void> {\n if (isLighthouseUserAgent()) {\n return Promise.resolve();\n }\n\n const eventsToBeSent = {\n events,\n metadata: {\n event_sent_at_ms: Date.now(),\n },\n };\n\n try {\n return fetch(\n shopDomain\n ? `https://${shopDomain}/.well-known/shopify/monorail/unstable/produce_batch`\n : 'https://monorail-edge.shopifysvc.com/unstable/produce_batch',\n {\n method: 'post',\n headers: {\n 'content-type': 'text/plain',\n },\n body: JSON.stringify(eventsToBeSent),\n },\n )\n .then((response) => {\n if (!response.ok) {\n throw new Error('Response failed');\n }\n return response.text();\n })\n .then((data) => {\n if (data) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const jsonResponse = JSON.parse(data);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n jsonResponse.result.forEach((eventResponse: MonorailResponse) => {\n if (eventResponse.status !== 200) {\n console.error(ERROR_MESSAGE, '\\n\\n', eventResponse.message);\n }\n });\n }\n })\n .catch((err) => {\n console.error(ERROR_MESSAGE, err);\n if (__HYDROGEN_DEV__) {\n throw new Error(ERROR_MESSAGE);\n }\n });\n } catch (error) {\n // Do nothing\n return Promise.resolve();\n }\n}\n\nexport function getClientBrowserParameters(): ClientBrowserParameters {\n if (errorIfServer('getClientBrowserParameters')) {\n return {\n uniqueToken: '',\n visitToken: '',\n url: '',\n path: '',\n search: '',\n referrer: '',\n title: '',\n userAgent: '',\n navigationType: '',\n navigationApi: '',\n };\n }\n\n const [navigationType, navigationApi] = getNavigationType();\n const cookies = getShopifyCookies(document.cookie);\n\n return {\n uniqueToken: cookies[SHOPIFY_Y],\n visitToken: cookies[SHOPIFY_S],\n url: location.href,\n path: location.pathname,\n search: location.search,\n referrer: document.referrer,\n title: document.title,\n userAgent: navigator.userAgent,\n navigationType,\n navigationApi,\n };\n}\n\nfunction getNavigationTypeExperimental(): string | undefined {\n try {\n const navigationEntries =\n performance?.getEntriesByType &&\n performance?.getEntriesByType('navigation');\n\n if (navigationEntries && navigationEntries[0]) {\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming\n const rawType = (\n window.performance.getEntriesByType(\n 'navigation',\n )[0] as PerformanceNavigationTiming\n )['type'];\n const navType = rawType && rawType.toString();\n\n return navType;\n }\n } catch (err) {\n // Do nothing\n }\n return undefined;\n}\n\nfunction getNavigationTypeLegacy(): string | undefined {\n try {\n if (\n PerformanceNavigation &&\n performance?.navigation?.type !== null &&\n performance?.navigation?.type !== undefined\n ) {\n // https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation\n const rawType = performance.navigation.type;\n switch (rawType) {\n case PerformanceNavigation.TYPE_NAVIGATE:\n return 'navigate';\n break;\n case PerformanceNavigation.TYPE_RELOAD:\n return 'reload';\n break;\n case PerformanceNavigation.TYPE_BACK_FORWARD:\n return 'back_forward';\n break;\n default:\n return `unknown: ${rawType}`;\n }\n }\n } catch (err) {\n // do nothing\n }\n return undefined;\n}\n\nfunction getNavigationType(): [string, string] {\n try {\n let navApi = 'PerformanceNavigationTiming';\n let navType = getNavigationTypeExperimental();\n if (!navType) {\n navType = getNavigationTypeLegacy();\n navApi = 'performance.navigation';\n }\n if (navType) {\n return [navType, navApi];\n } else {\n return ['unknown', 'unknown'];\n }\n } catch (err) {\n // do nothing\n }\n return ['error', 'error'];\n}\n","import {useEffect, useState, useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {\n BaseButton,\n type BaseButtonProps,\n type CustomBaseButtonProps,\n} from './BaseButton.js';\n\ninterface BuyNowButtonPropsBase {\n /** The item quantity. Defaults to 1. */\n quantity?: number;\n /** The ID of the variant. */\n variantId: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n}\n\ntype BuyNowButtonProps<AsType extends React.ElementType = 'button'> =\n BuyNowButtonPropsBase & BaseButtonProps<AsType>;\n\n/**\n * The `BuyNowButton` component renders a button that adds an item to the cart and redirects the customer to checkout.\n * Must be a child of a `CartProvider` component.\n */\nexport function BuyNowButton<AsType extends React.ElementType = 'button'>(\n props: BuyNowButtonProps<AsType>,\n): JSX.Element {\n const {cartCreate, checkoutUrl} = useCart();\n const [loading, setLoading] = useState<boolean>(false);\n\n const {\n quantity,\n variantId,\n sellingPlanId,\n onClick,\n attributes,\n children,\n ...passthroughProps\n } = props;\n\n useEffect(() => {\n if (loading && checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n }, [loading, checkoutUrl]);\n\n const handleBuyNow = useCallback(() => {\n setLoading(true);\n cartCreate({\n lines: [\n {\n quantity: quantity ?? 1,\n merchandiseId: variantId,\n attributes,\n sellingPlanId,\n },\n ],\n });\n }, [cartCreate, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <BaseButton\n // Only certain 'as' types such as 'button' contain `disabled`\n disabled={loading ?? (passthroughProps as {disabled?: boolean}).disabled}\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleBuyNow}\n >\n {children}\n </BaseButton>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface BuyNowButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends BuyNowButtonPropsBase,\n CustomBaseButtonProps<AsType> {}\n","import {ReactNode, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {\n BaseButton,\n type BaseButtonProps,\n type CustomBaseButtonProps,\n} from './BaseButton.js';\n\ntype ChildrenProps = {\n /** A `ReactNode` element. */\n children: ReactNode;\n};\ntype CartCheckoutButtonProps = Omit<BaseButtonProps<'button'>, 'onClick'> &\n ChildrenProps;\n\n/**\n * The `CartCheckoutButton` component renders a button that redirects to the checkout URL for the cart.\n * It must be a descendent of a `CartProvider` component.\n */\nexport function CartCheckoutButton(\n props: CartCheckoutButtonProps,\n): JSX.Element {\n const [requestedCheckout, setRequestedCheckout] = useState(false);\n const {status, checkoutUrl} = useCart();\n const {children, ...passthroughProps} = props;\n\n useEffect(() => {\n if (requestedCheckout && checkoutUrl && status === 'idle') {\n window.location.href = checkoutUrl;\n }\n }, [requestedCheckout, status, checkoutUrl]);\n\n return (\n <BaseButton\n {...passthroughProps}\n disabled={requestedCheckout || passthroughProps.disabled}\n onClick={(): void => setRequestedCheckout(true)}\n >\n {children}\n </BaseButton>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\n// we ignore this issue because it makes the documentation look better than the equivalent `type` that it wants us to convert to\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface CartCheckoutButtonPropsForDocs<\n AsType extends React.ElementType = 'button',\n> extends Omit<CustomBaseButtonProps<AsType>, 'onClick'> {}\n","import {useMemo} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {CurrencyCode, MoneyV2} from './storefront-api-types.js';\n\nexport type UseMoneyValue = {\n /**\n * The currency code from the `MoneyV2` object.\n */\n currencyCode: CurrencyCode;\n /**\n * The name for the currency code, returned by `Intl.NumberFormat`.\n */\n currencyName?: string;\n /**\n * The currency symbol returned by `Intl.NumberFormat`.\n */\n currencySymbol?: string;\n /**\n * The currency narrow symbol returned by `Intl.NumberFormat`.\n */\n currencyNarrowSymbol?: string;\n /**\n * The localized amount, without any currency symbols or non-number types from the `Intl.NumberFormat.formatToParts` parts.\n */\n amount: string;\n /**\n * All parts returned by `Intl.NumberFormat.formatToParts`.\n */\n parts: Intl.NumberFormatPart[];\n /**\n * A string returned by `new Intl.NumberFormat` for the amount and currency code,\n * using the `locale` value in the [`LocalizationProvider` component](https://shopify.dev/api/hydrogen/components/localization/localizationprovider).\n */\n localizedString: string;\n /**\n * The `MoneyV2` object provided as an argument to the hook.\n */\n original: MoneyV2;\n /**\n * A string with trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n * For example, `$640.00` turns into `$640`.\n * `$640.42` remains `$640.42`.\n */\n withoutTrailingZeros: string;\n /**\n * A string without currency and without trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n * For example, `$640.00` turns into `640`.\n * `$640.42` turns into `640.42`.\n */\n withoutTrailingZerosAndCurrency: string;\n};\n\n/**\n * The `useMoney` hook takes a [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2) and returns a\n * default-formatted string of the amount with the correct currency indicator, along with some of the parts provided by\n * [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).\n * Uses `locale` from `ShopifyProvider`\n * \n * @see {@link https://shopify.dev/api/hydrogen/hooks/usemoney}\n * @example initialize the money object\n * ```ts\n * const money = useMoney({\n * amount: '100.00',\n * currencyCode: 'USD'\n * })\n * ```\n * \n *\n * @example basic usage, outputs: $100.00\n * ```ts\n * money.localizedString\n * ```\n * \n *\n * @example without currency, outputs: 100.00\n * ```ts\n * money.amount\n * ```\n * \n *\n * @example without trailing zeros, outputs: $100\n * ```ts\n * money.withoutTrailingZeros\n * ```\n * \n *\n * @example currency name, outputs: US dollars\n * ```ts\n * money.currencyCode\n * ```\n * \n *\n * @example currency symbol, outputs: $\n * ```ts\n * money.currencySymbol\n * ```\n * \n *\n * @example without currency and without trailing zeros, outputs: 100\n * ```ts\n * money.withoutTrailingZerosAndCurrency\n * ```\n */\nexport function useMoney(money: MoneyV2): UseMoneyValue {\n const {countryIsoCode, languageIsoCode} = useShop();\n const locale = languageIsoCode.includes('_')\n ? languageIsoCode.replace('_', '-')\n : `${languageIsoCode}-${countryIsoCode}`;\n\n if (!locale) {\n throw new Error(\n `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to '<ShopifyProvider/>'. 'locale' is required for 'useMoney()' to work`,\n );\n }\n\n const amount = parseFloat(money.amount);\n\n const {\n defaultFormatter,\n nameFormatter,\n narrowSymbolFormatter,\n withoutTrailingZerosFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n } = useMemo(() => {\n const options = {\n style: 'currency' as const,\n currency: money.currencyCode,\n };\n\n return {\n defaultFormatter: getLazyFormatter(locale, options),\n nameFormatter: getLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'name',\n }),\n narrowSymbolFormatter: getLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'narrowSymbol',\n }),\n withoutTrailingZerosFormatter: getLazyFormatter(locale, {\n ...options,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }),\n withoutCurrencyFormatter: getLazyFormatter(locale),\n withoutTrailingZerosOrCurrencyFormatter: getLazyFormatter(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }),\n };\n }, [money.currencyCode, locale]);\n\n const isPartCurrency = (part: Intl.NumberFormatPart): boolean =>\n part.type === 'currency';\n\n // By wrapping these properties in functions, we only\n // create formatters if they are going to be used.\n const lazyFormatters = useMemo(\n () => ({\n original: () => money,\n currencyCode: () => money.currencyCode,\n\n localizedString: () => defaultFormatter().format(amount),\n\n parts: () => defaultFormatter().formatToParts(amount),\n\n withoutTrailingZeros: () =>\n amount % 1 === 0\n ? withoutTrailingZerosFormatter().format(amount)\n : defaultFormatter().format(amount),\n\n withoutTrailingZerosAndCurrency: () =>\n amount % 1 === 0\n ? withoutTrailingZerosOrCurrencyFormatter().format(amount)\n : withoutCurrencyFormatter().format(amount),\n\n currencyName: () =>\n nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"US dollars\"\n\n currencySymbol: () =>\n defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"USD\"\n\n currencyNarrowSymbol: () =>\n narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)\n ?.value ?? '', // e.g. \"$\"\n\n amount: () =>\n defaultFormatter()\n .formatToParts(amount)\n .filter((part) =>\n ['decimal', 'fraction', 'group', 'integer', 'literal'].includes(\n part.type,\n ),\n )\n .map((part) => part.value)\n .join(''),\n }),\n [\n money,\n amount,\n nameFormatter,\n defaultFormatter,\n narrowSymbolFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n ],\n );\n\n // Call functions automatically when the properties are accessed\n // to keep these functions as an implementation detail.\n return useMemo(\n () =>\n new Proxy(lazyFormatters as unknown as UseMoneyValue, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n get: (target, key) => Reflect.get(target, key)?.call(null),\n }),\n [lazyFormatters],\n );\n}\n\nconst formatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getLazyFormatter(\n locale: string,\n options?: Intl.NumberFormatOptions,\n): () => Intl.NumberFormat {\n const key = JSON.stringify([locale, options]);\n\n return function (): Intl.NumberFormat {\n let formatter = formatterCache.get(key);\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, options);\n formatterCache.set(key, formatter);\n }\n return formatter;\n };\n}\n","import {type ReactNode} from 'react';\nimport {useMoney} from './useMoney.js';\nimport type {MoneyV2, UnitPriceMeasurement} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nexport interface MoneyPropsBase<ComponentGeneric extends React.ElementType> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `div`. */\n as?: ComponentGeneric;\n /** An object with fields that correspond to the Storefront API's [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2). */\n data: PartialDeep<MoneyV2, {recurseIntoArrays: true}>;\n /** Whether to remove the currency symbol from the output. */\n withoutCurrency?: boolean;\n /** Whether to remove trailing zeros (fractional money) from the output. */\n withoutTrailingZeros?: boolean;\n /** A [UnitPriceMeasurement object](https://shopify.dev/api/storefront/2025-01/objects/unitpricemeasurement). */\n measurement?: PartialDeep<UnitPriceMeasurement, {recurseIntoArrays: true}>;\n /** Customizes the separator between the money output and the measurement output. Used with the `measurement` prop. Defaults to `'/'`. */\n measurementSeparator?: ReactNode;\n}\n\n// This article helps understand the typing here https://www.benmvp.com/blog/polymorphic-react-components-typescript/ Ben is the best :)\nexport type MoneyProps<ComponentGeneric extends React.ElementType> =\n MoneyPropsBase<ComponentGeneric> &\n (ComponentGeneric extends keyof React.JSX.IntrinsicElements\n ? Omit<\n React.ComponentPropsWithoutRef<ComponentGeneric>,\n keyof MoneyPropsBase<ComponentGeneric>\n >\n : React.ComponentPropsWithoutRef<ComponentGeneric>);\n\n/**\n * The `Money` component renders a string of the Storefront API's\n * [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2)\n * according to the `locale` in the `ShopifyProvider` component.\n * \n * @see {@link https://shopify.dev/api/hydrogen/components/money}\n * @example basic usage, outputs: $100.00\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} />\n * ```\n * \n *\n * @example without currency, outputs: 100.00\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} withoutCurrency />\n * ```\n * \n *\n * @example without trailing zeros, outputs: $100\n * ```ts\n * <Money data={{amount: '100.00', currencyCode: 'USD'}} withoutTrailingZeros />\n * ```\n * \n *\n * @example with per-unit measurement, outputs: $100.00 per G\n * ```ts\n * <Money\n * data={{amount: '100.00', currencyCode: 'USD'}}\n * measurement={{referenceUnit: 'G'}}\n * measurementSeparator=\" per \"\n * />\n * ```\n */\nexport function Money<ComponentGeneric extends React.ElementType = 'div'>({\n data,\n as,\n withoutCurrency,\n withoutTrailingZeros,\n measurement,\n measurementSeparator = '/',\n ...passthroughProps\n}: MoneyProps<ComponentGeneric>): JSX.Element {\n if (!isMoney(data)) {\n throw new Error(\n `<Money/> needs a valid 'data' prop that has 'amount' and 'currencyCode'`,\n );\n }\n const moneyObject = useMoney(data);\n const Wrapper = as ?? 'div';\n\n let output = moneyObject.localizedString;\n\n if (withoutCurrency || withoutTrailingZeros) {\n if (withoutCurrency && !withoutTrailingZeros) {\n output = moneyObject.amount;\n } else if (!withoutCurrency && withoutTrailingZeros) {\n output = moneyObject.withoutTrailingZeros;\n } else {\n // both\n output = moneyObject.withoutTrailingZerosAndCurrency;\n }\n }\n\n return (\n <Wrapper {...passthroughProps}>\n {output}\n {measurement && measurement.referenceUnit && (\n <>\n {measurementSeparator}\n {measurement.referenceUnit}\n </>\n )}\n </Wrapper>\n );\n}\n\n// required in order to narrow the money object down and make TS happy\nfunction isMoney(\n maybeMoney: PartialDeep<MoneyV2, {recurseIntoArrays: true}>,\n): maybeMoney is MoneyV2 {\n return (\n typeof maybeMoney.amount === 'string' &&\n !!maybeMoney.amount &&\n typeof maybeMoney.currencyCode === 'string' &&\n !!maybeMoney.currencyCode\n );\n}\n","import {Money, type MoneyPropsBase} from './Money.js';\nimport {useCart} from './CartProvider.js';\n\ninterface CartCostPropsBase {\n /** A string type that defines the type of cost needed. Valid values: `total`, `subtotal`, `tax`, or `duty`. */\n amountType?: 'total' | 'subtotal' | 'tax' | 'duty';\n /** Any `ReactNode` elements. */\n children?: React.ReactNode;\n}\n\ntype CartCostProps = Omit<React.ComponentProps<typeof Money>, 'data'> &\n CartCostPropsBase;\n\n/**\n * The `CartCost` component renders a `Money` component with the cost associated with the `amountType` prop.\n * If no `amountType` prop is specified, then it defaults to `totalAmount`.\n * Depends on `useCart()` and must be a child of `<CartProvider/>`\n */\nexport function CartCost(props: CartCostProps): JSX.Element | null {\n const {cost} = useCart();\n const {amountType = 'total', children, ...passthroughProps} = props;\n let amount;\n\n if (amountType == 'total') {\n amount = cost?.totalAmount;\n } else if (amountType == 'subtotal') {\n amount = cost?.subtotalAmount;\n } else if (amountType == 'tax') {\n amount = cost?.totalTaxAmount;\n } else if (amountType == 'duty') {\n amount = cost?.totalDutyAmount;\n }\n\n if (amount == null) {\n return null;\n }\n\n return (\n <Money {...passthroughProps} data={amount}>\n {children}\n </Money>\n );\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface CartCostPropsForDocs<AsType extends React.ElementType = 'div'>\n extends Omit<MoneyPropsBase<AsType>, 'data'>,\n CartCostPropsBase {}\n","import {useContext, createContext, type ReactNode} from 'react';\nimport {\n ComponentizableCartLine,\n type CartLine,\n} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\ntype CartLinePartialDeep = PartialDeep<\n CartLine | ComponentizableCartLine,\n {recurseIntoArrays: true}\n>;\n\nexport const CartLineContext = createContext<CartLinePartialDeep | null>(null);\n\n/**\n * The `useCartLine` hook provides access to the [CartLine object](https://shopify.dev/api/storefront/2025-01/objects/cartline) from the Storefront API. It must be a descendent of a `CartProvider` component.\n */\nexport function useCartLine(): CartLinePartialDeep {\n const context = useContext(CartLineContext);\n\n if (context == null) {\n throw new Error('Expected a cart line context but none was found');\n }\n\n return context;\n}\n\ntype CartLineProviderProps = {\n /** Any `ReactNode` elements. */\n children: ReactNode;\n /** A cart line object. */\n line: CartLinePartialDeep;\n};\n\n/**\n * The `CartLineProvider` component creates a context for using a cart line.\n */\nexport function CartLineProvider({\n children,\n line,\n}: CartLineProviderProps): JSX.Element {\n return (\n <CartLineContext.Provider value={line}>{children}</CartLineContext.Provider>\n );\n}\n","import type {ComponentPropsWithoutRef, ElementType} from 'react';\nimport {useCartLine} from './CartLineProvider.js';\n\ninterface CartLineQuantityBaseProps<\n ComponentGeneric extends ElementType = 'span',\n> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `span`. */\n as?: ComponentGeneric;\n}\n\nexport type CartLineQuantityProps<ComponentGeneric extends ElementType> =\n CartLineQuantityBaseProps<ComponentGeneric> &\n Omit<\n ComponentPropsWithoutRef<ComponentGeneric>,\n keyof CartLineQuantityBaseProps<ComponentGeneric>\n >;\n\n/**\n * The `<CartLineQuantity/>` component renders a `span` (or another element / component that can be customized by the `as` prop) with the cart line's quantity.\n *\n * It must be a descendent of a `<CartLineProvider/>` component, and uses the `useCartLine()` hook internally.\n */\nexport function CartLineQuantity<ComponentGeneric extends ElementType = 'span'>(\n props: CartLineQuantityProps<ComponentGeneric>,\n): JSX.Element {\n const cartLine = useCartLine();\n const {as, ...passthroughProps} = props;\n\n const Wrapper = as ? as : 'span';\n\n return <Wrapper {...passthroughProps}>{cartLine.quantity}</Wrapper>;\n}\n","import {useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {useCartLine} from './CartLineProvider.js';\nimport {BaseButton, type BaseButtonProps} from './BaseButton.js';\nimport type {CartLineUpdateInput} from './storefront-api-types.js';\n\ninterface CartLineQuantityAdjustButtonBaseProps {\n /** The adjustment for a cart line's quantity. Valid values: `increase` (default), `decrease`, or `remove`. */\n adjust?: 'increase' | 'decrease' | 'remove';\n}\n\ntype CartLineQuantityAdjustButtonProps<\n AsType extends React.ElementType = 'button',\n> = BaseButtonProps<AsType> & CartLineQuantityAdjustButtonBaseProps;\n\n/**\n * The `<CartLineQuantityAdjustButton />` component renders a button that adjusts the cart line's quantity when pressed.\n *\n * It must be a descendent of `<CartLineProvider/>` and `<CartProvider/>`.\n */\nexport function CartLineQuantityAdjustButton<\n AsType extends React.ElementType = 'button',\n>(props: CartLineQuantityAdjustButtonProps<AsType>): JSX.Element {\n const {status, linesRemove, linesUpdate} = useCart();\n const cartLine = useCartLine();\n const {children, adjust, onClick, ...passthroughProps} = props;\n\n const handleAdjust = useCallback(() => {\n if (adjust === 'remove') {\n linesRemove([cartLine?.id ?? '']);\n return;\n }\n\n const quantity =\n adjust === 'decrease'\n ? (cartLine?.quantity ?? 0) - 1\n : (cartLine?.quantity ?? 0) + 1;\n\n if (quantity <= 0) {\n linesRemove([cartLine?.id ?? '']);\n return;\n }\n\n const lineUpdate = {\n id: cartLine?.id ?? '',\n quantity,\n attributes: (cartLine?.attributes ??\n []) as CartLineUpdateInput['attributes'],\n } satisfies CartLineUpdateInput;\n\n linesUpdate([lineUpdate]);\n }, [\n adjust,\n cartLine?.attributes,\n cartLine?.id,\n cartLine?.quantity,\n linesRemove,\n linesUpdate,\n ]);\n\n // Only certain 'as' types such as 'button' contain `disabled`\n const disabledAttr = (passthroughProps as {disabled?: boolean}).disabled;\n\n return (\n <BaseButton\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleAdjust}\n disabled={\n typeof disabledAttr !== 'undefined' ? disabledAttr : status !== 'idle'\n }\n >\n {children}\n </BaseButton>\n );\n}\n","/**\n * Meant to be used with GraphQL CodeGen to type the Storefront API's custom scalars correctly.\n * Reference for the GraphQL types: https://shopify.dev/docs/api/storefront/2025-01/scalars/HTML\n * Note: JSON is generated as 'unknown' by default.\n */\nexport const storefrontApiCustomScalars = {\n // Keep in sync with the definitions in the app/nextjs/codegen.ts!\n DateTime: 'string',\n Decimal: 'string',\n HTML: 'string',\n URL: 'string',\n Color: 'string',\n UnsignedInt64: 'string',\n};\n\n/**\n * Meant to be used with GraphQL CodeGen to type the Storefront API's custom scalars correctly.\n * Reference for the GraphQL types: https://shopify.dev/docs/api/customer/2025-01/scalars/HTML\n * Note: JSON is generated as 'unknown' by default.\n */\nexport const customerAccountApiCustomScalars = {\n DateTime: 'string',\n Decimal: 'string',\n HTML: 'string',\n ISO8601DateTime: 'string',\n URL: 'string',\n UnsignedInt64: 'string',\n};\n","import type {ExternalVideo as ExternalVideoType} from './storefront-api-types.js';\nimport type {Entries, PartialDeep} from 'type-fest';\nimport {forwardRef, IframeHTMLAttributes} from 'react';\n\nexport interface ExternalVideoBaseProps {\n /**\n * An object with fields that correspond to the Storefront API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).\n */\n data: PartialDeep<ExternalVideoType, {recurseIntoArrays: true}>;\n /** An object containing the options available for either\n * [YouTube](https://developers.google.com/youtube/player_parameters#Parameters) or\n * [Vimeo](https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters).\n */\n options?: YouTube | Vimeo;\n}\n\nexport type ExternalVideoProps = Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n 'src'\n> &\n ExternalVideoBaseProps;\n\n/**\n * The `ExternalVideo` component renders an embedded video for the Storefront\n * API's [ExternalVideo object](https://shopify.dev/api/storefront/reference/products/externalvideo).\n */\nexport const ExternalVideo = forwardRef<HTMLIFrameElement, ExternalVideoProps>(\n (props, ref): JSX.Element => {\n const {\n data,\n options,\n id = data.id,\n frameBorder = '0',\n allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture',\n allowFullScreen = true,\n loading = 'lazy',\n ...passthroughProps\n } = props;\n\n if (!data.embedUrl) {\n throw new Error(`<ExternalVideo/> requires the 'embedUrl' property`);\n }\n\n let finalUrl: string = data.embedUrl;\n\n if (options) {\n const urlObject = new URL(data.embedUrl);\n for (const [key, value] of Object.entries(options) as Entries<\n typeof options\n >) {\n if (typeof value === 'undefined') {\n continue;\n }\n\n urlObject.searchParams.set(key, value.toString());\n }\n finalUrl = urlObject.toString();\n }\n\n return (\n <iframe\n {...passthroughProps}\n id={id ?? data.embedUrl}\n title={data.alt ?? data.id ?? 'external video'}\n frameBorder={frameBorder}\n allow={allow}\n allowFullScreen={allowFullScreen}\n src={finalUrl}\n loading={loading}\n ref={ref}\n ></iframe>\n );\n },\n);\n\ninterface YouTube {\n autoplay?: 0 | 1;\n cc_lang_pref?: string;\n cc_load_policy?: 1;\n color?: 'red' | 'white';\n controls?: 0 | 1;\n disablekb?: 0 | 1;\n enablejsapi?: 0 | 1;\n end?: number;\n fs?: 0 | 1;\n hl?: string;\n iv_load_policy?: 1 | 3;\n list?: string;\n list_type?: 'playlist' | 'user_uploads';\n loop?: 0 | 1;\n modest_branding?: 1;\n origin?: string;\n playlist?: string;\n plays_inline?: 0 | 1;\n rel?: 0 | 1;\n start?: number;\n widget_referrer?: string;\n}\n\ntype VimeoBoolean = 0 | 1 | boolean;\n\ninterface Vimeo {\n autopause?: VimeoBoolean;\n autoplay?: VimeoBoolean;\n background?: VimeoBoolean;\n byline?: VimeoBoolean;\n color?: string;\n controls?: VimeoBoolean;\n dnt?: VimeoBoolean;\n loop?: VimeoBoolean;\n muted?: VimeoBoolean;\n pip?: VimeoBoolean;\n playsinline?: VimeoBoolean;\n portrait?: VimeoBoolean;\n quality?: '240p' | '360p' | '540p' | '720p' | '1080p' | '2k' | '4k';\n speed?: VimeoBoolean;\n '#t'?: string;\n texttrack?: string;\n title?: VimeoBoolean;\n transparent?: VimeoBoolean;\n}\n","/**\n * This file provides utility functions for determining whether or not an option value combination is present in an encoded option value string.\n *\n * In V1 of the encoding strategy, option value arrays are encoded as a trie with the following rules:\n * - `:` `,` ` ` and `-` are control characters.\n * - `:` indicates a new option. ex: 0:1 indicates value 0 for the option in position 1, value 1 for the option in position 2.\n * - `,` indicates the end of a repeated prefix, mulitple consecutive commas indicate the end of multiple repeated prefixes.\n * - ` ` indicates a gap in the sequence of option values. ex: `0 4` indicates option values in position 0 and 4 are present.\n * - `-` indicates a continuous range of option values. ex: `0 1-3 4`. Ranges are only present encoded in the final option value position, so for example the trie for the set [[0,0,0],[0,0,1], ..., [0,2,2]] will be structured as `0:0:0-2,1:0-2,2:0-2`, not `0:0-2:0-2`.\n */\n\nimport {Product} from './storefront-api-types.js';\n\nconst OPTION_VALUE_SEPARATOR = ',';\n\nconst V1_CONTROL_CHARS = {\n OPTION: ':',\n END_OF_PREFIX: ',',\n SEQUENCE_GAP: ' ',\n RANGE: '-',\n};\n\nexport type IsOptionValueCombinationInEncodedVariant = (\n targetOptionValueCombination: number[],\n encodedVariantField: string,\n) => boolean;\n\n/**\n * Determine whether an option value combination is present in an encoded option value string. Function is memoized by encodedVariantField.\n *\n * @param targetOptionValueCombination - Indices of option values to look up in the encoded option value string. A partial set of indices may be passed to determine whether a node or any children is present. For example, if a product has 3 options, passing [0] will return true if any option value combination for the first option's option value is present in the encoded string.\n * @param encodedVariantField - Encoded option value string from the Storefront API, e.g. [product.encodedVariantExistence](/docs/api/storefront/2025-01/objects/Product#field-encodedvariantexistence) or [product.encodedVariantAvailability](/docs/api/storefront/2025-01/objects/Product#field-encodedvariantavailability)\n * @returns - True if a full or partial targetOptionValueIndices is present in the encoded option value string, false otherwise.\n */\nexport const isOptionValueCombinationInEncodedVariant: IsOptionValueCombinationInEncodedVariant =\n ((): IsOptionValueCombinationInEncodedVariant => {\n const decodedOptionValues = new Map<string, Set<string>>();\n\n return function (\n targetOptionValueCombination: number[],\n encodedVariantField: string,\n ): boolean {\n if (targetOptionValueCombination.length === 0) {\n return false;\n }\n\n if (!decodedOptionValues.has(encodedVariantField)) {\n const decodedOptionValuesSet = new Set<string>();\n\n for (const optionValue of decodeEncodedVariant(encodedVariantField)) {\n // add the complete option value to the decoded option values set\n decodedOptionValuesSet.add(optionValue.join(OPTION_VALUE_SEPARATOR));\n\n // add all composite parts of the option value to the decoded option values set. e.g. if the option value is [0,1,2], add \"0\", \"0,1\", \"0,1,2\"\n for (let i = 0; i < optionValue.length; i++) {\n decodedOptionValuesSet.add(\n optionValue.slice(0, i + 1).join(OPTION_VALUE_SEPARATOR),\n );\n }\n }\n\n decodedOptionValues.set(encodedVariantField, decodedOptionValuesSet);\n }\n\n return Boolean(\n decodedOptionValues\n .get(encodedVariantField)\n ?.has(targetOptionValueCombination.join(OPTION_VALUE_SEPARATOR)),\n );\n };\n })();\n\ntype EncodedVariantField =\n | Product['encodedVariantAvailability']\n | Product['encodedVariantExistence'];\ntype DecodedOptionValues = number[][];\n\n/**\n * For an encoded option value string, decode into option value combinations. Entries represent a valid combination formatted as an array of option value positions.\n * @param encodedVariantField - Encoded option value string from the Storefront API, e.g. [product.encodedVariantExistence](/docs/api/storefront/2025-01/objects/Product#field-encodedvariantexistence) or [product.encodedVariantAvailability](/docs/api/storefront/2025-01/objects/Product#field-encodedvariantavailability)\n * @returns Decoded option value combinations\n */\nexport function decodeEncodedVariant(\n encodedVariantField: EncodedVariantField,\n): DecodedOptionValues {\n if (!encodedVariantField) return [];\n\n if (encodedVariantField.startsWith('v1_')) {\n return v1Decoder(stripVersion(encodedVariantField));\n }\n\n throw new Error('Unsupported option value encoding');\n}\n\nconst stripVersion: (encodedVariantField: string) => string = (\n encodedVariantField: string,\n) => encodedVariantField.replace(/^v1_/, '');\n\n/**\n * We encode an array of arrays representing variants, expressed in terms of options and option values, as a trie.\n *\n * This encoding strategy allows extremely large numbers of variants to be expressed in an extremely compact data structure.\n *\n * Integers represent option and values, so [0,0,0] represents option_value at array index 0 for the options at array indexes 0, 1 and 2\n *\n * `:`, `,`, ` ` and `-` are control characters.\n * `:` indicates a new option\n * `,` indicates the end of a repeated prefix, mulitple consecutive commas indicate the end of multiple repeated prefixes.\n * ` ` indicates a gap in the sequence of option values\n * `-` indicates a continuous range of option values\n *\n * Encoding process:\n *\n * example input array: [[0,0,0], [0,1,0], [0,1,1], [1,0,0], [1,0,1], [1,1,1], [2,0,1], [2,1,0]]\n *\n * step 1: encode as string: \"0:0:0,0:1:0,0:1:1,1:0:0,1:0:1,1:1:1,2:0:1,2:1:0,\"\n * step 2: combine nodes that share a prefix: \"0:0:0,0:1:0 1,1:0:0 1,1:1:1,2:0:1,2:1:0,\"\n * step 3: encode data as a trie so no prefixes need to be repeated: \"0:0:0,1:0 1,,1:0:0 1,1:1,,2:0:1,1:0,,\"\n * step 4: since the options are sorted, use a dash to express ranges: \"0:0:0,1:0-1,,1:0:0-1,1:1,,2:0:1,1:0,,\"\n */\nfunction v1Decoder(encodedVariantField: string): number[][] {\n const tokenizer = /[ :,-]/g;\n let index = 0;\n let token: RegExpExecArray | null;\n const options: number[][] = [];\n const currentOptionValue: number[] = [];\n let depth = 0;\n let rangeStart: number | null = null;\n\n // iterate over control characters\n while ((token = tokenizer.exec(encodedVariantField))) {\n const operation = token[0];\n const optionValueIndex =\n Number.parseInt(encodedVariantField.slice(index, token.index)) || 0;\n\n if (rangeStart !== null) {\n // If a range has been started, iterate over the range and add each option value to the list of options\n // - `rangeStart` is set if the last control char was a dash, e.g. `0` for 0-2. It represents the numeric option value position for the start of the range.\n // - `optionValueIndex` is the numeric option value position for the end of the range\n for (; rangeStart < optionValueIndex; rangeStart++) {\n currentOptionValue[depth] = rangeStart;\n options.push([...currentOptionValue]);\n }\n // indicates the range has been processed\n rangeStart = null;\n }\n\n currentOptionValue[depth] = optionValueIndex;\n\n if (operation === V1_CONTROL_CHARS.RANGE) {\n // dash operation indicates we are in a range. e.g. 0-2 means option values 0, 1, 2\n rangeStart = optionValueIndex;\n } else if (operation === V1_CONTROL_CHARS.OPTION) {\n // colon operation indicates that we are moving down to the next layer of option values. e.g. 0:0:0-2 means we traverse down from option1 to option3 and represents [[0,0,0], [0,0,1], [0,0,2]]\n depth++;\n } else {\n if (\n operation === V1_CONTROL_CHARS.SEQUENCE_GAP ||\n (operation === V1_CONTROL_CHARS.END_OF_PREFIX &&\n encodedVariantField[token.index - 1] !==\n V1_CONTROL_CHARS.END_OF_PREFIX)\n ) {\n // add the current option value to the list of options if we hit a gap in our sequence or we are at the end of our depth and need to move back up\n options.push([...currentOptionValue]);\n }\n if (operation === V1_CONTROL_CHARS.END_OF_PREFIX) {\n // go up an option level, trash the last item in currentOptionValue\n currentOptionValue.pop();\n depth--;\n }\n }\n index = tokenizer.lastIndex;\n }\n\n // The while loop only iterates control characters, meaning if an encoded string ends with an index it will not be processed.\n const encodingEndsWithIndex = encodedVariantField.match(/\\d+$/g);\n if (encodingEndsWithIndex) {\n const finalValueIndex = parseInt(encodingEndsWithIndex[0]);\n if (rangeStart != null) {\n // process final range\n for (; rangeStart <= finalValueIndex; rangeStart++) {\n currentOptionValue[depth] = rangeStart;\n options.push([...currentOptionValue]);\n }\n } else {\n // process final index\n options.push([finalValueIndex]);\n }\n }\n\n return options;\n}\n","import {isOptionValueCombinationInEncodedVariant} from './optionValueDecoder.js';\nimport type {\n Product,\n ProductOption,\n ProductOptionValue,\n ProductVariant,\n SelectedOption,\n} from './storefront-api-types';\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: RecursivePartial<T[P]>;\n};\ntype ProductOptionsMapping = Record<string, number>;\ntype ProductOptionValueState = {\n variant: ProductVariant;\n handle: string;\n variantUriQuery: string;\n selected: boolean;\n exists: boolean;\n available: boolean;\n isDifferentProduct: boolean;\n};\ntype MappedProductOptionValue = ProductOptionValue & ProductOptionValueState;\n\n/**\n * Creates a mapping of product options to their index for matching encoded values\n * For example, a product option of\n * [\n * \\{\n * name: 'Color',\n * optionValues: [\\{name: 'Red'\\}, \\{name: 'Blue'\\}]\n * \\},\n * \\{\n * name: 'Size',\n * optionValues: [\\{name: 'Small'\\}, \\{name: 'Medium'\\}, \\{name: 'Large'\\}]\n * \\}\n * ]\n * Would return\n * [\n * \\{Red: 0, Blue: 1\\},\n * \\{Small: 0, Medium: 1, Large: 2\\}\n * ]\n */\nfunction mapProductOptions(options: ProductOption[]): ProductOptionsMapping[] {\n return options.map((option: ProductOption) => {\n return Object.assign(\n {},\n ...(option?.optionValues\n ? option.optionValues.map((value, index) => {\n return {[value.name]: index};\n })\n : []),\n ) as ProductOptionsMapping;\n });\n}\n\n/**\n * Converts the product option into an Object\\<key, value\\> for building query params\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n */\nexport function mapSelectedProductOptionToObject(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): Record<string, string> {\n return Object.assign(\n {},\n ...options.map((key) => {\n return {[key.name]: key.value};\n }),\n ) as Record<string, string>;\n}\n\n/**\n * Returns the JSON stringify result of mapSelectedProductOptionToObject\n */\nfunction mapSelectedProductOptionToObjectAsString(\n options: Pick<SelectedOption, 'name' | 'value'>[],\n): string {\n return JSON.stringify(mapSelectedProductOptionToObject(options));\n}\n\n/**\n * Encode the selected product option as a key for mapping to the encoded variants\n * For example, a selected product option of\n * [\n * \\{\n * name: 'Color',\n * value: 'Red',\n * \\},\n * \\{\n * name: 'Size',\n * value: 'Medium',\n * \\}\n * ]\n * Would return\n * [0,1]\n *\n * Also works with the result of mapSelectedProductOption. For example:\n * \\{\n * Color: 'Red',\n * Size: 'Medium',\n * \\}\n * Would return\n * [0,1]\n *\n * @param selectedOption - The selected product option\n * @param productOptionMappings - The result of product option mapping from mapProductOptions\n * @returns\n */\nfunction encodeSelectedProductOptionAsKey(\n selectedOption:\n | Pick<SelectedOption, 'name' | 'value'>[]\n | Record<string, string>,\n productOptionMappings: ProductOptionsMapping[],\n): string {\n if (Array.isArray(selectedOption)) {\n return JSON.stringify(\n selectedOption.map((key, index) => {\n return productOptionMappings[index][key.value];\n }),\n );\n } else {\n return JSON.stringify(\n Object.keys(selectedOption).map((key, index) => {\n return productOptionMappings[index][selectedOption[key]];\n }),\n );\n }\n}\n\n/**\n * Takes an array of product variants and maps them to an object with the encoded selected option values as the key.\n * For example, a product variant of\n * [\n * \\{\n * id: 1,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Small'\\},\n * ],\n * \\},\n * \\{\n * id: 2,\n * selectedOptions: [\n * \\{name: 'Color', value: 'Red'\\},\n * \\{name: 'Size', value: 'Medium'\\},\n * ],\n * \\}\n * ]\n * Would return\n * \\{\n * '[0,0]': \\{id: 1, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Small'\\}]\\},\n * '[0,1]': \\{id: 2, selectedOptions: [\\{name: 'Color', value: 'Red'\\}, \\{name: 'Size', value: 'Medium'\\}]\\},\n * \\}\n */\nfunction mapVariants(\n variants: ProductVariant[],\n productOptionMappings: ProductOptionsMapping[],\n): Record<string, ProductVariant> {\n return Object.assign(\n {},\n ...variants.map((variant) => {\n const variantKey = encodeSelectedProductOptionAsKey(\n variant.selectedOptions || [],\n productOptionMappings,\n );\n return {[variantKey]: variant};\n }),\n ) as Record<string, ProductVariant>;\n}\n\nexport type MappedProductOptions = Omit<ProductOption, 'optionValues'> & {\n optionValues: MappedProductOptionValue[];\n};\n\nconst PRODUCT_INPUTS = [\n 'options',\n 'selectedOrFirstAvailableVariant',\n 'adjacentVariants',\n];\n\nconst PRODUCT_INPUTS_EXTRA = [\n 'handle',\n 'encodedVariantExistence',\n 'encodedVariantAvailability',\n];\n\nfunction logErrorAndReturnFalse(key: string): boolean {\n console.error(\n `[h2:error:getProductOptions] product.${key} is missing. Make sure you query for this field from the Storefront API.`,\n );\n return false;\n}\n\nexport function checkProductParam(\n product: RecursivePartial<Product>,\n checkAll = false,\n): Product {\n let validParam = true;\n const productKeys = Object.keys(product);\n\n // Check product input\n (checkAll\n ? [...PRODUCT_INPUTS, ...PRODUCT_INPUTS_EXTRA]\n : PRODUCT_INPUTS\n ).forEach((key) => {\n if (!productKeys.includes(key)) {\n validParam = logErrorAndReturnFalse(key);\n }\n });\n\n // Check for nested options requirements\n if (product.options) {\n const firstOption = product?.options[0];\n\n if (checkAll && !firstOption?.name) {\n validParam = logErrorAndReturnFalse('options.name');\n }\n\n // Check for options.optionValues\n if (product?.options[0]?.optionValues) {\n let firstOptionValues = product.options[0].optionValues[0];\n\n // Check for options.optionValues.name\n if (checkAll && !firstOptionValues?.name) {\n validParam = logErrorAndReturnFalse('options.optionValues.name');\n }\n\n // It is possible for firstSelectableVariant to be null\n firstOptionValues = product.options[0].optionValues.filter(\n (value) => !!value?.firstSelectableVariant,\n )[0];\n\n // Check for options.optionValues.firstSelectableVariant\n if (firstOptionValues?.firstSelectableVariant) {\n // check product variant\n validParam = checkProductVariantParam(\n firstOptionValues.firstSelectableVariant,\n 'options.optionValues.firstSelectableVariant',\n validParam,\n checkAll,\n );\n }\n } else {\n validParam = logErrorAndReturnFalse('options.optionValues');\n }\n }\n\n // Check for nested selectedOrFirstAvailableVariant requirements\n if (product.selectedOrFirstAvailableVariant) {\n validParam = checkProductVariantParam(\n product.selectedOrFirstAvailableVariant,\n 'selectedOrFirstAvailableVariant',\n validParam,\n checkAll,\n );\n }\n\n // Check for nested adjacentVariants requirements\n if (!!product.adjacentVariants && product.adjacentVariants[0]) {\n validParam = checkProductVariantParam(\n product.adjacentVariants[0],\n 'adjacentVariants',\n validParam,\n checkAll,\n );\n }\n\n return (validParam ? product : {}) as Product;\n}\n\nfunction checkProductVariantParam(\n variant: RecursivePartial<ProductVariant>,\n key: string,\n currentValidParamState: boolean,\n checkAll: boolean,\n): boolean {\n let validParam = currentValidParamState;\n\n if (checkAll && !variant.product?.handle) {\n validParam = logErrorAndReturnFalse(`${key}.product.handle`);\n }\n if (variant.selectedOptions) {\n const firstSelectedOption = variant.selectedOptions[0];\n if (!firstSelectedOption?.name) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.name`);\n }\n if (!firstSelectedOption?.value) {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions.value`);\n }\n } else {\n validParam = logErrorAndReturnFalse(`${key}.selectedOptions`);\n }\n\n return validParam;\n}\n\n/**\n * Finds all the variants provided by adjacentVariants, options.optionValues.firstAvailableVariant,\n * and selectedOrFirstAvailableVariant and return them in a single array\n */\nexport function getAdjacentAndFirstAvailableVariants(\n product: RecursivePartial<Product>,\n): ProductVariant[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product);\n\n if (!checkedProduct.options) return [];\n\n const availableVariants: Record<string, ProductVariant> = {};\n checkedProduct.options.map((option) => {\n option.optionValues?.map((value) => {\n if (value.firstSelectableVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n value.firstSelectableVariant.selectedOptions,\n );\n availableVariants[variantKey] = value.firstSelectableVariant;\n }\n });\n });\n\n checkedProduct.adjacentVariants.map((variant) => {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n variant.selectedOptions,\n );\n availableVariants[variantKey] = variant;\n });\n\n const selectedVariant = checkedProduct.selectedOrFirstAvailableVariant;\n if (selectedVariant) {\n const variantKey = mapSelectedProductOptionToObjectAsString(\n selectedVariant.selectedOptions,\n );\n availableVariants[variantKey] = selectedVariant;\n }\n\n return Object.values(availableVariants);\n}\n\n/**\n * Returns a product options array with its relevant information\n * about the variant\n */\nexport function getProductOptions(\n product: RecursivePartial<Product>,\n): MappedProductOptions[] {\n // Checks for valid product input\n const checkedProduct = checkProductParam(product, true);\n\n if (!checkedProduct.options) return [];\n\n const {\n options,\n selectedOrFirstAvailableVariant: selectedVariant,\n adjacentVariants,\n encodedVariantExistence,\n encodedVariantAvailability,\n handle: productHandle,\n } = checkedProduct;\n // Get a mapping of product option names to their index for matching encoded values\n const productOptionMappings = mapProductOptions(options);\n\n // Get the adjacent variants mapped to the encoded selected option values\n const variants = mapVariants(\n selectedVariant ? [selectedVariant, ...adjacentVariants] : adjacentVariants,\n productOptionMappings,\n );\n\n // Get the key:value version of selected options for building url query params\n const selectedOptions = mapSelectedProductOptionToObject(\n selectedVariant ? selectedVariant.selectedOptions : [],\n );\n\n const productOptions = options.map((option, optionIndex) => {\n return {\n ...option,\n optionValues: option.optionValues.map((value) => {\n const targetOptionParams = {...selectedOptions}; // Clones the selected options\n\n // Modify the selected option value to the current option value\n targetOptionParams[option.name] = value.name;\n\n // Encode the new selected option values as a key for mapping to the product variants\n const targetKey = encodeSelectedProductOptionAsKey(\n targetOptionParams || [],\n productOptionMappings,\n );\n\n // Top-down option check for existence and availability\n const topDownKey = (JSON.parse(targetKey) as number[]).slice(\n 0,\n optionIndex + 1,\n );\n const exists = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantExistence || '',\n );\n const available = isOptionValueCombinationInEncodedVariant(\n topDownKey,\n encodedVariantAvailability || '',\n );\n\n // Get the variant for the current option value if exists, else use the first selectable variant\n const variant: ProductVariant =\n variants[targetKey] || value.firstSelectableVariant;\n\n // Build the query params for this option value\n let variantOptionParam = {};\n if (variant) {\n variantOptionParam = mapSelectedProductOptionToObject(\n variant.selectedOptions || [],\n );\n }\n const searchParams = new URLSearchParams(variantOptionParam);\n const handle = variant?.product?.handle || productHandle;\n\n return {\n ...value,\n variant,\n handle,\n variantUriQuery: searchParams.toString(),\n selected: selectedOptions[option.name] === value.name,\n exists,\n available,\n isDifferentProduct: handle !== productHandle,\n };\n }),\n };\n });\n\n return productOptions;\n}\n","/* eslint-disable eslint-comments/disable-enable-pair */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable hydrogen/prefer-image-component */\nimport * as React from 'react';\nimport type {PartialDeep} from 'type-fest';\nimport type {Image as ImageType} from './storefront-api-types.js';\n\n/*\n * An optional prop you can use to change the\n * default srcSet generation behaviour\n */\ntype SrcSetOptions = {\n /** The number of sizes to generate */\n intervals: number;\n /** The smallest image size */\n startingWidth: number;\n /** The increment by which to increase for each size, in pixels */\n incrementSize: number;\n /** The size used for placeholder fallback images */\n placeholderWidth: number;\n};\n\ntype NormalizedProps = {\n alt: string;\n aspectRatio: string | undefined;\n height: string;\n src: string | undefined;\n width: string;\n};\n\nexport type LoaderParams = {\n /** The base URL of the image */\n src?: ImageType['url'];\n /** The URL param that controls width */\n width?: number;\n /** The URL param that controls height */\n height?: number;\n /** The URL param that controls the cropping region */\n crop?: Crop;\n};\n\nexport type Loader = (params: LoaderParams) => string;\n\n/*\n * @TODO: Expand to include focal point support; and/or switch this to be an SF API type\n */\ntype Crop = 'center' | 'top' | 'bottom' | 'left' | 'right';\n\nexport type HydrogenImageProps = React.ComponentPropsWithRef<'img'> &\n HydrogenImageBaseProps;\n\ntype HydrogenImageBaseProps = {\n /** The aspect ratio of the image, in the format of `width/height`.\n *\n * @example\n * ```\n * <Image data={productImage} aspectRatio=\"4/5\" />\n * ```\n */\n aspectRatio?: string;\n /** The crop position of the image.\n *\n * @remarks\n * In the event that AspectRatio is set, without specifying a crop,\n * the Shopify CDN won't return the expected image.\n *\n * @defaultValue `center`\n */\n crop?: Crop;\n /** Data mapping to the [Storefront API `Image`](https://shopify.dev/docs/api/storefront/2025-01/objects/Image) object. Must be an Image object.\n *\n * @example\n * ```\n * import {IMAGE_FRAGMENT, Image} from '@shopify/hydrogen';\n *\n * export const IMAGE_QUERY = `#graphql\n * ${IMAGE_FRAGMENT}\n * query {\n * product {\n * featuredImage {\n * ...Image\n * }\n * }\n * }`\n *\n * <Image\n * data={productImage}\n * sizes=\"(min-width: 45em) 50vw, 100vw\"\n * aspectRatio=\"4/5\"\n * />\n * ```\n *\n * Image: {@link https://shopify.dev/api/storefront/reference/common-objects/image}\n */\n data?: PartialDeep<ImageType, {recurseIntoArrays: true}>;\n /** A function that returns a URL string for an image.\n *\n * @remarks\n * By default, this uses Shopify’s CDN {@link https://cdn.shopify.com/} but you can provide\n * your own function to use a another provider, as long as they support URL based image transformations.\n */\n loader?: Loader;\n /** An optional prop you can use to change the default srcSet generation behaviour */\n srcSetOptions?: SrcSetOptions;\n};\n\n/**\n * A Storefront API GraphQL fragment that can be used to query for an image.\n */\nexport const IMAGE_FRAGMENT = `#graphql\n fragment Image on Image {\n altText\n url\n width\n height\n }\n`;\n\n/**\n * Hydrogen’s Image component is a wrapper around the HTML image element.\n * It supports the same props as the HTML `img` element, but automatically\n * generates the srcSet and sizes attributes for you. For most use cases,\n * you’ll want to set the `aspectRatio` prop to ensure the image is sized\n * correctly.\n *\n * @remarks\n * - `decoding` is set to `async` by default.\n * - `loading` is set to `lazy` by default.\n * - `alt` will automatically be set to the `altText` from the Storefront API if passed in the `data` prop\n * - `src` will automatically be set to the `url` from the Storefront API if passed in the `data` prop\n *\n * @example\n * A responsive image with a 4:5 aspect ratio:\n * ```\n * <Image\n * data={product.featuredImage}\n * aspectRatio=\"4/5\"\n * sizes=\"(min-width: 45em) 40vw, 100vw\"\n * />\n * ```\n * @example\n * A fixed size image:\n * ```\n * <Image\n * data={product.featuredImage}\n * width={100}\n * height={100}\n * />\n * ```\n *\n * {@link https://shopify.dev/docs/api/hydrogen-react/components/image}\n */\nexport const Image = React.forwardRef<HTMLImageElement, HydrogenImageProps>(\n (\n {\n alt,\n aspectRatio,\n crop = 'center',\n data,\n decoding = 'async',\n height = 'auto',\n loader = shopifyLoader,\n loading = 'lazy',\n sizes,\n src,\n srcSetOptions = {\n intervals: 15,\n startingWidth: 200,\n incrementSize: 200,\n placeholderWidth: 100,\n },\n width = '100%',\n ...passthroughProps\n },\n ref,\n ) => {\n /*\n * Gets normalized values for width, height from data prop\n */\n const normalizedData = React.useMemo(() => {\n /* Only use data width if height is also set */\n const dataWidth: number | undefined =\n data?.width && data?.height ? data?.width : undefined;\n\n const dataHeight: number | undefined =\n data?.width && data?.height ? data?.height : undefined;\n\n return {\n width: dataWidth,\n height: dataHeight,\n unitsMatch: Boolean(unitsMatch(dataWidth, dataHeight)),\n };\n }, [data]);\n\n /*\n * Gets normalized values for width, height, src, alt, and aspectRatio props\n * supporting the presence of `data` in addition to flat props.\n */\n const normalizedProps = React.useMemo(() => {\n const nWidthProp: string | number = width || '100%';\n const widthParts = getUnitValueParts(nWidthProp.toString());\n const nWidth = `${widthParts.number}${widthParts.unit}`;\n\n const autoHeight = height === undefined || height === null;\n const heightParts = autoHeight\n ? null\n : getUnitValueParts(height.toString());\n\n const fixedHeight = heightParts\n ? `${heightParts.number}${heightParts.unit}`\n : '';\n\n const nHeight = autoHeight ? 'auto' : fixedHeight;\n\n const nSrc: string | undefined = src || data?.url;\n\n if (__HYDROGEN_DEV__ && !nSrc) {\n console.warn(\n `No src or data.url provided to Image component.`,\n passthroughProps?.key || '',\n );\n }\n\n const nAlt: string = data?.altText && !alt ? data?.altText : alt || '';\n\n const nAspectRatio: string | undefined = aspectRatio\n ? aspectRatio\n : normalizedData.unitsMatch\n ? [\n getNormalizedFixedUnit(normalizedData.width),\n getNormalizedFixedUnit(normalizedData.height),\n ].join('/')\n : undefined;\n\n return {\n width: nWidth,\n height: nHeight,\n src: nSrc,\n alt: nAlt,\n aspectRatio: nAspectRatio,\n };\n }, [\n width,\n height,\n src,\n data,\n alt,\n aspectRatio,\n normalizedData,\n passthroughProps?.key,\n ]);\n\n const {intervals, startingWidth, incrementSize, placeholderWidth} =\n srcSetOptions;\n\n /*\n * This function creates an array of widths to be used in srcSet\n */\n const imageWidths = React.useMemo(() => {\n return generateImageWidths(\n width,\n intervals,\n startingWidth,\n incrementSize,\n );\n }, [width, intervals, startingWidth, incrementSize]);\n\n const fixedWidth = isFixedWidth(normalizedProps.width);\n\n if (__HYDROGEN_DEV__ && !sizes && !fixedWidth) {\n console.warn(\n [\n 'No sizes prop provided to Image component,',\n 'you may be loading unnecessarily large images.',\n `Image used is ${\n src || data?.url || passthroughProps?.key || 'unknown'\n }`,\n ].join(' '),\n );\n }\n\n /*\n * We check to see whether the image is fixed width or not,\n * if fixed, we still provide a srcSet, but only to account for\n * different pixel densities.\n */\n if (fixedWidth) {\n return (\n <FixedWidthImage\n aspectRatio={aspectRatio}\n crop={crop}\n decoding={decoding}\n height={height}\n imageWidths={imageWidths}\n loader={loader}\n loading={loading}\n normalizedProps={normalizedProps}\n passthroughProps={passthroughProps}\n ref={ref}\n width={width}\n data={data}\n />\n );\n } else {\n return (\n <FluidImage\n aspectRatio={aspectRatio}\n crop={crop}\n decoding={decoding}\n imageWidths={imageWidths}\n loader={loader}\n loading={loading}\n normalizedProps={normalizedProps}\n passthroughProps={passthroughProps}\n placeholderWidth={placeholderWidth}\n ref={ref}\n sizes={sizes}\n data={data}\n />\n );\n }\n },\n);\n\ntype FixedImageExludedProps =\n | 'data'\n | 'loader'\n | 'loaderOptions'\n | 'sizes'\n | 'srcSetOptions'\n | 'widths';\n\ntype FixedWidthImageProps = Omit<HydrogenImageProps, FixedImageExludedProps> &\n Pick<HydrogenImageBaseProps, 'data'> & {\n loader: Loader;\n passthroughProps: React.ImgHTMLAttributes<HTMLImageElement>;\n normalizedProps: NormalizedProps;\n imageWidths: number[];\n ref: React.Ref<HTMLImageElement>;\n };\n\nconst FixedWidthImage = React.forwardRef<\n HTMLImageElement,\n FixedWidthImageProps\n>(\n (\n {\n aspectRatio,\n crop,\n decoding,\n height,\n imageWidths,\n loader = shopifyLoader,\n loading,\n normalizedProps,\n passthroughProps,\n width,\n data,\n },\n ref,\n ) => {\n const fixed = React.useMemo(() => {\n const intWidth: number | undefined = getNormalizedFixedUnit(width);\n const intHeight: number | undefined = getNormalizedFixedUnit(height);\n\n /*\n * The aspect ratio for fixed width images is taken from the explicitly\n * set prop, but if that's not present, and both width and height are\n * set, we calculate the aspect ratio from the width and height—as\n * long as they share the same unit type (e.g. both are 'px').\n */\n const fixedAspectRatio = aspectRatio\n ? aspectRatio\n : unitsMatch(normalizedProps.width, normalizedProps.height)\n ? [intWidth, intHeight].join('/')\n : normalizedProps.aspectRatio\n ? normalizedProps.aspectRatio\n : undefined;\n\n /*\n * The Sizes Array generates an array of all the parts\n * that make up the srcSet, including the width, height, and crop\n */\n const sizesArray =\n imageWidths === undefined\n ? undefined\n : generateSizes(imageWidths, fixedAspectRatio, crop, {\n width: data?.width ?? undefined,\n height: data?.height ?? undefined,\n });\n\n const fixedHeight = intHeight\n ? intHeight\n : fixedAspectRatio && intWidth\n ? intWidth * (parseAspectRatio(fixedAspectRatio) ?? 1)\n : undefined;\n\n const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);\n const src = loader({\n src: normalizedProps.src,\n width: intWidth,\n height: fixedHeight,\n crop: normalizedProps.height === 'auto' ? undefined : crop,\n });\n\n return {\n width: intWidth,\n aspectRatio: fixedAspectRatio,\n height: fixedHeight,\n srcSet,\n src,\n };\n }, [\n aspectRatio,\n crop,\n data,\n height,\n imageWidths,\n loader,\n normalizedProps,\n width,\n ]);\n\n return (\n <img\n ref={ref}\n alt={normalizedProps.alt}\n decoding={decoding}\n height={fixed.height}\n loading={loading}\n src={fixed.src}\n srcSet={fixed.srcSet}\n width={fixed.width}\n style={{\n aspectRatio: fixed.aspectRatio,\n ...passthroughProps.style,\n }}\n {...passthroughProps}\n />\n );\n },\n);\n\ntype FluidImageExcludedProps =\n | 'data'\n | 'width'\n | 'height'\n | 'loader'\n | 'loaderOptions'\n | 'srcSetOptions';\n\ntype FluidImageProps = Omit<HydrogenImageProps, FluidImageExcludedProps> &\n Pick<HydrogenImageBaseProps, 'data'> & {\n imageWidths: number[];\n loader: Loader;\n normalizedProps: NormalizedProps;\n passthroughProps: React.ImgHTMLAttributes<HTMLImageElement>;\n placeholderWidth: number;\n ref: React.Ref<HTMLImageElement>;\n };\n\nconst FluidImage = React.forwardRef<HTMLImageElement, FluidImageProps>(\n (\n {\n crop,\n decoding,\n imageWidths,\n loader = shopifyLoader,\n loading,\n normalizedProps,\n passthroughProps,\n placeholderWidth,\n sizes,\n data,\n },\n ref,\n ) => {\n const fluid = React.useMemo(() => {\n const sizesArray =\n imageWidths === undefined\n ? undefined\n : generateSizes(imageWidths, normalizedProps.aspectRatio, crop, {\n width: data?.width ?? undefined,\n height: data?.height ?? undefined,\n });\n\n const placeholderHeight =\n normalizedProps.aspectRatio && placeholderWidth\n ? placeholderWidth *\n (parseAspectRatio(normalizedProps.aspectRatio) ?? 1)\n : undefined;\n\n const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);\n\n const src = loader({\n src: normalizedProps.src,\n width: placeholderWidth,\n height: placeholderHeight,\n crop,\n });\n\n return {\n placeholderHeight,\n srcSet,\n src,\n };\n }, [crop, data, imageWidths, loader, normalizedProps, placeholderWidth]);\n\n return (\n <img\n ref={ref}\n alt={normalizedProps.alt}\n decoding={decoding}\n height={fluid.placeholderHeight}\n loading={loading}\n sizes={sizes}\n src={fluid.src}\n srcSet={fluid.srcSet}\n width={placeholderWidth}\n {...passthroughProps}\n style={{\n width: normalizedProps.width,\n aspectRatio: normalizedProps.aspectRatio,\n ...passthroughProps.style,\n }}\n />\n );\n },\n);\n\n/**\n * The shopifyLoader function is a simple utility function that takes a src, width,\n * height, and crop and returns a string that can be used as the src for an image.\n * It can be used with the Hydrogen Image component or with the next/image component.\n * (or any others that accept equivalent configuration)\n * @param src - The source URL of the image, e.g. `https://cdn.shopify.com/static/sample-images/garnished.jpeg`\n * @param width - The width of the image, e.g. `100`\n * @param height - The height of the image, e.g. `100`\n * @param crop - The crop of the image, e.g. `center`\n * @returns A Shopify image URL with the correct query parameters, e.g. `https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=100&height=100&crop=center`\n *\n * @example\n * ```\n * shopifyLoader({\n * src: 'https://cdn.shopify.com/static/sample-images/garnished.jpeg',\n * width: 100,\n * height: 100,\n * crop: 'center',\n * })\n * ```\n */\nconst PLACEHOLDER_DOMAIN = 'https://placeholder.shopify.com';\nexport function shopifyLoader({src, width, height, crop}: LoaderParams) {\n if (!src) {\n return '';\n }\n\n const url = new URL(src, PLACEHOLDER_DOMAIN);\n\n if (width) {\n url.searchParams.append('width', Math.round(width).toString());\n }\n\n if (height) {\n url.searchParams.append('height', Math.round(height).toString());\n }\n\n if (crop) {\n url.searchParams.append('crop', crop);\n }\n return url.href.replace(PLACEHOLDER_DOMAIN, '');\n}\n\n/**\n * Checks whether the width and height share the same unit type\n * @param width - The width of the image, e.g. 100% | 10px\n * @param height - The height of the image, e.g. auto | 100px\n * @returns Whether the width and height share the same unit type (boolean)\n */\nfunction unitsMatch(\n width: string | number = '100%',\n height: string | number = 'auto',\n): boolean {\n return (\n getUnitValueParts(width.toString()).unit ===\n getUnitValueParts(height.toString()).unit\n );\n}\n\n/**\n * Given a CSS size, returns the unit and number parts of the value\n * @param value - The CSS size, e.g. 100px\n * @returns The unit and number parts of the value, e.g. \\{unit: 'px', number: 100\\}\n */\nfunction getUnitValueParts(value: string): {unit: string; number: number} {\n const unit = value.replace(/[0-9.]/g, '');\n const number = parseFloat(value.replace(unit, ''));\n\n return {\n unit: unit === '' ? (number === undefined ? 'auto' : 'px') : unit,\n number,\n };\n}\n\n/**\n * Given a value, returns the width of the image as an integer in pixels\n * @param value - The width of the image, e.g. 16px | 1rem | 1em | 16\n * @returns The width of the image in pixels, e.g. 16, or undefined if the value is not a fixed unit\n */\nfunction getNormalizedFixedUnit(value?: string | number): number | undefined {\n if (value === undefined) {\n return;\n }\n\n const {unit, number} = getUnitValueParts(value.toString());\n\n switch (unit) {\n case 'em':\n return number * 16;\n case 'rem':\n return number * 16;\n case 'px':\n return number;\n case '':\n return number;\n default:\n return;\n }\n}\n\n/**\n * This function checks whether a width is fixed or not.\n * @param width - The width of the image, e.g. 100 | '100px' | '100em' | '100rem'\n * @returns Whether the width is fixed or not\n */\nfunction isFixedWidth(width: string | number): boolean {\n const fixedEndings = /\\d(px|em|rem)$/;\n return typeof width === 'number' || fixedEndings.test(width);\n}\n\n/**\n * This function generates a srcSet for Shopify images.\n * @param src - The source URL of the image, e.g. https://cdn.shopify.com/static/sample-images/garnished.jpeg\n * @param sizesArray - An array of objects containing the `width`, `height`, and `crop` of the image, e.g. [\\{width: 200, height: 200, crop: 'center'\\}, \\{width: 400, height: 400, crop: 'center'\\}]\n * @param loader - A function that takes a Shopify image URL and returns a Shopify image URL with the correct query parameters\n * @returns A srcSet for Shopify images, e.g. 'https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=200&height=200&crop=center 200w, https://cdn.shopify.com/static/sample-images/garnished.jpeg?width=400&height=400&crop=center 400w'\n */\nexport function generateSrcSet(\n src?: string,\n sizesArray?: Array<{width?: number; height?: number; crop?: Crop}>,\n loader: Loader = shopifyLoader,\n): string {\n if (!src) {\n return '';\n }\n\n if (sizesArray?.length === 0 || !sizesArray) {\n return src;\n }\n\n return sizesArray\n .map(\n (size, i) =>\n `${loader({\n src,\n width: size.width,\n height: size.height,\n crop: size.crop,\n })} ${sizesArray.length === 3 ? `${i + 1}x` : `${size.width ?? 0}w`}`,\n )\n .join(`, `);\n}\n\n/**\n * This function generates an array of sizes for Shopify images, for both fixed and responsive images.\n * @param width - The CSS width of the image\n * @param intervals - The number of intervals to generate\n * @param startingWidth - The starting width of the image\n * @param incrementSize - The size of each interval\n * @returns An array of widths\n */\nexport function generateImageWidths(\n width: string | number = '100%',\n intervals: number,\n startingWidth: number,\n incrementSize: number,\n): number[] {\n const responsive = Array.from(\n {length: intervals},\n (_, i) => i * incrementSize + startingWidth,\n );\n\n const fixed = Array.from(\n {length: 3},\n (_, i) => (i + 1) * (getNormalizedFixedUnit(width) ?? 0),\n );\n\n return isFixedWidth(width) ? fixed : responsive;\n}\n\n/**\n * Simple utility function to convert an aspect ratio CSS string to a decimal, currently only supports values like `1/1`, not `0.5`, or `auto`\n * @param aspectRatio - The aspect ratio of the image, e.g. `1/1`\n * @returns The aspect ratio as a number, e.g. `0.5`\n *\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio}\n */\nexport function parseAspectRatio(aspectRatio?: string): number | undefined {\n if (!aspectRatio) return;\n const [width, height] = aspectRatio.split('/');\n return 1 / (Number(width) / Number(height));\n}\n\n// Generate data needed for Imagery loader\nexport function generateSizes(\n imageWidths?: number[],\n aspectRatio?: string,\n crop: Crop = 'center',\n sourceDimensions?: {width?: number; height?: number},\n):\n | {\n width: number;\n height: number | undefined;\n crop: Crop;\n }[]\n | undefined {\n if (!imageWidths) return;\n return imageWidths\n .map((width: number) => {\n return {\n width,\n height: aspectRatio\n ? width * (parseAspectRatio(aspectRatio) ?? 1)\n : undefined,\n crop,\n };\n })\n .filter(({width, height}) => {\n if (sourceDimensions?.width && width > sourceDimensions.width) {\n return false;\n }\n\n if (\n sourceDimensions?.height &&\n height &&\n height > sourceDimensions.height\n ) {\n return false;\n }\n\n return true;\n });\n /*\n Given:\n ([100, 200], 1/1, 'center')\n Returns:\n [{width: 100, height: 100, crop: 'center'},\n {width: 200, height: 200, crop: 'center'}]\n */\n}\n","import {useState, useEffect} from 'react';\n\nconst SCRIPTS_LOADED: Record<string, Promise<boolean>> = {};\n\ntype LoadScriptOptions = {\n module?: boolean;\n in?: 'head' | 'body';\n attributes?: Record<string, string>;\n};\n\nexport function loadScript(\n src: string,\n options?: LoadScriptOptions,\n): Promise<boolean> {\n const isScriptLoaded = SCRIPTS_LOADED[src];\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n if (isScriptLoaded) {\n return isScriptLoaded;\n }\n\n const promise = new Promise<boolean>((resolve, reject) => {\n const script = document.createElement('script');\n if (options?.module) {\n script.type = 'module';\n } else {\n script.type = 'text/javascript';\n }\n script.src = src;\n script.onload = (): void => {\n resolve(true);\n };\n script.onerror = (): void => {\n reject(false);\n };\n if (options?.in === 'head') {\n document.head.appendChild(script);\n } else {\n document.body.appendChild(script);\n }\n\n const attributes = options?.attributes;\n if (attributes) {\n Object.keys(attributes).forEach((key) => {\n script.setAttribute(key, attributes[key]);\n });\n }\n });\n\n SCRIPTS_LOADED[src] = promise;\n\n return promise;\n}\n\ntype LoadScriptParams = Parameters<typeof loadScript>;\n\n/**\n * The `useLoadScript` hook loads an external script tag in the browser. It allows React components to lazy-load large third-party dependencies.\n */\nexport function useLoadScript(\n url: LoadScriptParams[0],\n options?: LoadScriptParams[1],\n): ScriptState {\n const [status, setStatus] = useState<ScriptState>('loading');\n\n useEffect(\n () => {\n loadScript(url, options)\n .then(() => setStatus('done'))\n .catch(() => setStatus('error'));\n },\n // Ignore options changes since it won't trigger a new load.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [url],\n );\n\n return status;\n}\n\ntype ScriptState = 'loading' | 'done' | 'error';\n","import {forwardRef, type HTMLAttributes} from 'react';\nimport {shopifyLoader} from './Image.js';\nimport type {Video as VideoType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\nexport interface VideoProps {\n /** An object with fields that correspond to the Storefront API's [Video object](https://shopify.dev/api/storefront/2025-01/objects/video). */\n data: PartialDeep<VideoType, {recurseIntoArrays: true}>;\n /** An object of image size options for the video's `previewImage`. Uses `shopifyImageLoader` to generate the `poster` URL. */\n previewImageOptions?: Parameters<typeof shopifyLoader>[0];\n /** Props that will be passed to the `video` element's `source` children elements. */\n sourceProps?: HTMLAttributes<HTMLSourceElement> & {\n 'data-testid'?: string;\n };\n}\n\n/**\n * The `Video` component renders a `video` for the Storefront API's [Video object](https://shopify.dev/api/storefront/reference/products/video).\n */\nexport const Video = forwardRef<\n HTMLVideoElement,\n JSX.IntrinsicElements['video'] & VideoProps\n>((props, ref): JSX.Element => {\n const {\n data,\n previewImageOptions,\n id = data.id,\n playsInline = true,\n controls = true,\n sourceProps = {},\n ...passthroughProps\n } = props;\n\n const posterUrl = shopifyLoader({\n src: data.previewImage?.url ?? '',\n ...previewImageOptions,\n });\n\n if (!data.sources) {\n throw new Error(`<Video/> requires a 'data.sources' array`);\n }\n\n return (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n {...passthroughProps}\n id={id}\n playsInline={playsInline}\n controls={controls}\n poster={posterUrl}\n ref={ref}\n >\n {data.sources.map((source) => {\n if (!(source?.url && source?.mimeType)) {\n throw new Error(`<Video/> needs 'source.url' and 'source.mimeType'`);\n }\n return (\n <source\n {...sourceProps}\n key={source.url}\n src={source.url}\n type={source.mimeType}\n />\n );\n })}\n </video>\n );\n});\n","import {useState, useEffect, useCallback} from 'react';\nimport {useLoadScript} from './load-script.js';\nimport type {Model3d} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n interface IntrinsicElements {\n 'model-viewer': PartialDeep<\n ModelViewerElement,\n {recurseIntoArrays: true}\n >;\n }\n }\n}\n\ntype ModelViewerProps = Omit<\n PartialDeep<JSX.IntrinsicElements['model-viewer'], {recurseIntoArrays: true}>,\n 'src'\n> &\n ModelViewerBaseProps;\n\ntype ModelViewerBaseProps = {\n /** An object with fields that correspond to the Storefront API's [Model3D object](https://shopify.dev/api/storefront/2025-01/objects/model3d). */\n data: PartialDeep<Model3d, {recurseIntoArrays: true}>;\n /** The callback to invoke when the 'error' event is triggered. Refer to [error in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-error). */\n onError?: (event: Event) => void;\n /** The callback to invoke when the `load` event is triggered. Refer to [load in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-load). */\n onLoad?: (event: Event) => void;\n /** The callback to invoke when the 'preload' event is triggered. Refer to [preload in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-preload). */\n onPreload?: (event: Event) => void;\n /** The callback to invoke when the 'model-visibility' event is triggered. Refer to [model-visibility in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-modelVisibility). */\n onModelVisibility?: (event: Event) => void;\n /** The callback to invoke when the 'progress' event is triggered. Refer to [progress in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-loading-events-progress). */\n onProgress?: (event: Event) => void;\n /** The callback to invoke when the 'ar-status' event is triggered. Refer to [ar-status in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-arStatus). */\n onArStatus?: (event: Event) => void;\n /** The callback to invoke when the 'ar-tracking' event is triggered. Refer to [ar-tracking in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-arTracking). */\n onArTracking?: (event: Event) => void;\n /** The callback to invoke when the 'quick-look-button-tapped' event is triggered. Refer to [quick-look-button-tapped in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-events-quickLookButtonTapped). */\n onQuickLookButtonTapped?: (event: Event) => void;\n /** The callback to invoke when the 'camera-change' event is triggered. Refer to [camera-change in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-stagingandcameras-events-cameraChange). */\n onCameraChange?: (event: Event) => void;\n /** The callback to invoke when the 'environment-change' event is triggered. Refer to [environment-change in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-lightingandenv-events-environmentChange). */\n onEnvironmentChange?: (event: Event) => void;\n /** The callback to invoke when the 'play' event is triggered. Refer to [play in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-animation-events-play). */\n onPlay?: (event: Event) => void;\n /** The callback to invoke when the 'pause' event is triggered. Refer to [pause in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-animation-events-pause). */\n onPause?: (event: Event) => void;\n /** The callback to invoke when the 'scene-graph-ready' event is triggered. Refer to [scene-graph-ready in the <model-viewer> documentation](https://modelviewer.dev/docs/index.html#entrydocs-scenegraph-events-sceneGraphReady). */\n onSceneGraphReady?: (event: Event) => void;\n};\n\n/**\n * The `ModelViewer` component renders a 3D model (with the `model-viewer` custom element) for\n * the Storefront API's [Model3d object](https://shopify.dev/api/storefront/reference/products/model3d).\n *\n * The `model-viewer` custom element is lazily downloaded through a dynamically-injected `<script type=\"module\">` tag when the `<ModelViewer />` component is rendered\n *\n * ModelViewer is using version `1.21.1` of the `@google/model-viewer` library.\n */\nexport function ModelViewer(props: ModelViewerProps): JSX.Element | null {\n const [modelViewer, setModelViewer] = useState<undefined | HTMLElement>(\n undefined,\n );\n const callbackRef = useCallback((node: HTMLElement) => {\n setModelViewer(node);\n }, []);\n const {data, children, className, ...passthroughProps} = props;\n\n const modelViewerLoadedStatus = useLoadScript(\n 'https://unpkg.com/@google/model-viewer@v1.12.1/dist/model-viewer.min.js',\n {\n module: true,\n },\n );\n\n useEffect(() => {\n const hydrogenEventListener = {\n error: passthroughProps.onError,\n load: passthroughProps.onLoad,\n preload: passthroughProps.onPreload,\n 'model-visibility': passthroughProps.onModelVisibility,\n progress: passthroughProps.onProgress,\n 'ar-status': passthroughProps.onArStatus,\n 'ar-tracking': passthroughProps.onArTracking,\n 'quick-look-button-tapped': passthroughProps.onQuickLookButtonTapped,\n 'camera-change': passthroughProps.onCameraChange,\n 'environment-change': passthroughProps.onEnvironmentChange,\n play: passthroughProps.onPlay,\n pause: passthroughProps.onPause,\n 'scene-graph-ready': passthroughProps.onSceneGraphReady,\n };\n\n if (!modelViewer) {\n return;\n }\n Object.entries(hydrogenEventListener).forEach(\n ([eventName, callbackFunc]) => {\n if (callbackFunc) {\n modelViewer.addEventListener(eventName, callbackFunc);\n }\n },\n );\n\n return () => {\n if (modelViewer == null) {\n return;\n }\n Object.entries(hydrogenEventListener).forEach(\n ([eventName, callbackFunc]) => {\n if (callbackFunc) {\n modelViewer.removeEventListener(eventName, callbackFunc);\n }\n },\n );\n };\n }, [\n modelViewer,\n passthroughProps.onArStatus,\n passthroughProps.onArTracking,\n passthroughProps.onCameraChange,\n passthroughProps.onEnvironmentChange,\n passthroughProps.onError,\n passthroughProps.onLoad,\n passthroughProps.onModelVisibility,\n passthroughProps.onPause,\n passthroughProps.onPlay,\n passthroughProps.onPreload,\n passthroughProps.onProgress,\n passthroughProps.onQuickLookButtonTapped,\n passthroughProps.onSceneGraphReady,\n ]);\n\n if (modelViewerLoadedStatus !== 'done') {\n // TODO: What do we want to display while the model-viewer library loads?\n return null;\n }\n\n if (!data.sources?.[0]?.url) {\n const sourcesUrlError = `<ModelViewer/> requires 'data.sources' prop to be an array, with an object that has a property 'url' on it. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(sourcesUrlError);\n } else {\n console.error(sourcesUrlError);\n return null;\n }\n }\n\n if (__HYDROGEN_DEV__ && !data.alt) {\n console.warn(\n `<ModelViewer/> requires the 'data.alt' prop for accessibility`,\n );\n }\n\n return (\n <model-viewer\n ref={callbackRef}\n {...passthroughProps}\n // @ts-expect-error src should exist\n // @eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n class={className}\n id={passthroughProps.id ?? data.id}\n src={data.sources[0].url}\n alt={data.alt ?? null}\n camera-controls={passthroughProps.cameraControls ?? true}\n poster={(passthroughProps.poster || data.previewImage?.url) ?? null}\n autoplay={passthroughProps.autoplay ?? true}\n loading={passthroughProps.loading}\n reveal={passthroughProps.reveal}\n ar={passthroughProps.ar}\n ar-modes={passthroughProps.arModes}\n ar-scale={passthroughProps.arScale}\n // @ts-expect-error arPlacement should exist as a type, not sure why it doesn't. https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-attributes-arPlacement\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ar-placement={passthroughProps.arPlacement}\n ios-src={passthroughProps.iosSrc}\n touch-action={passthroughProps.touchAction}\n disable-zoom={passthroughProps.disableZoom}\n orbit-sensitivity={passthroughProps.orbitSensitivity}\n auto-rotate={passthroughProps.autoRotate}\n auto-rotate-delay={passthroughProps.autoRotateDelay}\n // @ts-expect-error rotationPerSecond should exist as a type, not sure why it doesn't. https://modelviewer.dev/docs/index.html#entrydocs-stagingandcameras-attributes-rotationPerSecond\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n rotation-per-second={passthroughProps.rotationPerSecond}\n interaction-policy={passthroughProps.interactionPolicy}\n interaction-prompt={passthroughProps.interactionPrompt}\n interaction-prompt-style={passthroughProps.interactionPromptStyle}\n interaction-prompt-threshold={passthroughProps.interactionPromptThreshold}\n camera-orbit={passthroughProps.cameraOrbit}\n camera-target={passthroughProps.cameraTarget}\n field-of-view={passthroughProps.fieldOfView}\n max-camera-orbit={passthroughProps.maxCameraOrbit}\n min-camera-orbit={passthroughProps.minCameraOrbit}\n max-field-of-view={passthroughProps.maxFieldOfView}\n min-field-of-view={passthroughProps.minFieldOfView}\n bounds={passthroughProps.bounds}\n interpolation-decay={passthroughProps.interpolationDecay ?? 100}\n skybox-image={passthroughProps.skyboxImage}\n environment-image={passthroughProps.environmentImage}\n exposure={passthroughProps.exposure}\n shadow-intensity={passthroughProps.shadowIntensity ?? 0}\n shadow-softness={passthroughProps.shadowSoftness ?? 0}\n animation-name={passthroughProps.animationName}\n animation-crossfade-duration={passthroughProps.animationCrossfadeDuration}\n variant-name={passthroughProps.variantName}\n orientation={passthroughProps.orientation}\n scale={passthroughProps.scale}\n >\n {children}\n </model-viewer>\n );\n}\n","import {Image, type HydrogenImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ntype BaseProps = React.HTMLAttributes<\n HTMLImageElement | HTMLVideoElement | HTMLIFrameElement | ModelViewerElement\n>;\nexport interface MediaFileProps extends BaseProps {\n /** An object with fields that correspond to the Storefront API's [Media object](https://shopify.dev/api/storefront/reference/products/media). */\n data: PartialDeep<MediaEdgeType['node'], {recurseIntoArrays: true}>;\n /** The options for the `Image`, `Video`, `ExternalVideo`, or `ModelViewer` components. */\n mediaOptions?: MediaOptions;\n}\n\ntype MediaOptions = {\n /** Props that will only apply when an `<Image />` is rendered */\n image?: Omit<HydrogenImageProps, 'data'>;\n /** Props that will only apply when a `<Video />` is rendered */\n video?: Omit<React.ComponentProps<typeof Video>, 'data'>;\n /** Props that will only apply when an `<ExternalVideo />` is rendered */\n externalVideo?: Omit<\n React.ComponentProps<typeof ExternalVideo>['options'],\n 'data'\n >;\n /** Props that will only apply when a `<ModelViewer />` is rendered */\n modelViewer?: Omit<typeof ModelViewer, 'data'>;\n};\n\n/**\n * The `MediaFile` component renders the media for the Storefront API's\n * [Media object](https://shopify.dev/api/storefront/reference/products/media). It renders an `Image`, a\n * `Video`, an `ExternalVideo`, or a `ModelViewer` depending on the `__typename` of the `data` prop.\n */\nexport function MediaFile({\n data,\n mediaOptions,\n ...passthroughProps\n}: MediaFileProps): JSX.Element | null {\n switch (data.__typename) {\n case 'MediaImage': {\n if (!data.image) {\n const noDataImage = `<MediaFile/>: 'data.image' does not exist for __typename of 'MediaImage'; rendering 'null' by default.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataImage);\n } else {\n console.warn(noDataImage);\n return null;\n }\n }\n\n return (\n <Image\n {...passthroughProps}\n {...mediaOptions?.image}\n data={data.image}\n />\n );\n }\n case 'Video': {\n return (\n <Video {...passthroughProps} {...mediaOptions?.video} data={data} />\n );\n }\n case 'ExternalVideo': {\n return (\n <ExternalVideo\n {...passthroughProps}\n {...mediaOptions?.externalVideo}\n data={data}\n />\n );\n }\n case 'Model3d': {\n return (\n // @ts-expect-error There are issues with the inferred HTML attribute types here for ModelViewer (and contentEditable), but I think that's a little bit beyond me at the moment\n <ModelViewer\n {...passthroughProps}\n {...mediaOptions?.modelViewer}\n data={data}\n />\n );\n }\n default: {\n const typenameMissingMessage = `<MediaFile /> requires the '__typename' property to exist on the 'data' prop in order to render the matching sub-component for this type of media.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typenameMissingMessage);\n } else {\n console.error(`${typenameMissingMessage} Rendering 'null' by default`);\n return null;\n }\n }\n }\n}\n","import type {\n Collection,\n GenericFile,\n Metafield as MetafieldBaseType,\n MoneyV2,\n Page,\n Product,\n ProductVariant,\n} from './storefront-api-types.js';\nimport type {PartialDeep, Simplify} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\nimport {RootASTNode as RichTextRootASTNode} from './RichText.types.js';\n\n/**\n * A function that uses `metafield.type` to parse the Metafield's `value` or `reference` or `references` (depending on the `metafield.type`) and places the result in `metafield.parsedValue`\n *\n * TypeScript developers can use the type `ParsedMetafields` from this package to get the returned object's type correct. For example:\n *\n * ```\n * parseMetafield<ParsedMetafields['boolean']>({type: 'boolean', value: 'false'}\n * ```\n */\nexport function parseMetafield<ReturnGeneric>(\n metafield: PartialDeep<MetafieldBaseType, {recurseIntoArrays: true}>,\n): ReturnGeneric {\n if (!metafield.type) {\n const noTypeError = `parseMetafield(): The 'type' field is required in order to parse the Metafield.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noTypeError);\n } else {\n console.error(`${noTypeError} Returning 'parsedValue' of 'null'`);\n return {\n ...metafield,\n parsedValue: null,\n } as ReturnGeneric;\n }\n }\n\n switch (metafield.type) {\n case 'boolean':\n return {\n ...metafield,\n parsedValue: metafield.value === 'true',\n } as ReturnGeneric;\n\n case 'collection_reference':\n case 'file_reference':\n case 'page_reference':\n case 'product_reference':\n case 'variant_reference':\n return {\n ...metafield,\n parsedValue: metafield.reference,\n } as ReturnGeneric;\n\n case 'color':\n case 'multi_line_text_field':\n case 'single_line_text_field':\n case 'url':\n return {\n ...metafield,\n parsedValue: metafield.value,\n } as ReturnGeneric;\n\n // TODO: 'money' should probably be parsed even further to like `useMoney()`, but that logic needs to be extracted first so it's not a hook\n case 'dimension':\n case 'money':\n case 'json':\n case 'rating':\n case 'volume':\n case 'weight':\n case 'rich_text_field':\n case 'list.color':\n case 'list.dimension':\n case 'list.number_integer':\n case 'list.number_decimal':\n case 'list.rating':\n case 'list.single_line_text_field':\n case 'list.url':\n case 'list.volume':\n case 'list.weight': {\n let parsedValue = null;\n try {\n parsedValue = parseJSON(metafield.value ?? '');\n } catch (err) {\n const parseError = `parseMetafield(): attempted to JSON.parse the 'metafield.value' property, but failed.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(parseError);\n } else {\n console.error(`${parseError} Returning 'null' for 'parsedValue'`);\n }\n parsedValue = null;\n }\n return {\n ...metafield,\n parsedValue,\n } as ReturnGeneric;\n }\n\n case 'date':\n case 'date_time':\n return {\n ...metafield,\n parsedValue: new Date(metafield.value ?? ''),\n } as ReturnGeneric;\n\n case 'list.date':\n case 'list.date_time': {\n const jsonParseValue = parseJSON(metafield?.value ?? '') as string[];\n return {\n ...metafield,\n parsedValue: jsonParseValue.map((dateString) => new Date(dateString)),\n } as ReturnGeneric;\n }\n\n case 'number_decimal':\n case 'number_integer':\n return {\n ...metafield,\n parsedValue: Number(metafield.value),\n } as ReturnGeneric;\n\n case 'list.collection_reference':\n case 'list.file_reference':\n case 'list.page_reference':\n case 'list.product_reference':\n case 'list.variant_reference':\n return {\n ...metafield,\n parsedValue: flattenConnection(metafield.references ?? undefined),\n } as ReturnGeneric;\n\n default: {\n const typeNotFoundError = `parseMetafield(): the 'metafield.type' you passed in is not supported. Your type: \"${metafield.type}\". If you believe this is an error, please open an issue on GitHub.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typeNotFoundError);\n } else {\n console.error(\n `${typeNotFoundError} Returning 'parsedValue' of 'null'`,\n );\n return {\n ...metafield,\n parsedValue: null,\n } as ReturnGeneric;\n }\n }\n }\n}\n\n/**\n * Parses a JSON string while preventing prototype injection attacks.\n */\nexport function parseJSON(json: string): unknown {\n if (String(json).includes('__proto__')) {\n return JSON.parse(json, (k, v) => {\n if (k !== '__proto__') return v as unknown;\n }) as unknown;\n }\n return JSON.parse(json) as unknown;\n}\n\n// taken from https://shopify.dev/apps/metafields/types\nexport const allMetafieldTypesArray = [\n 'boolean',\n 'collection_reference',\n 'color',\n 'date',\n 'date_time',\n 'dimension',\n 'file_reference',\n 'json',\n 'money',\n 'rich_text_field',\n 'multi_line_text_field',\n 'number_decimal',\n 'number_integer',\n 'page_reference',\n 'product_reference',\n 'rating',\n 'single_line_text_field',\n 'url',\n 'variant_reference',\n 'volume',\n 'weight',\n // list metafields\n 'list.collection_reference',\n 'list.color',\n 'list.date',\n 'list.date_time',\n 'list.dimension',\n 'list.file_reference',\n 'list.number_integer',\n 'list.number_decimal',\n 'list.page_reference',\n 'list.product_reference',\n 'list.rating',\n 'list.single_line_text_field',\n 'list.url',\n 'list.variant_reference',\n 'list.volume',\n 'list.weight',\n] as const;\n\n/** A union of all the supported `metafield.type`s */\nexport type MetafieldTypeTypes = (typeof allMetafieldTypesArray)[number];\n\n/**\n * A mapping of a Metafield's `type` to the TypeScript type that is returned from `parseMetafield()`\n * For example, when using `parseMetafield()`, the type will be correctly returned when used like the following:\n *\n * ```\n * const parsedMetafield = parseMetafield<ParsedMetafields['boolean']>(metafield);`\n * ```\n * `parsedMetafield.parsedValue`'s type is now `boolean`\n */\nexport type ParsedMetafields<ExtraTypeGeneric = void> = {\n /** A Metafield that's been parsed, with a `parsedValue` of `boolean` */\n boolean: Simplify<BooleanParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Collection` object (as defined by the Storefront API) */\n collection_reference: Simplify<CollectionParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n color: Simplify<ColorParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Date` */\n date: Simplify<DatesParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Date` */\n date_time: Simplify<DatesParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n dimension: Simplify<MeasurementParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `GenericFile` object (as defined by the Storefront API) */\n file_reference: Simplify<FileRefParsedMetafield>;\n /**\n * A Metafield that's been parsed, with a `parsedValue` of type `unknown`, unless you pass in the type as a generic. For example:\n *\n * ```\n * ParsedMetafields<MyJsonType>['json']\n * ```\n */\n json: Simplify<JsonParsedMetafield<ExtraTypeGeneric>>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Money` */\n money: Simplify<MoneyParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n multi_line_text_field: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `number` */\n number_decimal: Simplify<NumberParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `number` */\n number_integer: Simplify<NumberParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Page` object (as defined by the Storefront API) */\n page_reference: Simplify<PageParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `Product` object (as defined by the Storefront API) */\n product_reference: Simplify<ProductParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Rating` */\n rating: Simplify<RatingParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Rating` */\n rich_text_field: Simplify<RichTextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n single_line_text_field: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `string` */\n url: Simplify<TextParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of a `ProductVariant` object (as defined by the Storefront API) */\n variant_reference: Simplify<VariantParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n volume: Simplify<MeasurementParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of type `Measurement` */\n weight: Simplify<MeasurementParsedMetafield>;\n // list metafields\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Collection` objects (as defined by the Storefront API) */\n 'list.collection_reference': Simplify<CollectionListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.color': Simplify<ColorListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of Date objects */\n 'list.date': Simplify<DatesListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of Date objects */\n 'list.date_time': Simplify<DatesListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement` objects */\n 'list.dimension': Simplify<MeasurementListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `GenericFile` objects (as defined by the Storefront API) */\n 'list.file_reference': Simplify<FileListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of numbers */\n 'list.number_integer': Simplify<NumberListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of numbers */\n 'list.number_decimal': Simplify<NumberListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Page` objects (as defined by the Storefront API) */\n 'list.page_reference': Simplify<PageListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Product` objects (as defined by the Storefront API) */\n 'list.product_reference': Simplify<ProductListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Rating`s */\n 'list.rating': Simplify<RatingListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.single_line_text_field': Simplify<TextListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of strings */\n 'list.url': Simplify<TextListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `ProductVariant` objects (as defined by the Storefront API) */\n 'list.variant_reference': Simplify<VariantListParsedRefMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement`s */\n 'list.volume': Simplify<MeasurementListParsedMetafield>;\n /** A Metafield that's been parsed, with a `parsedValue` of an array of `Measurement`s */\n 'list.weight': Simplify<MeasurementListParsedMetafield>;\n};\n\ninterface ParsedBase extends MetafieldBaseType {\n type: MetafieldTypeTypes;\n parsedValue: unknown;\n}\n\ninterface BooleanParsedMetafield extends ParsedBase {\n type: 'boolean';\n parsedValue: boolean | null;\n}\ntype CollectionParsedRefMetafield = MetafieldBaseType & {\n type: 'collection_reference';\n parsedValue: Collection | null;\n};\ntype ColorParsedMetafield = MetafieldBaseType & {\n type: 'color';\n parsedValue: string | null;\n};\ntype DatesParsedMetafield = MetafieldBaseType & {\n type: 'date' | 'date_time';\n parsedValue: Date | null;\n};\n\ntype MeasurementParsedMetafield = MetafieldBaseType & {\n type: 'dimension' | 'weight' | 'volume';\n parsedValue: Measurement | null;\n};\n\ntype FileRefParsedMetafield = MetafieldBaseType & {\n type: 'file_reference';\n parsedValue: GenericFile | null;\n};\n\ntype JsonParsedMetafield<JsonTypeGeneric = void> = MetafieldBaseType & {\n type: 'json';\n parsedValue: JsonTypeGeneric extends void ? unknown : JsonTypeGeneric | null;\n};\n\ntype MoneyParsedMetafield = MetafieldBaseType & {\n type: 'money';\n parsedValue: MoneyV2 | null;\n};\n\ntype TextParsedMetafield = MetafieldBaseType & {\n type: 'single_line_text_field' | 'multi_line_text_field' | 'url';\n parsedValue: string | null;\n};\n\ntype NumberParsedMetafield = MetafieldBaseType & {\n type: 'number_decimal' | 'number_integer';\n parsedValue: number | null;\n};\n\ntype PageParsedRefMetafield = MetafieldBaseType & {\n type: 'page_reference';\n parsedValue: Page | null;\n};\n\ntype ProductParsedRefMetafield = MetafieldBaseType & {\n type: 'product_reference';\n parsedValue: Product | null;\n};\n\ntype RatingParsedMetafield = MetafieldBaseType & {\n type: 'rating';\n parsedValue: Rating | null;\n};\n\ntype RichTextParsedMetafield = MetafieldBaseType & {\n type: 'rich_text_field';\n parsedValue: RichTextRootASTNode | null;\n};\n\ntype VariantParsedRefMetafield = MetafieldBaseType & {\n type: 'variant_reference';\n parsedValue: ProductVariant | null;\n};\n\ntype CollectionListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.collection_reference';\n parsedValue: Array<Collection> | null;\n};\n\ntype ColorListParsedMetafield = MetafieldBaseType & {\n type: 'list.color';\n parsedValue: Array<string> | null;\n};\n\ntype DatesListParsedMetafield = MetafieldBaseType & {\n type: 'list.date' | 'list.date_time';\n parsedValue: Array<Date> | null;\n};\n\ntype MeasurementListParsedMetafield = MetafieldBaseType & {\n type: 'list.dimension' | 'list.weight' | 'list.volume';\n parsedValue: Array<Measurement> | null;\n};\n\ntype FileListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.file_reference';\n parsedValue: Array<GenericFile> | null;\n};\n\ntype TextListParsedMetafield = MetafieldBaseType & {\n type: 'list.single_line_text_field' | 'list.url';\n parsedValue: Array<string> | null;\n};\n\ntype NumberListParsedMetafield = MetafieldBaseType & {\n type: 'list.number_decimal' | 'list.number_integer';\n parsedValue: Array<number> | null;\n};\n\ntype PageListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.page_reference';\n parsedValue: Array<Page> | null;\n};\n\ntype ProductListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.product_reference';\n parsedValue: Array<Product> | null;\n};\n\ntype RatingListParsedMetafield = MetafieldBaseType & {\n type: 'list.rating';\n parsedValue: Array<Rating> | null;\n};\n\ntype VariantListParsedRefMetafield = MetafieldBaseType & {\n type: 'list.variant_reference';\n parsedValue: Array<ProductVariant> | null;\n};\n\nexport type Measurement = {\n unit: string;\n value: number;\n};\n\nexport interface Rating {\n value: number;\n scale_min: number;\n scale_max: number;\n}\n","import type {\n MoneyV2,\n UnitPriceMeasurement,\n Product,\n} from './storefront-api-types.js';\nimport {Money, type MoneyProps, type MoneyPropsBase} from './Money.js';\nimport type {PartialDeep} from 'type-fest';\nimport {flattenConnection} from './flatten-connection.js';\n\nexport interface ProductPriceProps {\n /** A Storefront API [Product object](https://shopify.dev/api/storefront/reference/products/product). */\n data: PartialDeep<Product, {recurseIntoArrays: true}>;\n /** The type of price. Valid values: `regular` (default) or `compareAt`. */\n priceType?: 'regular' | 'compareAt';\n /** The type of value. Valid values: `min` (default), `max` or `unit`. */\n valueType?: 'max' | 'min' | 'unit';\n /** The ID of the variant. */\n variantId?: string;\n}\n\n/**\n * The `ProductPrice` component renders a `Money` component with the product\n * [`priceRange`](https://shopify.dev/api/storefront/reference/products/productpricerange)'s `maxVariantPrice` or `minVariantPrice`, for either the regular price or compare at price range.\n */\nexport function ProductPrice<\n ComponentGeneric extends React.ElementType = 'div',\n>(\n props: ProductPriceProps &\n Omit<MoneyProps<ComponentGeneric>, 'data' | 'measurement'>,\n): JSX.Element | null {\n const {\n priceType = 'regular',\n variantId,\n valueType = 'min',\n data: product,\n ...passthroughProps\n } = props;\n\n if (product == null) {\n throw new Error(`<ProductPrice/> requires a product as the 'data' prop`);\n }\n\n let price: Partial<MoneyV2> | undefined | null;\n let measurement: Partial<UnitPriceMeasurement> | undefined | null;\n\n const variant = variantId\n ? flattenConnection(product?.variants ?? {}).find(\n (variant) => variant?.id === variantId,\n ) ?? null\n : null;\n\n const variantPriceProperty =\n valueType === 'max' ? 'maxVariantPrice' : 'minVariantPrice';\n\n if (priceType === 'compareAt') {\n if (variantId && variant) {\n price = variant.compareAtPrice;\n } else {\n price = product?.compareAtPriceRange?.[variantPriceProperty];\n }\n\n let priceAsNumber: number;\n if (variantId && variant) {\n priceAsNumber = parseFloat(variant.price?.amount ?? '0');\n } else {\n priceAsNumber = parseFloat(\n product?.priceRange?.[variantPriceProperty]?.amount ?? '0',\n );\n }\n\n const compareAtPriceAsNumber = parseFloat(price?.amount ?? '0');\n\n if (priceAsNumber >= compareAtPriceAsNumber) {\n return null;\n }\n } else {\n if (variantId && variant) {\n price = variant.price;\n if (valueType === 'unit') {\n price = variant.unitPrice;\n measurement = variant.unitPriceMeasurement;\n }\n } else if (valueType === 'max') {\n price = product.priceRange?.maxVariantPrice;\n } else {\n price = product.priceRange?.minVariantPrice;\n }\n }\n\n if (!price) {\n return null;\n }\n\n if (measurement) {\n return (\n <Money {...passthroughProps} data={price} measurement={measurement} />\n );\n }\n\n return <Money {...passthroughProps} data={price} />;\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport interface ProductPricePropsForDocs<\n AsType extends React.ElementType = 'div',\n> extends Omit<MoneyPropsBase<AsType>, 'data' | 'measurement'>,\n ProductPriceProps {}\n","import {createElement, type ReactNode} from 'react';\n\nexport type CustomComponents = {\n /** The root node of the rich text. Defaults to `<div>` */\n root?: typeof Root;\n /** Customize the headings. Each heading has a `level` property from 1-6. Defaults to `<h1>` to `<h6>` */\n heading?: typeof Heading;\n /** Customize paragraphs. Defaults to `<p>` */\n paragraph?: typeof Paragraph;\n /** Customize how text nodes. They can either be bold or italic. Defaults to `<em>`, `<strong>` or text. */\n text?: typeof Text;\n /** Customize links. Defaults to a React Router `<Link>` component in Hydrogen and a `<a>` in Hydrogen React. */\n link?: typeof RichTextLink;\n /** Customize lists. They can be either ordered or unordered. Defaults to `<ol>` or `<ul>` */\n list?: typeof List;\n /** Customize list items. Defaults to `<li>`. */\n listItem?: typeof ListItem;\n};\n\nexport const RichTextComponents = {\n root: Root,\n heading: Heading,\n paragraph: Paragraph,\n text: Text,\n link: RichTextLink,\n list: List,\n 'list-item': ListItem,\n};\n\nfunction Root({\n node,\n}: {\n node: {\n type: 'root';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <div>{node.children}</div>;\n}\n\nfunction Heading({\n node,\n}: {\n node: {\n type: 'heading';\n level: number;\n children?: ReactNode[];\n };\n}): ReactNode {\n return createElement(`h${node.level ?? '1'}`, null, node.children);\n}\n\nfunction Paragraph({\n node,\n}: {\n node: {\n type: 'paragraph';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <p>{node.children}</p>;\n}\n\nfunction Text({\n node,\n}: {\n node: {\n type: 'text';\n italic?: boolean;\n bold?: boolean;\n value?: string;\n };\n}): ReactNode {\n if (node.bold && node.italic)\n return (\n <em>\n <strong>{node.value}</strong>\n </em>\n );\n\n if (node.bold) return <strong>{node.value}</strong>;\n if (node.italic) return <em>{node.value}</em>;\n\n return node.value;\n}\n\nfunction RichTextLink({\n node,\n}: {\n node: {\n type: 'link';\n url: string;\n title?: string;\n target?: string;\n children?: ReactNode[];\n };\n}): ReactNode {\n return (\n <a href={node.url} title={node.title} target={node.target}>\n {node.children}\n </a>\n );\n}\n\nfunction List({\n node,\n}: {\n node: {\n type: 'list';\n listType: 'unordered' | 'ordered';\n children?: ReactNode[];\n };\n}): ReactNode {\n const List = node.listType === 'unordered' ? 'ul' : 'ol';\n return <List>{node.children}</List>;\n}\n\nfunction ListItem({\n node,\n}: {\n node: {\n type: 'list-item';\n children?: ReactNode[];\n };\n}): ReactNode {\n return <li>{node.children}</li>;\n}\n","import {createElement, Fragment, type ReactNode, useMemo} from 'react';\nimport type {RichTextASTNode} from './RichText.types.js';\nimport {\n type CustomComponents,\n RichTextComponents,\n} from './RichText.components.js';\n\nexport interface RichTextPropsBase<ComponentGeneric extends React.ElementType> {\n /** An HTML tag or React Component to be rendered as the base element wrapper. The default is `div`. */\n as?: ComponentGeneric;\n /** The JSON string that correspond to the Storefront API's [RichText format](https://shopify.dev/docs/apps/custom-data/metafields/types#rich-text-formatting). */\n data: string;\n /** Customize how rich text components are rendered */\n components?: CustomComponents;\n /** Remove rich text formatting and render plain text */\n plain?: boolean;\n}\n\nexport function RichText<ComponentGeneric extends React.ElementType = 'div'>({\n as,\n data,\n plain,\n components,\n ...passthroughProps\n}: RichTextProps<ComponentGeneric>): JSX.Element {\n try {\n const Wrapper = as ?? 'div';\n const parsedData = useMemo(\n () => JSON.parse(data) as RichTextASTNode,\n [data],\n );\n\n return (\n <Wrapper {...passthroughProps}>\n {plain\n ? richTextToString(parsedData)\n : serializeRichTextASTNode(components, parsedData)}\n </Wrapper>\n );\n } catch (e) {\n throw new Error(\n '[h2:error:RichText] Parsing error. Make sure to pass a JSON string of rich text metafield',\n {\n cause: e,\n },\n );\n }\n}\n\n// This article helps understand the typing here https://www.benmvp.com/blog/polymorphic-react-components-typescript/ Ben is the best :)\nexport type RichTextProps<ComponentGeneric extends React.ElementType> =\n RichTextPropsBase<ComponentGeneric> &\n Omit<\n React.ComponentPropsWithoutRef<ComponentGeneric>,\n keyof RichTextPropsBase<ComponentGeneric>\n >;\n\nfunction serializeRichTextASTNode(\n components: CustomComponents = {},\n node: RichTextASTNode,\n index = 0,\n): ReactNode {\n let children;\n if ('children' in node) {\n children = node.children.map((child, childIndex) =>\n serializeRichTextASTNode(components, child, childIndex),\n );\n }\n\n const Component =\n components[node.type === 'list-item' ? 'listItem' : node.type] ??\n RichTextComponents[node.type];\n\n switch (node.type) {\n case 'root':\n return createElement(\n Component as Exclude<CustomComponents['root'], undefined>,\n {\n key: index,\n node: {\n type: 'root',\n children,\n },\n },\n );\n case 'heading':\n return createElement(\n Component as Exclude<CustomComponents['heading'], undefined>,\n {\n key: index,\n node: {\n type: 'heading',\n level: node.level,\n children,\n },\n },\n );\n case 'paragraph':\n return createElement(\n Component as Exclude<CustomComponents['paragraph'], undefined>,\n {\n key: index,\n node: {\n type: 'paragraph',\n children,\n },\n },\n );\n case 'text': {\n const elements = (node.value ?? '')\n .split('\\n')\n .flatMap((value, subindex) => {\n const key = `${index}-${value}-${subindex}`;\n const textElement = createElement(\n Component as Exclude<CustomComponents['text'], undefined>,\n {\n key,\n node: {\n type: 'text',\n italic: node.italic,\n bold: node.bold,\n value,\n },\n },\n );\n\n // Add a `<br>` before each substring except the first one\n return subindex === 0\n ? textElement\n : [createElement('br', {key: `${key}-br`}), textElement];\n });\n\n return elements.length > 1\n ? createElement(Fragment, {key: index}, elements)\n : elements[0];\n }\n case 'link':\n return createElement(\n Component as Exclude<CustomComponents['link'], undefined>,\n {\n key: index,\n node: {\n type: 'link',\n url: node.url,\n title: node.title,\n target: node.target,\n children,\n },\n },\n );\n case 'list':\n return createElement(\n Component as Exclude<CustomComponents['list'], undefined>,\n {\n key: index,\n node: {\n type: 'list',\n listType: node.listType,\n children,\n },\n },\n );\n case 'list-item':\n return createElement(\n Component as Exclude<CustomComponents['listItem'], undefined>,\n {\n key: index,\n node: {\n type: 'list-item',\n children,\n },\n },\n );\n }\n}\n\nfunction richTextToString(\n node: RichTextASTNode,\n result: string[] = [],\n): string {\n switch (node.type) {\n case 'root':\n node.children.forEach((child) => richTextToString(child, result));\n break;\n case 'heading':\n case 'paragraph':\n node.children.forEach((child) => richTextToString(child, result));\n result.push(' ');\n break;\n case 'text':\n result.push(node.value || '');\n break;\n case 'link':\n node.children.forEach((child) => richTextToString(child, result));\n break;\n case 'list':\n node.children.forEach((item) => {\n if (item.children) {\n item.children.forEach((child) => richTextToString(child, result));\n }\n result.push(' ');\n });\n break;\n default:\n throw new Error(`Unknown node encountered ${node.type}`);\n }\n\n return result.join('').trim();\n}\n\n// This is only for documentation purposes, and it is not used in the code.\nexport type RichTextPropsForDocs<AsType extends React.ElementType = 'div'> =\n RichTextPropsBase<AsType>;\n","import {defaultShopifyContext, useShop} from './ShopifyProvider.js';\nimport {useLoadScript} from './load-script.js';\nimport {parseGid} from './analytics-utils.js';\n\n// By using 'never' in the \"or\" cases below, it makes these props \"exclusive\" and means that you cannot pass both of them; you must pass either one OR the other.\ntype ShopPayButtonProps = ShopPayButtonStyleProps &\n ShopPayDomainProps &\n ShopPayChannelAttribution &\n (ShopPayVariantIds | ShopPayVariantAndQuantities);\n\ntype ShopPayButtonStyleProps = {\n /** A string of classes to apply to the `div` that wraps the Shop Pay button. */\n className?: string;\n /** A string that's applied to the [CSS custom property (variable)](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) `--shop-pay-button-width` for the [Buy with Shop Pay component](https://shopify.dev/custom-storefronts/tools/web-components#buy-with-shop-pay-component). */\n width?: string;\n};\n\ntype ShopPayDomainProps = {\n /** The domain of your Shopify storefront URL (eg: `your-store.myshopify.com`). */\n storeDomain?: string;\n};\n\ntype ShopPayVariantIds = {\n /** An array of IDs of the variants to purchase with Shop Pay. This will only ever have a quantity of 1 for each variant. If you want to use other quantities, then use `variantIdsAndQuantities`. */\n variantIds: string[];\n /** An array of variant IDs and quantities to purchase with Shop Pay. */\n variantIdsAndQuantities?: never;\n};\n\ntype ShopPayVariantAndQuantities = {\n /** An array of IDs of the variants to purchase with Shop Pay. This will only ever have a quantity of 1 for each variant. If you want to use other quantities, then use `variantIdsAndQuantities`. */\n variantIds?: never;\n /** An array of variant IDs and quantities to purchase with Shop Pay. */\n variantIdsAndQuantities: Array<{\n id: string;\n quantity: number;\n }>;\n};\n\ntype ShopPayChannelAttribution = {\n /** A string that adds channel attribution to the order. Can be either `headless` or `hydrogen` */\n channel?: 'headless' | 'hydrogen';\n};\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n interface IntrinsicElements {\n 'shop-pay-button': {\n channel?: string;\n variants: string;\n 'store-url': string;\n };\n }\n }\n}\n\nconst SHOPJS_URL =\n 'https://cdn.shopify.com/shopifycloud/shop-js/v1.0/client.js';\n\nfunction isChannel(\n channel: string,\n): channel is Exclude<ShopPayChannelAttribution['channel'], undefined> {\n return channel === 'headless' || channel === 'hydrogen';\n}\n\n/**\n * The `ShopPayButton` component renders a button that redirects to the Shop Pay checkout.\n * It renders a [`<shop-pay-button>`](https://shopify.dev/custom-storefronts/tools/web-components) custom element, for which it will lazy-load the source code automatically.\n * It relies on the `<ShopProvider>` context provider.\n */\nexport function ShopPayButton({\n channel,\n variantIds,\n className,\n variantIdsAndQuantities,\n width,\n storeDomain: _storeDomain,\n}: ShopPayButtonProps): JSX.Element {\n const shop = useShop();\n const storeDomain = _storeDomain || shop?.storeDomain;\n const shopPayLoadedStatus = useLoadScript(SHOPJS_URL);\n\n let ids: string[] = [];\n let channelAttribution: string | undefined;\n\n if (!storeDomain || storeDomain === defaultShopifyContext.storeDomain) {\n throw new Error(MissingStoreDomainErrorMessage);\n }\n\n if (variantIds && variantIdsAndQuantities) {\n throw new Error(DoublePropsErrorMessage);\n }\n\n if (!variantIds && !variantIdsAndQuantities) {\n throw new Error(MissingPropsErrorMessage);\n }\n\n if (channel) {\n if (isChannel(channel)) {\n channelAttribution = channel;\n } else {\n throw new Error(InvalidChannelErrorMessage);\n }\n }\n\n if (variantIds) {\n ids = variantIds.reduce<string[]>((prev, curr) => {\n const bareId = parseGid(curr).id;\n if (bareId) {\n prev.push(bareId);\n }\n return prev;\n }, []);\n } else if (variantIdsAndQuantities) {\n ids = variantIdsAndQuantities.reduce<string[]>((prev, curr) => {\n const bareId = parseGid(curr?.id).id;\n if (bareId) {\n prev.push(`${bareId}:${curr?.quantity ?? 1}`);\n }\n return prev;\n }, []);\n } else {\n throw new Error(MissingPropsErrorMessage);\n }\n\n if (ids.length === 0) {\n throw new Error(InvalidPropsErrorMessage);\n }\n\n const style = width\n ? ({\n '--shop-pay-button-width': width,\n } as React.CSSProperties)\n : undefined;\n\n return (\n <div className={className} style={style}>\n {shopPayLoadedStatus === 'done' && (\n <shop-pay-button\n {...(channelAttribution ? {channel: channelAttribution} : {})}\n store-url={storeDomain}\n variants={ids.join(',')}\n />\n )}\n </div>\n );\n}\n\nexport const MissingStoreDomainErrorMessage =\n 'You must pass a \"storeDomain\" prop to the \"ShopPayButton\" component, or wrap it in a \"ShopifyProvider\" component.';\nexport const InvalidPropsErrorMessage = `You must pass in \"variantIds\" in the form of [\"gid://shopify/ProductVariant/1\"]`;\nexport const MissingPropsErrorMessage = `You must pass in either \"variantIds\" or \"variantIdsAndQuantities\" to ShopPayButton`;\nexport const DoublePropsErrorMessage = `You must provide either a variantIds or variantIdsAndQuantities prop, but not both in the ShopPayButton component`;\nexport const InvalidChannelErrorMessage = `Invalid channel attribution value. Must be either \"headless\" or \"hydrogen\"`;\n","import {useEffect} from 'react';\nimport {mapSelectedProductOptionToObject} from './getProductOptions.js';\nimport {SelectedOption} from './storefront-api-types.js';\n\nexport function useSelectedOptionInUrlParam(\n selectedOptions: Pick<SelectedOption, 'name' | 'value'>[],\n): null {\n useEffect(() => {\n const optionsSearchParams = new URLSearchParams(\n mapSelectedProductOptionToObject(selectedOptions || []),\n );\n const currentSearchParams = new URLSearchParams(window.location.search);\n\n // ts ignoring the URLSearchParams not iterable error for now\n // https://stackoverflow.com/questions/72522489/urlsearchparams-not-accepting-string#answer-72522838\n // TODO: update ts lib\n const combinedSearchParams = new URLSearchParams({\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...Object.fromEntries(currentSearchParams),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...Object.fromEntries(optionsSearchParams),\n });\n\n if (combinedSearchParams.size > 0) {\n window.history.replaceState(\n {},\n '',\n `${window.location.pathname}?${combinedSearchParams.toString()}`,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(selectedOptions)]);\n\n return null;\n}\n","import {useEffect} from 'react';\nimport {stringify} from 'worktop/cookie';\nimport {SHOPIFY_Y, SHOPIFY_S} from './cart-constants.js';\nimport {buildUUID, getShopifyCookies} from './cookies-utils.js';\n\nconst longTermLength = 60 * 60 * 24 * 360 * 1; // ~1 year expiry\nconst shortTermLength = 60 * 30; // 30 mins\n\ntype UseShopifyCookiesOptions = {\n /**\n * If set to `false`, Shopify cookies will be removed.\n * If set to `true`, Shopify unique user token cookie will have cookie expiry of 1 year.\n * Defaults to false.\n **/\n hasUserConsent?: boolean;\n /**\n * The domain scope of the cookie. Defaults to empty string.\n **/\n domain?: string;\n /**\n * The checkout domain of the shop. Defaults to empty string. If set, the cookie domain will check if it can be set with the checkout domain.\n */\n checkoutDomain?: string;\n};\n\nexport function useShopifyCookies(options?: UseShopifyCookiesOptions): void {\n const {\n hasUserConsent = false,\n domain = '',\n checkoutDomain = '',\n } = options || {};\n useEffect(() => {\n const cookies = getShopifyCookies(document.cookie);\n\n /**\n * Setting cookie with domain\n *\n * If no domain is provided, the cookie will be set for the current host.\n * For Shopify, we need to ensure this domain is set with a leading dot.\n */\n\n // Use override domain or current host\n let currentDomain = domain || window.document.location.host;\n\n if (checkoutDomain) {\n const checkoutDomainParts = checkoutDomain.split('.').reverse();\n const currentDomainParts = currentDomain.split('.').reverse();\n const sameDomainParts: Array<string> = [];\n checkoutDomainParts.forEach((part, index) => {\n if (part === currentDomainParts[index]) {\n sameDomainParts.push(part);\n }\n });\n\n currentDomain = sameDomainParts.reverse().join('.');\n }\n\n // Reset domain if localhost\n if (/^localhost/.test(currentDomain)) currentDomain = '';\n\n // Shopify checkout only consumes cookies set with leading dot domain\n const domainWithLeadingDot = currentDomain\n ? /^\\./.test(currentDomain)\n ? currentDomain\n : `.${currentDomain}`\n : '';\n\n /**\n * Set user and session cookies and refresh the expiry time\n */\n if (hasUserConsent) {\n setCookie(\n SHOPIFY_Y,\n cookies[SHOPIFY_Y] || buildUUID(),\n longTermLength,\n domainWithLeadingDot,\n );\n setCookie(\n SHOPIFY_S,\n cookies[SHOPIFY_S] || buildUUID(),\n shortTermLength,\n domainWithLeadingDot,\n );\n } else {\n setCookie(SHOPIFY_Y, '', 0, domainWithLeadingDot);\n setCookie(SHOPIFY_S, '', 0, domainWithLeadingDot);\n }\n }, [options, hasUserConsent, domain, checkoutDomain]);\n}\n\nfunction setCookie(\n name: string,\n value: string,\n maxage: number,\n domain: string,\n): void {\n document.cookie = stringify(name, value, {\n maxage,\n domain,\n samesite: 'Lax',\n path: '/',\n });\n}\n"],"names":["t","n","e","r","i","o","a","u","c","f","s","l","v","y","p","g","x","m","h","S","j","E","R","N","O","_","k","T","z","A","B","C","index","useLayoutEffect","require$$0","b","q","d","useSyncExternalStoreShim_production_min","shimModule","require$$1","w","withSelector_production_min","withSelectorModule","useConstant","fn","ref","React","__read","ar","error","identity","getServiceState","service","currentValue","state","useMachine","stateMachine","options","persistedStateRef","useRef","_b","queue","interpret","createMachine","send","event","InterpreterStatus","useIsomorphicLayoutEffect","useServiceResult","useService","useEffect","isEqual","_prevState","nextState","getSnapshot","useCallback","subscribe","handleStoreChange","unsubscribe","storeSnapshot","useSyncExternalStoreWithSelector","flattenConnection","connection","noConnectionErr","edge","CartLineAdd","cartFragment","CartCreate","CartLineRemove","CartLineUpdate","CartNoteUpdate","CartBuyerIdentityUpdate","CartAttributesUpdate","CartDiscountCodesUpdate","CartQuery","defaultCartFragment","SFAPI_VERSION","MOCK_SHOP_DOMAIN","isMockShop","domain","createStorefrontClient","storeDomain","privateStorefrontToken","publicStorefrontToken","storefrontApiVersion","contentType","H2_PREFIX_ERROR","warnOnce","getShopifyDomain","overrideProps","apiUrl","finalContentType","getPublicTokenHeadersRaw","accessToken","warnings","string","type","defaultShopifyContext","ShopifyContext","createContext","ShopifyProvider","children","shopifyConfig","finalConfig","useMemo","finalDomainUrl","useShop","shopContext","useContext","CART_ID_STORAGE_KEY","SHOPIFY_STOREFRONT_ID_HEADER","SHOPIFY_STOREFRONT_Y_HEADER","SHOPIFY_STOREFRONT_S_HEADER","SHOPIFY_Y","SHOPIFY_S","tokenHash","buildUUID","hash","crypto","randomValuesArray","hexTime","dateNumber","perfNumber","getShopifyCookies","cookies","cookieData","parse","useCartFetch","storefrontId","getPublicTokenHeaders","getStorefrontApiUrl","query","variables","headers","res","useCartActions","numCartLines","countryCode","languageCode","fetchCart","cartFetch","cartId","cartCreate","cart","cartLineAdd","lines","cartLineUpdate","cartLineRemove","noteUpdate","note","buyerIdentityUpdate","buyerIdentity","cartAttributesUpdate","attributes","discountCodesUpdate","discountCodes","invokeCart","action","assign","context","_a","INITIALIZING_CART_EVENTS","cartFromGraphQL","UPDATING_CART_EVENTS","createCartMachine","initialCart","useCartAPIStateMachine","onCartActionEntry","onCartActionOptimisticUI","onCartActionComplete","cartMachine","data","errors","resultEvent","eventFromFetchResult","isCartActionEvent","isCartFetchResultEvent","cartActionEvent","CartContext","useCart","CartProvider","onCreate","onLineAdd","onLineRemove","onLineUpdate","onNoteUpdate","onBuyerIdentityUpdate","onAttributesUpdate","onDiscountCodesUpdate","onCreateComplete","onLineAddComplete","onLineRemoveComplete","onLineUpdateComplete","onNoteUpdateComplete","onBuyerIdentityUpdateComplete","onAttributesUpdateComplete","onDiscountCodesUpdateComplete","customerAccessToken","shop","prevCountryCode","setPrevCountryCode","useState","prevCustomerAccessToken","setPrevCustomerAccessToken","customerOverridesCountryCode","cartState","cartSend","line","_d","_c","updatedLine","id","countryCodeNotUpdated","cartReady","isCartReady","setIsCartReady","cartCompleted","countryChanged","fetchingFromStorage","storageAvailable","onCartReadySend","cartEvent","_e","cartInput","cartDisplayState","useDelayedStateUntilHydration","cartContextValue","transposeStatus","_f","_g","status","isPending","startTransition","useTransition","delayedState","setDelayedState","firstTimePending","firstTimePendingFinished","storage","ProductOptionsContext","ProductProvider","product","explicitVariantId","variants","isProductVariantArray","getOptions","selectedVariant","setSelectedVariant","getVariantBasedOnIdProp","selectedOptions","setSelectedOptions","getSelectedOptions","newSelectedVariant","setSelectedOption","name","value","opts","getSelectedVariant","isOptionInStock","option","proposedVariant","sellingPlanGroups","sellingPlanGroup","selectedSellingPlan","setSelectedSellingPlan","selectedSellingPlanAllocation","allocation","useProduct","choices","variant","map","memo","opt","foundVariant","optionSet","maybeVariantArray","BaseButton","props","as","onClick","defaultOnClick","buttonRef","passthroughProps","handleOnClick","clickShouldContinue","Component","AddToCartButton","addingItem","setAddingItem","quantity","sellingPlanId","accessibleAddingToCartLabel","linesAdd","variantId","disabled","handleAddItem","AnalyticsEventName","AnalyticsPageType","ShopifySalesChannel","ShopifyAppId","schemaWrapper","schemaId","payload","parseGid","gid","defaultReturn","search","searchParams","pathname","pathnameParts","lastPathnamePart","resourcePart","addDataIf","keyValuePairs","formattedData","key","errorIfServer","fnName","SCHEMA_ID","OXYGEN_DOMAIN","pageView","pageViewPayload","resource","resourceType","formatPayload","isMerchantRequest","url","hostname","PAGE_RENDERED_EVENT_NAME","COLLECTION_PAGE_RENDERED_EVENT_NAME","PRODUCT_PAGE_RENDERED_EVENT_NAME","PRODUCT_ADDED_TO_CART_EVENT_NAME","SEARCH_SUBMITTED_EVENT_NAME","prepareAdditionalPayload","additionalPayload","pageType","pageViewEvents","formatProductPayload","pageView2","collectionView","productView","searchView","addToCart","addToCartPayload","cartToken","cart_token","version","products","sendShopifyAnalytics","shopDomain","eventName","events","trekkiePageView","customerPageView","customerAddToCart","customerPageView2","customerCollectionView","customerProductView","customerSearchView","sendToShopify","isLighthouseUserAgent","ERROR_MESSAGE","eventsToBeSent","response","eventResponse","err","getClientBrowserParameters","navigationType","navigationApi","getNavigationType","getNavigationTypeExperimental","navigationEntries","rawType","getNavigationTypeLegacy","navApi","navType","BuyNowButton","checkoutUrl","loading","setLoading","handleBuyNow","CartCheckoutButton","requestedCheckout","setRequestedCheckout","useMoney","money","countryIsoCode","languageIsoCode","locale","amount","defaultFormatter","nameFormatter","narrowSymbolFormatter","withoutTrailingZerosFormatter","withoutCurrencyFormatter","withoutTrailingZerosOrCurrencyFormatter","getLazyFormatter","isPartCurrency","part","lazyFormatters","target","formatterCache","formatter","Money","withoutCurrency","withoutTrailingZeros","measurement","measurementSeparator","isMoney","moneyObject","Wrapper","output","maybeMoney","CartCost","cost","amountType","CartLineContext","useCartLine","CartLineProvider","CartLineQuantity","cartLine","CartLineQuantityAdjustButton","linesRemove","linesUpdate","adjust","handleAdjust","lineUpdate","disabledAttr","storefrontApiCustomScalars","customerAccountApiCustomScalars","ExternalVideo","forwardRef","frameBorder","allow","allowFullScreen","finalUrl","urlObject","OPTION_VALUE_SEPARATOR","V1_CONTROL_CHARS","isOptionValueCombinationInEncodedVariant","decodedOptionValues","targetOptionValueCombination","encodedVariantField","decodedOptionValuesSet","optionValue","decodeEncodedVariant","v1Decoder","stripVersion","tokenizer","token","currentOptionValue","depth","rangeStart","operation","optionValueIndex","encodingEndsWithIndex","finalValueIndex","mapProductOptions","mapSelectedProductOptionToObject","mapSelectedProductOptionToObjectAsString","encodeSelectedProductOptionAsKey","selectedOption","productOptionMappings","mapVariants","PRODUCT_INPUTS","PRODUCT_INPUTS_EXTRA","logErrorAndReturnFalse","checkProductParam","checkAll","validParam","productKeys","firstOption","firstOptionValues","checkProductVariantParam","currentValidParamState","firstSelectedOption","getAdjacentAndFirstAvailableVariants","checkedProduct","availableVariants","variantKey","getProductOptions","adjacentVariants","encodedVariantExistence","encodedVariantAvailability","productHandle","optionIndex","targetOptionParams","targetKey","topDownKey","exists","available","variantOptionParam","handle","IMAGE_FRAGMENT","Image","alt","aspectRatio","crop","decoding","height","loader","shopifyLoader","sizes","src","srcSetOptions","width","normalizedData","dataWidth","dataHeight","unitsMatch","normalizedProps","widthParts","getUnitValueParts","nWidth","autoHeight","heightParts","fixedHeight","nHeight","nSrc","nAlt","nAspectRatio","getNormalizedFixedUnit","intervals","startingWidth","incrementSize","placeholderWidth","imageWidths","generateImageWidths","isFixedWidth","FixedWidthImage","FluidImage","fixed","intWidth","intHeight","fixedAspectRatio","sizesArray","generateSizes","parseAspectRatio","srcSet","generateSrcSet","fluid","placeholderHeight","PLACEHOLDER_DOMAIN","unit","number","size","responsive","sourceDimensions","SCRIPTS_LOADED","loadScript","isScriptLoaded","promise","resolve","reject","script","useLoadScript","setStatus","Video","previewImageOptions","playsInline","controls","sourceProps","posterUrl","source","ModelViewer","modelViewer","setModelViewer","callbackRef","node","className","modelViewerLoadedStatus","hydrogenEventListener","callbackFunc","MediaFile","mediaOptions","parseMetafield","metafield","parsedValue","parseJSON","jsonParseValue","dateString","typeNotFoundError","json","ProductPrice","priceType","valueType","price","variantPriceProperty","priceAsNumber","compareAtPriceAsNumber","RichTextComponents","Root","Heading","Paragraph","Text","RichTextLink","List","ListItem","createElement","RichText","plain","components","parsedData","richTextToString","serializeRichTextASTNode","child","childIndex","elements","subindex","textElement","Fragment","result","item","SHOPJS_URL","isChannel","channel","ShopPayButton","variantIds","variantIdsAndQuantities","_storeDomain","shopPayLoadedStatus","ids","channelAttribution","MissingStoreDomainErrorMessage","DoublePropsErrorMessage","MissingPropsErrorMessage","InvalidChannelErrorMessage","prev","curr","bareId","InvalidPropsErrorMessage","style","useSelectedOptionInUrlParam","optionsSearchParams","currentSearchParams","combinedSearchParams","longTermLength","shortTermLength","useShopifyCookies","hasUserConsent","checkoutDomain","currentDomain","checkoutDomainParts","currentDomainParts","sameDomainParts","domainWithLeadingDot","setCookie","maxage","stringify"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,14]}
|