@shopify/hydrogen-react 2025.5.0 → 2025.7.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.
Files changed (370) hide show
  1. package/customer-account.schema.json +1 -1
  2. package/dist/browser-dev/AddToCartButton.mjs.map +1 -1
  3. package/dist/browser-dev/BaseButton.mjs.map +1 -1
  4. package/dist/browser-dev/BuyNowButton.mjs.map +1 -1
  5. package/dist/browser-dev/CartCheckoutButton.mjs.map +1 -1
  6. package/dist/browser-dev/CartCost.mjs.map +1 -1
  7. package/dist/browser-dev/CartLineProvider.mjs.map +1 -1
  8. package/dist/browser-dev/CartLineQuantity.mjs.map +1 -1
  9. package/dist/browser-dev/CartLineQuantityAdjustButton.mjs.map +1 -1
  10. package/dist/browser-dev/CartProvider.mjs.map +1 -1
  11. package/dist/browser-dev/ExternalVideo.mjs.map +1 -1
  12. package/dist/browser-dev/Image.mjs.map +1 -1
  13. package/dist/browser-dev/MediaFile.mjs.map +1 -1
  14. package/dist/browser-dev/ModelViewer.mjs.map +1 -1
  15. package/dist/browser-dev/Money.mjs.map +1 -1
  16. package/dist/browser-dev/ProductPrice.mjs.map +1 -1
  17. package/dist/browser-dev/ProductProvider.mjs.map +1 -1
  18. package/dist/browser-dev/RichText.components.mjs.map +1 -1
  19. package/dist/browser-dev/RichText.mjs.map +1 -1
  20. package/dist/browser-dev/ShopPayButton.mjs.map +1 -1
  21. package/dist/browser-dev/ShopifyProvider.mjs.map +1 -1
  22. package/dist/browser-dev/Video.mjs.map +1 -1
  23. package/dist/browser-dev/analytics-schema-custom-storefront-customer-tracking.mjs.map +1 -1
  24. package/dist/browser-dev/analytics-schema-trekkie-storefront-page-view.mjs.map +1 -1
  25. package/dist/browser-dev/analytics-utils.mjs.map +1 -1
  26. package/dist/browser-dev/analytics.mjs.map +1 -1
  27. package/dist/browser-dev/cart-hooks.mjs.map +1 -1
  28. package/dist/browser-dev/cart-queries.mjs.map +1 -1
  29. package/dist/browser-dev/codegen.helpers.mjs.map +1 -1
  30. package/dist/browser-dev/cookies-utils.mjs.map +1 -1
  31. package/dist/browser-dev/flatten-connection.mjs.map +1 -1
  32. package/dist/browser-dev/getProductOptions.mjs.map +1 -1
  33. package/dist/browser-dev/load-script.mjs.map +1 -1
  34. package/dist/browser-dev/node_modules/@xstate/fsm/es/index.mjs +17 -17
  35. package/dist/browser-dev/node_modules/@xstate/fsm/es/index.mjs.map +1 -1
  36. package/dist/browser-dev/node_modules/@xstate/react/es/fsm.mjs +2 -2
  37. package/dist/browser-dev/node_modules/@xstate/react/es/fsm.mjs.map +1 -1
  38. package/dist/browser-dev/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  39. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs.map +1 -1
  40. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  41. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs.map +1 -1
  42. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs.map +1 -1
  43. package/dist/browser-dev/node_modules/use-sync-external-store/shim/index.mjs.map +1 -1
  44. package/dist/browser-dev/node_modules/use-sync-external-store/shim/with-selector.mjs.map +1 -1
  45. package/dist/browser-dev/optionValueDecoder.mjs.map +1 -1
  46. package/dist/browser-dev/packages/hydrogen-react/package.json.mjs +1 -1
  47. package/dist/browser-dev/parse-metafield.mjs +26 -1
  48. package/dist/browser-dev/parse-metafield.mjs.map +1 -1
  49. package/dist/browser-dev/storefront-api-constants.mjs +1 -1
  50. package/dist/browser-dev/storefront-api-constants.mjs.map +1 -1
  51. package/dist/browser-dev/storefront-client.mjs.map +1 -1
  52. package/dist/browser-dev/useCartAPIStateMachine.mjs.map +1 -1
  53. package/dist/browser-dev/useCartActions.mjs.map +1 -1
  54. package/dist/browser-dev/useMoney.mjs +53 -7
  55. package/dist/browser-dev/useMoney.mjs.map +1 -1
  56. package/dist/browser-dev/useSelectedOptionInUrlParam.mjs.map +1 -1
  57. package/dist/browser-dev/useShopifyCookies.mjs.map +1 -1
  58. package/dist/browser-prod/AddToCartButton.mjs.map +1 -1
  59. package/dist/browser-prod/BaseButton.mjs.map +1 -1
  60. package/dist/browser-prod/BuyNowButton.mjs.map +1 -1
  61. package/dist/browser-prod/CartCheckoutButton.mjs.map +1 -1
  62. package/dist/browser-prod/CartCost.mjs.map +1 -1
  63. package/dist/browser-prod/CartLineProvider.mjs.map +1 -1
  64. package/dist/browser-prod/CartLineQuantity.mjs.map +1 -1
  65. package/dist/browser-prod/CartLineQuantityAdjustButton.mjs.map +1 -1
  66. package/dist/browser-prod/CartProvider.mjs.map +1 -1
  67. package/dist/browser-prod/ExternalVideo.mjs.map +1 -1
  68. package/dist/browser-prod/Image.mjs.map +1 -1
  69. package/dist/browser-prod/MediaFile.mjs.map +1 -1
  70. package/dist/browser-prod/ModelViewer.mjs.map +1 -1
  71. package/dist/browser-prod/Money.mjs.map +1 -1
  72. package/dist/browser-prod/ProductPrice.mjs.map +1 -1
  73. package/dist/browser-prod/ProductProvider.mjs.map +1 -1
  74. package/dist/browser-prod/RichText.components.mjs.map +1 -1
  75. package/dist/browser-prod/RichText.mjs.map +1 -1
  76. package/dist/browser-prod/ShopPayButton.mjs.map +1 -1
  77. package/dist/browser-prod/ShopifyProvider.mjs.map +1 -1
  78. package/dist/browser-prod/Video.mjs.map +1 -1
  79. package/dist/browser-prod/analytics-schema-custom-storefront-customer-tracking.mjs.map +1 -1
  80. package/dist/browser-prod/analytics-schema-trekkie-storefront-page-view.mjs.map +1 -1
  81. package/dist/browser-prod/analytics-utils.mjs.map +1 -1
  82. package/dist/browser-prod/analytics.mjs.map +1 -1
  83. package/dist/browser-prod/cart-hooks.mjs.map +1 -1
  84. package/dist/browser-prod/cart-queries.mjs.map +1 -1
  85. package/dist/browser-prod/codegen.helpers.mjs.map +1 -1
  86. package/dist/browser-prod/cookies-utils.mjs.map +1 -1
  87. package/dist/browser-prod/flatten-connection.mjs.map +1 -1
  88. package/dist/browser-prod/getProductOptions.mjs.map +1 -1
  89. package/dist/browser-prod/load-script.mjs.map +1 -1
  90. package/dist/browser-prod/node_modules/@xstate/fsm/es/index.mjs +17 -17
  91. package/dist/browser-prod/node_modules/@xstate/fsm/es/index.mjs.map +1 -1
  92. package/dist/browser-prod/node_modules/@xstate/react/es/fsm.mjs +2 -2
  93. package/dist/browser-prod/node_modules/@xstate/react/es/fsm.mjs.map +1 -1
  94. package/dist/browser-prod/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  95. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs.map +1 -1
  96. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  97. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs.map +1 -1
  98. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs.map +1 -1
  99. package/dist/browser-prod/node_modules/use-sync-external-store/shim/index.mjs.map +1 -1
  100. package/dist/browser-prod/node_modules/use-sync-external-store/shim/with-selector.mjs.map +1 -1
  101. package/dist/browser-prod/optionValueDecoder.mjs.map +1 -1
  102. package/dist/browser-prod/packages/hydrogen-react/package.json.mjs +1 -1
  103. package/dist/browser-prod/parse-metafield.mjs +27 -1
  104. package/dist/browser-prod/parse-metafield.mjs.map +1 -1
  105. package/dist/browser-prod/storefront-api-constants.mjs +1 -1
  106. package/dist/browser-prod/storefront-api-constants.mjs.map +1 -1
  107. package/dist/browser-prod/storefront-client.mjs.map +1 -1
  108. package/dist/browser-prod/useCartAPIStateMachine.mjs.map +1 -1
  109. package/dist/browser-prod/useCartActions.mjs.map +1 -1
  110. package/dist/browser-prod/useMoney.mjs +53 -7
  111. package/dist/browser-prod/useMoney.mjs.map +1 -1
  112. package/dist/browser-prod/useSelectedOptionInUrlParam.mjs.map +1 -1
  113. package/dist/browser-prod/useShopifyCookies.mjs.map +1 -1
  114. package/dist/node-dev/AddToCartButton.js.map +1 -1
  115. package/dist/node-dev/AddToCartButton.mjs.map +1 -1
  116. package/dist/node-dev/BaseButton.js.map +1 -1
  117. package/dist/node-dev/BaseButton.mjs.map +1 -1
  118. package/dist/node-dev/BuyNowButton.js.map +1 -1
  119. package/dist/node-dev/BuyNowButton.mjs.map +1 -1
  120. package/dist/node-dev/CartCheckoutButton.js.map +1 -1
  121. package/dist/node-dev/CartCheckoutButton.mjs.map +1 -1
  122. package/dist/node-dev/CartCost.js.map +1 -1
  123. package/dist/node-dev/CartCost.mjs.map +1 -1
  124. package/dist/node-dev/CartLineProvider.js.map +1 -1
  125. package/dist/node-dev/CartLineProvider.mjs.map +1 -1
  126. package/dist/node-dev/CartLineQuantity.js.map +1 -1
  127. package/dist/node-dev/CartLineQuantity.mjs.map +1 -1
  128. package/dist/node-dev/CartLineQuantityAdjustButton.js.map +1 -1
  129. package/dist/node-dev/CartLineQuantityAdjustButton.mjs.map +1 -1
  130. package/dist/node-dev/CartProvider.js.map +1 -1
  131. package/dist/node-dev/CartProvider.mjs.map +1 -1
  132. package/dist/node-dev/ExternalVideo.js.map +1 -1
  133. package/dist/node-dev/ExternalVideo.mjs.map +1 -1
  134. package/dist/node-dev/Image.js.map +1 -1
  135. package/dist/node-dev/Image.mjs.map +1 -1
  136. package/dist/node-dev/MediaFile.js.map +1 -1
  137. package/dist/node-dev/MediaFile.mjs.map +1 -1
  138. package/dist/node-dev/ModelViewer.js.map +1 -1
  139. package/dist/node-dev/ModelViewer.mjs.map +1 -1
  140. package/dist/node-dev/Money.js.map +1 -1
  141. package/dist/node-dev/Money.mjs.map +1 -1
  142. package/dist/node-dev/ProductPrice.js.map +1 -1
  143. package/dist/node-dev/ProductPrice.mjs.map +1 -1
  144. package/dist/node-dev/ProductProvider.js.map +1 -1
  145. package/dist/node-dev/ProductProvider.mjs.map +1 -1
  146. package/dist/node-dev/RichText.components.js.map +1 -1
  147. package/dist/node-dev/RichText.components.mjs.map +1 -1
  148. package/dist/node-dev/RichText.js.map +1 -1
  149. package/dist/node-dev/RichText.mjs.map +1 -1
  150. package/dist/node-dev/ShopPayButton.js.map +1 -1
  151. package/dist/node-dev/ShopPayButton.mjs.map +1 -1
  152. package/dist/node-dev/ShopifyProvider.js.map +1 -1
  153. package/dist/node-dev/ShopifyProvider.mjs.map +1 -1
  154. package/dist/node-dev/Video.js.map +1 -1
  155. package/dist/node-dev/Video.mjs.map +1 -1
  156. package/dist/node-dev/analytics-schema-custom-storefront-customer-tracking.js.map +1 -1
  157. package/dist/node-dev/analytics-schema-custom-storefront-customer-tracking.mjs.map +1 -1
  158. package/dist/node-dev/analytics-schema-trekkie-storefront-page-view.js.map +1 -1
  159. package/dist/node-dev/analytics-schema-trekkie-storefront-page-view.mjs.map +1 -1
  160. package/dist/node-dev/analytics-utils.js.map +1 -1
  161. package/dist/node-dev/analytics-utils.mjs.map +1 -1
  162. package/dist/node-dev/analytics.js.map +1 -1
  163. package/dist/node-dev/analytics.mjs.map +1 -1
  164. package/dist/node-dev/cart-hooks.js.map +1 -1
  165. package/dist/node-dev/cart-hooks.mjs.map +1 -1
  166. package/dist/node-dev/cart-queries.js.map +1 -1
  167. package/dist/node-dev/cart-queries.mjs.map +1 -1
  168. package/dist/node-dev/codegen.helpers.js.map +1 -1
  169. package/dist/node-dev/codegen.helpers.mjs.map +1 -1
  170. package/dist/node-dev/cookies-utils.js.map +1 -1
  171. package/dist/node-dev/cookies-utils.mjs.map +1 -1
  172. package/dist/node-dev/flatten-connection.js.map +1 -1
  173. package/dist/node-dev/flatten-connection.mjs.map +1 -1
  174. package/dist/node-dev/getProductOptions.js.map +1 -1
  175. package/dist/node-dev/getProductOptions.mjs.map +1 -1
  176. package/dist/node-dev/load-script.js.map +1 -1
  177. package/dist/node-dev/load-script.mjs.map +1 -1
  178. package/dist/node-dev/node_modules/@xstate/fsm/es/index.js +17 -17
  179. package/dist/node-dev/node_modules/@xstate/fsm/es/index.js.map +1 -1
  180. package/dist/node-dev/node_modules/@xstate/fsm/es/index.mjs +17 -17
  181. package/dist/node-dev/node_modules/@xstate/fsm/es/index.mjs.map +1 -1
  182. package/dist/node-dev/node_modules/@xstate/react/es/fsm.js +2 -2
  183. package/dist/node-dev/node_modules/@xstate/react/es/fsm.js.map +1 -1
  184. package/dist/node-dev/node_modules/@xstate/react/es/fsm.mjs +2 -2
  185. package/dist/node-dev/node_modules/@xstate/react/es/fsm.mjs.map +1 -1
  186. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.js.map +1 -1
  187. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  188. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -1
  189. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs.map +1 -1
  190. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -1
  191. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  192. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -1
  193. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs.map +1 -1
  194. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js.map +1 -1
  195. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs.map +1 -1
  196. package/dist/node-dev/node_modules/use-sync-external-store/shim/index.js.map +1 -1
  197. package/dist/node-dev/node_modules/use-sync-external-store/shim/index.mjs.map +1 -1
  198. package/dist/node-dev/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -1
  199. package/dist/node-dev/node_modules/use-sync-external-store/shim/with-selector.mjs.map +1 -1
  200. package/dist/node-dev/optionValueDecoder.js.map +1 -1
  201. package/dist/node-dev/optionValueDecoder.mjs.map +1 -1
  202. package/dist/node-dev/packages/hydrogen-react/package.json.js +1 -1
  203. package/dist/node-dev/packages/hydrogen-react/package.json.mjs +1 -1
  204. package/dist/node-dev/parse-metafield.js +26 -1
  205. package/dist/node-dev/parse-metafield.js.map +1 -1
  206. package/dist/node-dev/parse-metafield.mjs +26 -1
  207. package/dist/node-dev/parse-metafield.mjs.map +1 -1
  208. package/dist/node-dev/storefront-api-constants.js +1 -1
  209. package/dist/node-dev/storefront-api-constants.js.map +1 -1
  210. package/dist/node-dev/storefront-api-constants.mjs +1 -1
  211. package/dist/node-dev/storefront-api-constants.mjs.map +1 -1
  212. package/dist/node-dev/storefront-client.js.map +1 -1
  213. package/dist/node-dev/storefront-client.mjs.map +1 -1
  214. package/dist/node-dev/useCartAPIStateMachine.js.map +1 -1
  215. package/dist/node-dev/useCartAPIStateMachine.mjs.map +1 -1
  216. package/dist/node-dev/useCartActions.js.map +1 -1
  217. package/dist/node-dev/useCartActions.mjs.map +1 -1
  218. package/dist/node-dev/useMoney.js +53 -7
  219. package/dist/node-dev/useMoney.js.map +1 -1
  220. package/dist/node-dev/useMoney.mjs +53 -7
  221. package/dist/node-dev/useMoney.mjs.map +1 -1
  222. package/dist/node-dev/useSelectedOptionInUrlParam.js.map +1 -1
  223. package/dist/node-dev/useSelectedOptionInUrlParam.mjs.map +1 -1
  224. package/dist/node-dev/useShopifyCookies.js.map +1 -1
  225. package/dist/node-dev/useShopifyCookies.mjs.map +1 -1
  226. package/dist/node-prod/AddToCartButton.js.map +1 -1
  227. package/dist/node-prod/AddToCartButton.mjs.map +1 -1
  228. package/dist/node-prod/BaseButton.js.map +1 -1
  229. package/dist/node-prod/BaseButton.mjs.map +1 -1
  230. package/dist/node-prod/BuyNowButton.js.map +1 -1
  231. package/dist/node-prod/BuyNowButton.mjs.map +1 -1
  232. package/dist/node-prod/CartCheckoutButton.js.map +1 -1
  233. package/dist/node-prod/CartCheckoutButton.mjs.map +1 -1
  234. package/dist/node-prod/CartCost.js.map +1 -1
  235. package/dist/node-prod/CartCost.mjs.map +1 -1
  236. package/dist/node-prod/CartLineProvider.js.map +1 -1
  237. package/dist/node-prod/CartLineProvider.mjs.map +1 -1
  238. package/dist/node-prod/CartLineQuantity.js.map +1 -1
  239. package/dist/node-prod/CartLineQuantity.mjs.map +1 -1
  240. package/dist/node-prod/CartLineQuantityAdjustButton.js.map +1 -1
  241. package/dist/node-prod/CartLineQuantityAdjustButton.mjs.map +1 -1
  242. package/dist/node-prod/CartProvider.js.map +1 -1
  243. package/dist/node-prod/CartProvider.mjs.map +1 -1
  244. package/dist/node-prod/ExternalVideo.js.map +1 -1
  245. package/dist/node-prod/ExternalVideo.mjs.map +1 -1
  246. package/dist/node-prod/Image.js.map +1 -1
  247. package/dist/node-prod/Image.mjs.map +1 -1
  248. package/dist/node-prod/MediaFile.js.map +1 -1
  249. package/dist/node-prod/MediaFile.mjs.map +1 -1
  250. package/dist/node-prod/ModelViewer.js.map +1 -1
  251. package/dist/node-prod/ModelViewer.mjs.map +1 -1
  252. package/dist/node-prod/Money.js.map +1 -1
  253. package/dist/node-prod/Money.mjs.map +1 -1
  254. package/dist/node-prod/ProductPrice.js.map +1 -1
  255. package/dist/node-prod/ProductPrice.mjs.map +1 -1
  256. package/dist/node-prod/ProductProvider.js.map +1 -1
  257. package/dist/node-prod/ProductProvider.mjs.map +1 -1
  258. package/dist/node-prod/RichText.components.js.map +1 -1
  259. package/dist/node-prod/RichText.components.mjs.map +1 -1
  260. package/dist/node-prod/RichText.js.map +1 -1
  261. package/dist/node-prod/RichText.mjs.map +1 -1
  262. package/dist/node-prod/ShopPayButton.js.map +1 -1
  263. package/dist/node-prod/ShopPayButton.mjs.map +1 -1
  264. package/dist/node-prod/ShopifyProvider.js.map +1 -1
  265. package/dist/node-prod/ShopifyProvider.mjs.map +1 -1
  266. package/dist/node-prod/Video.js.map +1 -1
  267. package/dist/node-prod/Video.mjs.map +1 -1
  268. package/dist/node-prod/analytics-schema-custom-storefront-customer-tracking.js.map +1 -1
  269. package/dist/node-prod/analytics-schema-custom-storefront-customer-tracking.mjs.map +1 -1
  270. package/dist/node-prod/analytics-schema-trekkie-storefront-page-view.js.map +1 -1
  271. package/dist/node-prod/analytics-schema-trekkie-storefront-page-view.mjs.map +1 -1
  272. package/dist/node-prod/analytics-utils.js.map +1 -1
  273. package/dist/node-prod/analytics-utils.mjs.map +1 -1
  274. package/dist/node-prod/analytics.js.map +1 -1
  275. package/dist/node-prod/analytics.mjs.map +1 -1
  276. package/dist/node-prod/cart-hooks.js.map +1 -1
  277. package/dist/node-prod/cart-hooks.mjs.map +1 -1
  278. package/dist/node-prod/cart-queries.js.map +1 -1
  279. package/dist/node-prod/cart-queries.mjs.map +1 -1
  280. package/dist/node-prod/codegen.helpers.js.map +1 -1
  281. package/dist/node-prod/codegen.helpers.mjs.map +1 -1
  282. package/dist/node-prod/cookies-utils.js.map +1 -1
  283. package/dist/node-prod/cookies-utils.mjs.map +1 -1
  284. package/dist/node-prod/flatten-connection.js.map +1 -1
  285. package/dist/node-prod/flatten-connection.mjs.map +1 -1
  286. package/dist/node-prod/getProductOptions.js.map +1 -1
  287. package/dist/node-prod/getProductOptions.mjs.map +1 -1
  288. package/dist/node-prod/load-script.js.map +1 -1
  289. package/dist/node-prod/load-script.mjs.map +1 -1
  290. package/dist/node-prod/node_modules/@xstate/fsm/es/index.js +17 -17
  291. package/dist/node-prod/node_modules/@xstate/fsm/es/index.js.map +1 -1
  292. package/dist/node-prod/node_modules/@xstate/fsm/es/index.mjs +17 -17
  293. package/dist/node-prod/node_modules/@xstate/fsm/es/index.mjs.map +1 -1
  294. package/dist/node-prod/node_modules/@xstate/react/es/fsm.js +2 -2
  295. package/dist/node-prod/node_modules/@xstate/react/es/fsm.js.map +1 -1
  296. package/dist/node-prod/node_modules/@xstate/react/es/fsm.mjs +2 -2
  297. package/dist/node-prod/node_modules/@xstate/react/es/fsm.mjs.map +1 -1
  298. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.js.map +1 -1
  299. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  300. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -1
  301. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs.map +1 -1
  302. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -1
  303. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  304. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -1
  305. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs.map +1 -1
  306. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js.map +1 -1
  307. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs.map +1 -1
  308. package/dist/node-prod/node_modules/use-sync-external-store/shim/index.js.map +1 -1
  309. package/dist/node-prod/node_modules/use-sync-external-store/shim/index.mjs.map +1 -1
  310. package/dist/node-prod/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -1
  311. package/dist/node-prod/node_modules/use-sync-external-store/shim/with-selector.mjs.map +1 -1
  312. package/dist/node-prod/optionValueDecoder.js.map +1 -1
  313. package/dist/node-prod/optionValueDecoder.mjs.map +1 -1
  314. package/dist/node-prod/packages/hydrogen-react/package.json.js +1 -1
  315. package/dist/node-prod/packages/hydrogen-react/package.json.mjs +1 -1
  316. package/dist/node-prod/parse-metafield.js +27 -1
  317. package/dist/node-prod/parse-metafield.js.map +1 -1
  318. package/dist/node-prod/parse-metafield.mjs +27 -1
  319. package/dist/node-prod/parse-metafield.mjs.map +1 -1
  320. package/dist/node-prod/storefront-api-constants.js +1 -1
  321. package/dist/node-prod/storefront-api-constants.js.map +1 -1
  322. package/dist/node-prod/storefront-api-constants.mjs +1 -1
  323. package/dist/node-prod/storefront-api-constants.mjs.map +1 -1
  324. package/dist/node-prod/storefront-client.js.map +1 -1
  325. package/dist/node-prod/storefront-client.mjs.map +1 -1
  326. package/dist/node-prod/useCartAPIStateMachine.js.map +1 -1
  327. package/dist/node-prod/useCartAPIStateMachine.mjs.map +1 -1
  328. package/dist/node-prod/useCartActions.js.map +1 -1
  329. package/dist/node-prod/useCartActions.mjs.map +1 -1
  330. package/dist/node-prod/useMoney.js +53 -7
  331. package/dist/node-prod/useMoney.js.map +1 -1
  332. package/dist/node-prod/useMoney.mjs +53 -7
  333. package/dist/node-prod/useMoney.mjs.map +1 -1
  334. package/dist/node-prod/useSelectedOptionInUrlParam.js.map +1 -1
  335. package/dist/node-prod/useSelectedOptionInUrlParam.mjs.map +1 -1
  336. package/dist/node-prod/useShopifyCookies.js.map +1 -1
  337. package/dist/node-prod/useShopifyCookies.mjs.map +1 -1
  338. package/dist/types/CartLineProvider.d.ts +1 -1
  339. package/dist/types/CartProvider.d.ts +2 -2
  340. package/dist/types/Image.d.ts +1 -1
  341. package/dist/types/ModelViewer.d.ts +1 -1
  342. package/dist/types/Money.d.ts +13 -5
  343. package/dist/types/Video.d.ts +1 -1
  344. package/dist/types/cart-hooks.d.ts +3 -4
  345. package/dist/types/codegen.helpers.d.ts +2 -2
  346. package/dist/types/customer-account-api-types.d.ts +9386 -0
  347. package/dist/types/optionValueDecoder.d.ts +2 -2
  348. package/dist/types/storefront-api-constants.d.ts +1 -1
  349. package/dist/types/storefront-api-types.d.ts +143 -8
  350. package/dist/types/useCartAPIStateMachine.d.ts +2 -2
  351. package/dist/types/useCartActions.d.ts +2 -2
  352. package/dist/types/useMoney.d.ts +16 -2
  353. package/dist/umd/hydrogen-react.dev.js +100 -29
  354. package/dist/umd/hydrogen-react.dev.js.map +1 -1
  355. package/dist/umd/hydrogen-react.prod.js +13 -13
  356. package/dist/umd/hydrogen-react.prod.js.map +1 -1
  357. package/package.json +26 -25
  358. package/storefront.schema.json +1 -1
  359. package/dist/browser-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.mjs +0 -6
  360. package/dist/browser-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.mjs.map +0 -1
  361. package/dist/browser-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.mjs +0 -6
  362. package/dist/browser-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.mjs.map +0 -1
  363. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js +0 -5
  364. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js.map +0 -1
  365. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.mjs +0 -6
  366. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.mjs.map +0 -1
  367. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js +0 -5
  368. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js.map +0 -1
  369. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.mjs +0 -6
  370. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProductPrice.mjs","sources":["../../src/ProductPrice.tsx"],"sourcesContent":["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"],"names":["variant"],"mappings":";;;AAwBO,SAAS,aAGd,OAEoB;;AACd,QAAA;AAAA,IACJ,YAAY;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,GAAG;AAAA,EAAA,IACD;AAEJ,MAAI,WAAW,MAAM;AACb,UAAA,IAAI,MAAM,uDAAuD;AAAA,EAAA;AAGrE,MAAA;AACA,MAAA;AAEJ,QAAM,UAAU,YACX,mBAAkB,mCAAS,aAAY,CAAE,CAAA,EAAE;AAAA,IAC1C,CAACA,cAAYA,qCAAS,QAAO;AAAA,OAC1B,OACL;AAEE,QAAA,uBACJ,cAAc,QAAQ,oBAAoB;AAE5C,MAAI,cAAc,aAAa;AAC7B,QAAI,aAAa,SAAS;AACxB,cAAQ,QAAQ;AAAA,IAAA,OACX;AACG,eAAA,wCAAS,wBAAT,mBAA+B;AAAA,IAAoB;AAGzD,QAAA;AACJ,QAAI,aAAa,SAAS;AACxB,sBAAgB,aAAW,aAAQ,UAAR,mBAAe,WAAU,GAAG;AAAA,IAAA,OAClD;AACW,sBAAA;AAAA,UACd,8CAAS,eAAT,mBAAsB,0BAAtB,mBAA6C,WAAU;AAAA,MACzD;AAAA,IAAA;AAGF,UAAM,yBAAyB,YAAW,+BAAO,WAAU,GAAG;AAE9D,QAAI,iBAAiB,wBAAwB;AACpC,aAAA;AAAA,IAAA;AAAA,EACT,OACK;AACL,QAAI,aAAa,SAAS;AACxB,cAAQ,QAAQ;AAChB,UAAI,cAAc,QAAQ;AACxB,gBAAQ,QAAQ;AAChB,sBAAc,QAAQ;AAAA,MAAA;AAAA,IACxB,WACS,cAAc,OAAO;AAC9B,eAAQ,aAAQ,eAAR,mBAAoB;AAAA,IAAA,OACvB;AACL,eAAQ,aAAQ,eAAR,mBAAoB;AAAA,IAAA;AAAA,EAC9B;AAGF,MAAI,CAAC,OAAO;AACH,WAAA;AAAA,EAAA;AAGT,MAAI,aAAa;AACf,+BACG,OAAO,EAAA,GAAG,kBAAkB,MAAM,OAAO,aAA0B;AAAA,EAAA;AAIxE,SAAQ,oBAAA,OAAA,EAAO,GAAG,kBAAkB,MAAM,OAAO;AACnD;"}
1
+ {"version":3,"file":"ProductPrice.mjs","sources":["../../src/ProductPrice.tsx"],"sourcesContent":["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"],"names":["variant"],"mappings":";;;AAwBO,SAAS,aAGd,OAEoB;;AACpB,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,GAAG;AAAA,EAAA,IACD;AAEJ,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEA,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,YACX,mBAAkB,mCAAS,aAAY,CAAA,CAAE,EAAE;AAAA,IAC1C,CAACA,cAAYA,qCAAS,QAAO;AAAA,EAAA,KAC1B,OACL;AAEJ,QAAM,uBACJ,cAAc,QAAQ,oBAAoB;AAE5C,MAAI,cAAc,aAAa;AAC7B,QAAI,aAAa,SAAS;AACxB,cAAQ,QAAQ;AAAA,IAClB,OAAO;AACL,eAAQ,wCAAS,wBAAT,mBAA+B;AAAA,IACzC;AAEA,QAAI;AACJ,QAAI,aAAa,SAAS;AACxB,sBAAgB,aAAW,aAAQ,UAAR,mBAAe,WAAU,GAAG;AAAA,IACzD,OAAO;AACL,sBAAgB;AAAA,UACd,8CAAS,eAAT,mBAAsB,0BAAtB,mBAA6C,WAAU;AAAA,MAAA;AAAA,IAE3D;AAEA,UAAM,yBAAyB,YAAW,+BAAO,WAAU,GAAG;AAE9D,QAAI,iBAAiB,wBAAwB;AAC3C,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AACL,QAAI,aAAa,SAAS;AACxB,cAAQ,QAAQ;AAChB,UAAI,cAAc,QAAQ;AACxB,gBAAQ,QAAQ;AAChB,sBAAc,QAAQ;AAAA,MACxB;AAAA,IACF,WAAW,cAAc,OAAO;AAC9B,eAAQ,aAAQ,eAAR,mBAAoB;AAAA,IAC9B,OAAO;AACL,eAAQ,aAAQ,eAAR,mBAAoB;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,MAAI,aAAa;AACf,+BACG,OAAA,EAAO,GAAG,kBAAkB,MAAM,OAAO,aAA0B;AAAA,EAExE;AAEA,SAAO,oBAAC,OAAA,EAAO,GAAG,kBAAkB,MAAM,OAAO;AACnD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProductProvider.mjs","sources":["../../src/ProductProvider.tsx"],"sourcesContent":["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(\n (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 },\n {} as Record<string, Set<string>>,\n );\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"],"names":["value","selectedOptions","_a"],"mappings":"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"}
1
+ {"version":3,"file":"ProductProvider.mjs","sources":["../../src/ProductProvider.tsx"],"sourcesContent":["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(\n (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 },\n {} as Record<string, Set<string>>,\n );\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"],"names":["value","selectedOptions","_a"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RichText.components.mjs","sources":["../../src/RichText.components.tsx"],"sourcesContent":["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"],"names":["List"],"mappings":";;AAmBO,MAAM,qBAAqB;AAAA,EAChC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AACf;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAKc;AACL,SAAA,oBAAC,OAAK,EAAA,UAAA,KAAK,SAAS,CAAA;AAC7B;AAEA,SAAS,QAAQ;AAAA,EACf;AACF,GAMc;AACL,SAAA,cAAc,IAAI,KAAK,SAAS,GAAG,IAAI,MAAM,KAAK,QAAQ;AACnE;AAEA,SAAS,UAAU;AAAA,EACjB;AACF,GAKc;AACL,SAAA,oBAAC,KAAG,EAAA,UAAA,KAAK,SAAS,CAAA;AAC3B;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAOc;AACR,MAAA,KAAK,QAAQ,KAAK;AACpB,+BACG,MACC,EAAA,UAAA,oBAAC,UAAQ,EAAA,UAAA,KAAK,OAAM,EACtB,CAAA;AAGJ,MAAI,KAAK,KAAM,QAAQ,oBAAA,UAAA,EAAQ,eAAK,OAAM;AAC1C,MAAI,KAAK,OAAQ,QAAQ,oBAAA,MAAA,EAAI,eAAK,OAAM;AAExC,SAAO,KAAK;AACd;AAEA,SAAS,aAAa;AAAA,EACpB;AACF,GAQc;AACZ,SACG,oBAAA,KAAA,EAAE,MAAM,KAAK,KAAK,OAAO,KAAK,OAAO,QAAQ,KAAK,QAChD,UAAA,KAAK,UACR;AAEJ;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAMc;AACZ,QAAMA,QAAO,KAAK,aAAa,cAAc,OAAO;AACpD,SAAQA,oBAAAA,OAAA,EAAM,UAAA,KAAK,SAAS,CAAA;AAC9B;AAEA,SAAS,SAAS;AAAA,EAChB;AACF,GAKc;AACL,SAAA,oBAAC,MAAI,EAAA,UAAA,KAAK,SAAS,CAAA;AAC5B;"}
1
+ {"version":3,"file":"RichText.components.mjs","sources":["../../src/RichText.components.tsx"],"sourcesContent":["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"],"names":["List"],"mappings":";;AAmBO,MAAM,qBAAqB;AAAA,EAChC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AACf;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAKc;AACZ,SAAO,oBAAC,OAAA,EAAK,UAAA,KAAK,SAAA,CAAS;AAC7B;AAEA,SAAS,QAAQ;AAAA,EACf;AACF,GAMc;AACZ,SAAO,cAAc,IAAI,KAAK,SAAS,GAAG,IAAI,MAAM,KAAK,QAAQ;AACnE;AAEA,SAAS,UAAU;AAAA,EACjB;AACF,GAKc;AACZ,SAAO,oBAAC,KAAA,EAAG,UAAA,KAAK,SAAA,CAAS;AAC3B;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAOc;AACZ,MAAI,KAAK,QAAQ,KAAK;AACpB,+BACG,MAAA,EACC,UAAA,oBAAC,UAAA,EAAQ,UAAA,KAAK,OAAM,EAAA,CACtB;AAGJ,MAAI,KAAK,KAAM,QAAO,oBAAC,UAAA,EAAQ,eAAK,OAAM;AAC1C,MAAI,KAAK,OAAQ,QAAO,oBAAC,MAAA,EAAI,eAAK,OAAM;AAExC,SAAO,KAAK;AACd;AAEA,SAAS,aAAa;AAAA,EACpB;AACF,GAQc;AACZ,SACE,oBAAC,KAAA,EAAE,MAAM,KAAK,KAAK,OAAO,KAAK,OAAO,QAAQ,KAAK,QAChD,UAAA,KAAK,UACR;AAEJ;AAEA,SAAS,KAAK;AAAA,EACZ;AACF,GAMc;AACZ,QAAMA,QAAO,KAAK,aAAa,cAAc,OAAO;AACpD,SAAO,oBAACA,OAAA,EAAM,UAAA,KAAK,SAAA,CAAS;AAC9B;AAEA,SAAS,SAAS;AAAA,EAChB;AACF,GAKc;AACZ,SAAO,oBAAC,MAAA,EAAI,UAAA,KAAK,SAAA,CAAS;AAC5B;"}
@@ -1 +1 @@
1
- {"version":3,"file":"RichText.mjs","sources":["../../src/RichText.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;;AAkBO,SAAS,SAA6D;AAAA,EAC3E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAiD;AAC3C,MAAA;AACF,UAAM,UAAU,MAAM;AACtB,UAAM,aAAa;AAAA,MACjB,MAAM,KAAK,MAAM,IAAI;AAAA,MACrB,CAAC,IAAI;AAAA,IACP;AAGE,WAAA,oBAAC,SAAS,EAAA,GAAG,kBACV,UAAA,QACG,iBAAiB,UAAU,IAC3B,yBAAyB,YAAY,UAAU,EACrD,CAAA;AAAA,WAEK,GAAG;AACV,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,OAAO;AAAA,MAAA;AAAA,IAEX;AAAA,EAAA;AAEJ;AAUA,SAAS,yBACP,aAA+B,CAAA,GAC/B,MACA,QAAQ,GACG;AACP,MAAA;AACJ,MAAI,cAAc,MAAM;AACtB,eAAW,KAAK,SAAS;AAAA,MAAI,CAAC,OAAO,eACnC,yBAAyB,YAAY,OAAO,UAAU;AAAA,IACxD;AAAA,EAAA;AAGI,QAAA,YACJ,WAAW,KAAK,SAAS,cAAc,aAAa,KAAK,IAAI,KAC7D,mBAAmB,KAAK,IAAI;AAE9B,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAO,KAAK;AAAA,YACZ;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACF,KAAK,QAAQ;AACL,YAAA,YAAY,KAAK,SAAS,IAC7B,MAAM,IAAI,EACV,QAAQ,CAAC,OAAO,aAAa;AAC5B,cAAM,MAAM,GAAG,KAAK,IAAI,KAAK,IAAI,QAAQ;AACzC,cAAM,cAAc;AAAA,UAClB;AAAA,UACA;AAAA,YACE;AAAA,YACA,MAAM;AAAA,cACJ,MAAM;AAAA,cACN,QAAQ,KAAK;AAAA,cACb,MAAM,KAAK;AAAA,cACX;AAAA,YAAA;AAAA,UACF;AAAA,QAEJ;AAGA,eAAO,aAAa,IAChB,cACA,CAAC,cAAc,MAAM,EAAC,KAAK,GAAG,GAAG,MAAM,CAAA,GAAG,WAAW;AAAA,MAAA,CAC1D;AAEH,aAAO,SAAS,SAAS,IACrB,cAAc,UAAU,EAAC,KAAK,MAAA,GAAQ,QAAQ,IAC9C,SAAS,CAAC;AAAA,IAAA;AAAA,IAEhB,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,KAAK,KAAK;AAAA,YACV,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,YACb;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,UAAU,KAAK;AAAA,YACf;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL;AAAA,QACA;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,EAAA;AAEN;AAEA,SAAS,iBACP,MACA,SAAmB,IACX;AACR,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,WAAK,SAAS,QAAQ,CAAC,UAAU,iBAAiB,OAAO,MAAM,CAAC;AAChE;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH,WAAK,SAAS,QAAQ,CAAC,UAAU,iBAAiB,OAAO,MAAM,CAAC;AAChE,aAAO,KAAK,GAAG;AACf;AAAA,IACF,KAAK;AACI,aAAA,KAAK,KAAK,SAAS,EAAE;AAC5B;AAAA,IACF,KAAK;AACH,WAAK,SAAS,QAAQ,CAAC,UAAU,iBAAiB,OAAO,MAAM,CAAC;AAChE;AAAA,IACF,KAAK;AACE,WAAA,SAAS,QAAQ,CAAC,SAAS;AAC9B,YAAI,KAAK,UAAU;AACjB,eAAK,SAAS,QAAQ,CAAC,UAAU,iBAAiB,OAAO,MAAM,CAAC;AAAA,QAAA;AAElE,eAAO,KAAK,GAAG;AAAA,MAAA,CAChB;AACD;AAAA,IACF;AACE,YAAM,IAAI,MAAM,4BAA4B,KAAK,IAAI,EAAE;AAAA,EAAA;AAG3D,SAAO,OAAO,KAAK,EAAE,EAAE,KAAK;AAC9B;"}
1
+ {"version":3,"file":"RichText.mjs","sources":["../../src/RichText.tsx"],"sourcesContent":["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"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ShopPayButton.mjs","sources":["../../src/ShopPayButton.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;;;AAyDA,MAAM,aACJ;AAEF,SAAS,UACP,SACqE;AAC9D,SAAA,YAAY,cAAc,YAAY;AAC/C;AAOO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAAoC;AAClC,QAAM,OAAO,QAAQ;AACf,QAAA,cAAc,iBAAgB,6BAAM;AACpC,QAAA,sBAAsB,cAAc,UAAU;AAEpD,MAAI,MAAgB,CAAC;AACjB,MAAA;AAEJ,MAAI,CAAC,eAAe,gBAAgB,sBAAsB,aAAa;AAC/D,UAAA,IAAI,MAAM,8BAA8B;AAAA,EAAA;AAGhD,MAAI,cAAc,yBAAyB;AACnC,UAAA,IAAI,MAAM,uBAAuB;AAAA,EAAA;AAGrC,MAAA,CAAC,cAAc,CAAC,yBAAyB;AACrC,UAAA,IAAI,MAAM,wBAAwB;AAAA,EAAA;AAG1C,MAAI,SAAS;AACP,QAAA,UAAU,OAAO,GAAG;AACD,2BAAA;AAAA,IAAA,OAChB;AACC,YAAA,IAAI,MAAM,0BAA0B;AAAA,IAAA;AAAA,EAC5C;AAGF,MAAI,YAAY;AACd,UAAM,WAAW,OAAiB,CAAC,MAAM,SAAS;AAC1C,YAAA,SAAS,SAAS,IAAI,EAAE;AAC9B,UAAI,QAAQ;AACV,aAAK,KAAK,MAAM;AAAA,MAAA;AAEX,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,aACI,yBAAyB;AAClC,UAAM,wBAAwB,OAAiB,CAAC,MAAM,SAAS;AAC7D,YAAM,SAAS,SAAS,6BAAM,EAAE,EAAE;AAClC,UAAI,QAAQ;AACV,aAAK,KAAK,GAAG,MAAM,KAAI,6BAAM,aAAY,CAAC,EAAE;AAAA,MAAA;AAEvC,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,EAAA,OACA;AACC,UAAA,IAAI,MAAM,wBAAwB;AAAA,EAAA;AAGtC,MAAA,IAAI,WAAW,GAAG;AACd,UAAA,IAAI,MAAM,wBAAwB;AAAA,EAAA;AAG1C,QAAM,QAAQ,QACT;AAAA,IACC,2BAA2B;AAAA,EAAA,IAE7B;AAEJ,SACG,oBAAA,OAAA,EAAI,WAAsB,OACxB,kCAAwB,UACvB;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAI,qBAAqB,EAAC,SAAS,uBAAsB,CAAC;AAAA,MAC3D,aAAW;AAAA,MACX,UAAU,IAAI,KAAK,GAAG;AAAA,IAAA;AAAA,EAAA,GAG5B;AAEJ;AAEO,MAAM,iCACX;AACK,MAAM,2BAA2B;AACjC,MAAM,2BAA2B;AACjC,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;"}
1
+ {"version":3,"file":"ShopPayButton.mjs","sources":["../../src/ShopPayButton.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;;;AAyDA,MAAM,aACJ;AAEF,SAAS,UACP,SACqE;AACrE,SAAO,YAAY,cAAc,YAAY;AAC/C;AAOO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAAoC;AAClC,QAAM,OAAO,QAAA;AACb,QAAM,cAAc,iBAAgB,6BAAM;AAC1C,QAAM,sBAAsB,cAAc,UAAU;AAEpD,MAAI,MAAgB,CAAA;AACpB,MAAI;AAEJ,MAAI,CAAC,eAAe,gBAAgB,sBAAsB,aAAa;AACrE,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAEA,MAAI,cAAc,yBAAyB;AACzC,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,MAAI,CAAC,cAAc,CAAC,yBAAyB;AAC3C,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,MAAI,SAAS;AACX,QAAI,UAAU,OAAO,GAAG;AACtB,2BAAqB;AAAA,IACvB,OAAO;AACL,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,YAAY;AACd,UAAM,WAAW,OAAiB,CAAC,MAAM,SAAS;AAChD,YAAM,SAAS,SAAS,IAAI,EAAE;AAC9B,UAAI,QAAQ;AACV,aAAK,KAAK,MAAM;AAAA,MAClB;AACA,aAAO;AAAA,IACT,GAAG,CAAA,CAAE;AAAA,EACP,WAAW,yBAAyB;AAClC,UAAM,wBAAwB,OAAiB,CAAC,MAAM,SAAS;AAC7D,YAAM,SAAS,SAAS,6BAAM,EAAE,EAAE;AAClC,UAAI,QAAQ;AACV,aAAK,KAAK,GAAG,MAAM,KAAI,6BAAM,aAAY,CAAC,EAAE;AAAA,MAC9C;AACA,aAAO;AAAA,IACT,GAAG,CAAA,CAAE;AAAA,EACP,OAAO;AACL,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,QAAM,QAAQ,QACT;AAAA,IACC,2BAA2B;AAAA,EAAA,IAE7B;AAEJ,SACE,oBAAC,OAAA,EAAI,WAAsB,OACxB,kCAAwB,UACvB;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAI,qBAAqB,EAAC,SAAS,mBAAA,IAAsB,CAAA;AAAA,MAC1D,aAAW;AAAA,MACX,UAAU,IAAI,KAAK,GAAG;AAAA,IAAA;AAAA,EAAA,GAG5B;AAEJ;AAEO,MAAM,iCACX;AACK,MAAM,2BAA2B;AACjC,MAAM,2BAA2B;AACjC,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ShopifyProvider.mjs","sources":["../../src/ShopifyProvider.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;;;AAKO,MAAM,wBAA6C;AAAA,EACxD,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,sBAAsB;AACb,WAAA;AAAA,EACT;AAAA,EACA,wBAAwB;AACtB,WAAO,CAAC;AAAA,EACV;AAAA,EACA,mBAAmB;AACV,WAAA;AAAA,EAAA;AAEX;AAEA,MAAM,iBAAiB;AAAA,EACrB;AACF;AAKO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,GAAsC;AACpC,MACE,CAAC,cAAc,kBACf,CAAC,cAAc,mBACf,CAAC,cAAc,eACf,CAAC,cAAc,mBACf,CAAC,cAAc,sBACf;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EAAA;AAGE,MAAA,cAAc,yBAAyB,eAAe;AAChD,YAAA;AAAA,MACN,oGAAoG,aAAa,4CAA4C,cAAc,oBAAoB;AAAA,IACjM;AAAA,EAAA;AAGI,QAAA,cAAc,QAA6B,MAAM;AACrD,aAAS,iBAAiB,eAAgD;AAClE,YAAA,UAAS,+CAAe,gBAAe,cAAc;AAC3D,aAAO,OAAO,SAAS,KAAK,IAAI,SAAS,WAAW,MAAM;AAAA,IAAA;AAGrD,WAAA;AAAA,MACL,GAAG;AAAA,MACH,sBAAsB,eAAuC;AACpD,eAAA;AAAA,UACL,cAAc;AAAA,UACd,cAAc;AAAA,UACd,cAAc,mBAAmB,cAAc;AAAA,QACjD;AAAA,MACF;AAAA,MACA;AAAA,MACA,oBAAoB,eAAuB;AACzC,cAAM,iBAAiB,iBAAiB;AAAA,UACtC,cAAa,+CAAe,gBAAe,cAAc;AAAA,QAAA,CAC1D;AACD,eAAO,GAAG,cAAc,GACtB,eAAe,SAAS,GAAG,IAAI,KAAK,GACtC,QACE,+CAAe,yBACf,cAAc,oBAChB;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA,GACC,CAAC,aAAa,CAAC;AAElB,6BACG,eAAe,UAAf,EAAwB,OAAO,aAC7B,UACH;AAEJ;AAKO,SAAS,UAA+B;AACvC,QAAA,cAAc,WAAW,cAAc;AAC7C,MAAI,CAAC,aAAa;AACV,UAAA,IAAI,MAAM,wDAAwD;AAAA,EAAA;AAEnE,SAAA;AACT;"}
1
+ {"version":3,"file":"ShopifyProvider.mjs","sources":["../../src/ShopifyProvider.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;;;AAKO,MAAM,wBAA6C;AAAA,EACxD,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,sBAAsB;AACpB,WAAO;AAAA,EACT;AAAA,EACA,wBAAwB;AACtB,WAAO,CAAA;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AACF;AAEA,MAAM,iBAAiB;AAAA,EACrB;AACF;AAKO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,GAAsC;AACpC,MACE,CAAC,cAAc,kBACf,CAAC,cAAc,mBACf,CAAC,cAAc,eACf,CAAC,cAAc,mBACf,CAAC,cAAc,sBACf;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAI,cAAc,yBAAyB,eAAe;AACxD,YAAQ;AAAA,MACN,oGAAoG,aAAa,4CAA4C,cAAc,oBAAoB;AAAA,IAAA;AAAA,EAEnM;AAEA,QAAM,cAAc,QAA6B,MAAM;AACrD,aAAS,iBAAiB,eAAgD;AACxE,YAAM,UAAS,+CAAe,gBAAe,cAAc;AAC3D,aAAO,OAAO,SAAS,KAAK,IAAI,SAAS,WAAW,MAAM;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,sBAAsB,eAAuC;AAC3D,eAAO;AAAA,UACL,cAAc;AAAA,UACd,cAAc;AAAA,UACd,cAAc,mBAAmB,cAAc;AAAA,QAAA;AAAA,MAEnD;AAAA,MACA;AAAA,MACA,oBAAoB,eAAuB;AACzC,cAAM,iBAAiB,iBAAiB;AAAA,UACtC,cAAa,+CAAe,gBAAe,cAAc;AAAA,QAAA,CAC1D;AACD,eAAO,GAAG,cAAc,GACtB,eAAe,SAAS,GAAG,IAAI,KAAK,GACtC,QACE,+CAAe,yBACf,cAAc,oBAChB;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAC,aAAa,CAAC;AAElB,6BACG,eAAe,UAAf,EAAwB,OAAO,aAC7B,UACH;AAEJ;AAKO,SAAS,UAA+B;AAC7C,QAAM,cAAc,WAAW,cAAc;AAC7C,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Video.mjs","sources":["../../src/Video.tsx"],"sourcesContent":["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-04/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"],"names":[],"mappings":";;;AAmBO,MAAM,QAAQ,WAGnB,CAAC,OAAO,QAAqB;;AACvB,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA,KAAK,KAAK;AAAA,IACV,cAAc;AAAA,IACd,WAAW;AAAA,IACX,cAAc,CAAC;AAAA,IACf,GAAG;AAAA,EAAA,IACD;AAEJ,QAAM,YAAY,cAAc;AAAA,IAC9B,OAAK,UAAK,iBAAL,mBAAmB,QAAO;AAAA,IAC/B,GAAG;AAAA,EAAA,CACJ;AAEG,MAAA,CAAC,KAAK,SAAS;AACX,UAAA,IAAI,MAAM,0CAA0C;AAAA,EAAA;AAG5D;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QAEC,UAAK,KAAA,QAAQ,IAAI,CAAC,WAAW;AAC5B,cAAI,GAAE,iCAAQ,SAAO,iCAAQ,YAAW;AAChC,kBAAA,IAAI,MAAM,mDAAmD;AAAA,UAAA;AAGnE,iBAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACE,GAAG;AAAA,cACJ,KAAK,OAAO;AAAA,cACZ,KAAK,OAAO;AAAA,cACZ,MAAM,OAAO;AAAA,YAAA;AAAA,UACf;AAAA,QAEH,CAAA;AAAA,MAAA;AAAA,IAAA;AAAA;AAGP,CAAC;"}
1
+ {"version":3,"file":"Video.mjs","sources":["../../src/Video.tsx"],"sourcesContent":["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-07/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"],"names":[],"mappings":";;;AAmBO,MAAM,QAAQ,WAGnB,CAAC,OAAO,QAAqB;;AAC7B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,KAAK,KAAK;AAAA,IACV,cAAc;AAAA,IACd,WAAW;AAAA,IACX,cAAc,CAAA;AAAA,IACd,GAAG;AAAA,EAAA,IACD;AAEJ,QAAM,YAAY,cAAc;AAAA,IAC9B,OAAK,UAAK,iBAAL,mBAAmB,QAAO;AAAA,IAC/B,GAAG;AAAA,EAAA,CACJ;AAED,MAAI,CAAC,KAAK,SAAS;AACjB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAEA;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QAEC,UAAA,KAAK,QAAQ,IAAI,CAAC,WAAW;AAC5B,cAAI,GAAE,iCAAQ,SAAO,iCAAQ,YAAW;AACtC,kBAAM,IAAI,MAAM,mDAAmD;AAAA,UACrE;AACA,iBACE;AAAA,YAAC;AAAA,YAAA;AAAA,cACE,GAAG;AAAA,cACJ,KAAK,OAAO;AAAA,cACZ,KAAK,OAAO;AAAA,cACZ,MAAM,OAAO;AAAA,YAAA;AAAA,UAAA;AAAA,QAGnB,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA;AAGP,CAAC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-schema-custom-storefront-customer-tracking.mjs","sources":["../../src/analytics-schema-custom-storefront-customer-tracking.ts"],"sourcesContent":["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 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: cartToken?.id ? `${cartToken.id}` : null,\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"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analytics-schema-custom-storefront-customer-tracking.mjs","sources":["../../src/analytics-schema-custom-storefront-customer-tracking.ts"],"sourcesContent":["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 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: cartToken?.id ? `${cartToken.id}` : null,\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"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-schema-trekkie-storefront-page-view.mjs","sources":["../../src/analytics-schema-trekkie-storefront-page-view.ts"],"sourcesContent":["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"],"names":[],"mappings":";;;AASA,MAAM,YAAY;AAClB,MAAM,gBAAgB;AAEf,SAAS,SACd,SACwB;AACxB,QAAM,kBAAkB;AACxB,QAAM,EAAC,IAAI,SAAA,IAAY,SAAS,gBAAgB,UAAU;AAC1D,QAAM,eAAe,WAAW,SAAS,YAAgB,IAAA;AAClD,SAAA;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,QACE;AAAA,UACE,UAAU,gBAAgB;AAAA,UAC1B,YAAY,SAAS,SAAS,gBAAgB,UAAU,EAAE,MAAM,GAAG;AAAA,UACnE;AAAA,UACA,YAAY,SAAS,EAAE;AAAA,QACzB;AAAA,QACA,cAAc,eAAe;AAAA,MAAA;AAAA,IAC/B;AAAA,EAEJ;AACF;AAEA,SAAS,cACP,SACwB;AACjB,SAAA;AAAA,IACL,aAAa,QAAQ,sBACjB,aAAa,QAAQ,mBAAmB,IACxC,aAAa;AAAA,IACjB,mBAAmB,kBAAkB,QAAQ,GAAG;AAAA,IAChD,sBACE,QAAQ,gBAAgB,QAAQ,wBAAwB;AAAA,IAE1D,oBAAoB,QAAQ;AAAA,IAC5B,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,IACpB,gBAAgB,UAAU;AAAA,IAC1B,mBAAmB;AAAA,IAEnB,KAAK,QAAQ;AAAA,IACb,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,OAAO,QAAQ;AAAA,IAEf,QAAQ,SAAS,SAAS,QAAQ,MAAM,EAAE,EAAE;AAAA,IAC5C,UAAU,QAAQ;AAAA,IAClB,iBAAiB,QAAQ,oBAAoB;AAAA,EAC/C;AACF;AAEA,SAAS,kBAAkB,KAAsB;AAC3C,MAAA,OAAO,QAAQ,UAAU;AACpB,WAAA;AAAA,EAAA;AAET,QAAM,WAAW,IAAI,IAAI,GAAG,EAAE;AAC9B,MAAI,SAAS,QAAQ,aAAa,MAAM,MAAM,aAAa,aAAa;AAC/D,WAAA;AAAA,EAAA;AAEF,SAAA;AACT;"}
1
+ {"version":3,"file":"analytics-schema-trekkie-storefront-page-view.mjs","sources":["../../src/analytics-schema-trekkie-storefront-page-view.ts"],"sourcesContent":["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"],"names":[],"mappings":";;;AASA,MAAM,YAAY;AAClB,MAAM,gBAAgB;AAEf,SAAS,SACd,SACwB;AACxB,QAAM,kBAAkB;AACxB,QAAM,EAAC,IAAI,SAAA,IAAY,SAAS,gBAAgB,UAAU;AAC1D,QAAM,eAAe,WAAW,SAAS,YAAA,IAAgB;AACzD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,QACE;AAAA,UACE,UAAU,gBAAgB;AAAA,UAC1B,YAAY,SAAS,SAAS,gBAAgB,UAAU,EAAE,MAAM,GAAG;AAAA,UACnE;AAAA,UACA,YAAY,SAAS,EAAE;AAAA,QAAA;AAAA,QAEzB,cAAc,eAAe;AAAA,MAAA;AAAA,IAC/B;AAAA,EACF;AAEJ;AAEA,SAAS,cACP,SACwB;AACxB,SAAO;AAAA,IACL,aAAa,QAAQ,sBACjB,aAAa,QAAQ,mBAAmB,IACxC,aAAa;AAAA,IACjB,mBAAmB,kBAAkB,QAAQ,GAAG;AAAA,IAChD,sBACE,QAAQ,gBAAgB,QAAQ,wBAAwB;AAAA,IAE1D,oBAAoB,QAAQ;AAAA,IAC5B,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,IACpB,gBAAgB,UAAA;AAAA,IAChB,mBAAmB;AAAA,IAEnB,KAAK,QAAQ;AAAA,IACb,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,OAAO,QAAQ;AAAA,IAEf,QAAQ,SAAS,SAAS,QAAQ,MAAM,EAAE,EAAE;AAAA,IAC5C,UAAU,QAAQ;AAAA,IAClB,iBAAiB,QAAQ,oBAAoB;AAAA,EAAA;AAEjD;AAEA,SAAS,kBAAkB,KAAsB;AAC/C,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,WAAW,IAAI,IAAI,GAAG,EAAE;AAC9B,MAAI,SAAS,QAAQ,aAAa,MAAM,MAAM,aAAa,aAAa;AACtE,WAAO;AAAA,EACT;AACA,SAAO;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-utils.mjs","sources":["../../src/analytics-utils.ts"],"sourcesContent":["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"],"names":[],"mappings":"AAYgB,SAAA,cACd,UACA,SACsB;AACf,SAAA;AAAA,IACL,WAAW;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR,qBAAqB,KAAK,IAAI;AAAA,IAAA;AAAA,EAElC;AACF;AAgBO,SAAS,SAAS,KAAqC;AAC5D,QAAM,gBAA4B;AAAA,IAChC,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,cAAc,IAAI,gBAAgB;AAAA,IAClC,MAAM;AAAA,EACR;AAEI,MAAA,OAAO,QAAQ,UAAU;AACpB,WAAA;AAAA,EAAA;AAGL,MAAA;AACI,UAAA,EAAC,QAAQ,cAAc,UAAU,SAAQ,IAAI,IAAI,GAAG;AACpD,UAAA,gBAAgB,SAAS,MAAM,GAAG;AACxC,UAAM,mBAAmB,cAAc,cAAc,SAAS,CAAC;AAC/D,UAAM,eAAe,cAAc,cAAc,SAAS,CAAC;AAEvD,QAAA,CAAC,oBAAoB,CAAC,cAAc;AAC/B,aAAA;AAAA,IAAA;AAGT,UAAM,KAAK,GAAG,gBAAgB,GAAG,MAAM,GAAG,IAAI,MAAM;AACpD,UAAM,aAAa,oBAAoB;AACvC,UAAM,WAAW,gBAAgB;AAEjC,WAAO,EAAC,IAAI,UAAU,YAAY,QAAQ,cAAc,KAAI;AAAA,EAAA,QACtD;AACC,WAAA;AAAA,EAAA;AAEX;AAQgB,SAAA,UACd,eACA,eACwB;AACpB,MAAA,OAAO,kBAAkB,UAAU;AACrC,WAAO,CAAC;AAAA,EAAA;AAEH,SAAA,QAAQ,aAAa,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACtD,QAAI,OAAO;AACT,oBAAc,GAAG,IAAI;AAAA,IAAA;AAAA,EACvB,CACD;AACM,SAAA;AACT;AAOO,SAAS,cAAc,QAAyB;AACjD,MAAA,OAAO,aAAa,aAAa;AAC3B,YAAA;AAAA,MACN,GAAG,MAAM;AAAA,IACX;AACO,WAAA;AAAA,EAAA;AAEF,SAAA;AACT;"}
1
+ {"version":3,"file":"analytics-utils.mjs","sources":["../../src/analytics-utils.ts"],"sourcesContent":["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"],"names":[],"mappings":"AAYO,SAAS,cACd,UACA,SACsB;AACtB,SAAO;AAAA,IACL,WAAW;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR,qBAAqB,KAAK,IAAA;AAAA,IAAI;AAAA,EAChC;AAEJ;AAgBO,SAAS,SAAS,KAAqC;AAC5D,QAAM,gBAA4B;AAAA,IAChC,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,cAAc,IAAI,gBAAA;AAAA,IAClB,MAAM;AAAA,EAAA;AAGR,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,EAAC,QAAQ,cAAc,UAAU,SAAQ,IAAI,IAAI,GAAG;AAC1D,UAAM,gBAAgB,SAAS,MAAM,GAAG;AACxC,UAAM,mBAAmB,cAAc,cAAc,SAAS,CAAC;AAC/D,UAAM,eAAe,cAAc,cAAc,SAAS,CAAC;AAE3D,QAAI,CAAC,oBAAoB,CAAC,cAAc;AACtC,aAAO;AAAA,IACT;AAEA,UAAM,KAAK,GAAG,gBAAgB,GAAG,MAAM,GAAG,IAAI,MAAM;AACpD,UAAM,aAAa,oBAAoB;AACvC,UAAM,WAAW,gBAAgB;AAEjC,WAAO,EAAC,IAAI,UAAU,YAAY,QAAQ,cAAc,KAAA;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,UACd,eACA,eACwB;AACxB,MAAI,OAAO,kBAAkB,UAAU;AACrC,WAAO,CAAA;AAAA,EACT;AACA,SAAO,QAAQ,aAAa,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACtD,QAAI,OAAO;AACT,oBAAc,GAAG,IAAI;AAAA,IACvB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAOO,SAAS,cAAc,QAAyB;AACrD,MAAI,OAAO,aAAa,aAAa;AACnC,YAAQ;AAAA,MACN,GAAG,MAAM;AAAA,IAAA;AAEX,WAAO;AAAA,EACT;AACA,SAAO;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.mjs","sources":["../../src/analytics.ts"],"sourcesContent":["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 case PerformanceNavigation.TYPE_RELOAD:\n return 'reload';\n case PerformanceNavigation.TYPE_BACK_FORWARD:\n return 'back_forward';\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"],"names":["trekkiePageView","customerPageView","customerAddToCart","customerPageView2","customerCollectionView","customerProductView","customerSearchView"],"mappings":"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"}
1
+ {"version":3,"file":"analytics.mjs","sources":["../../src/analytics.ts"],"sourcesContent":["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 case PerformanceNavigation.TYPE_RELOAD:\n return 'reload';\n case PerformanceNavigation.TYPE_BACK_FORWARD:\n return 'back_forward';\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"],"names":["trekkiePageView","customerPageView","customerAddToCart","customerPageView2","customerCollectionView","customerProductView","customerSearchView"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cart-hooks.mjs","sources":["../../src/cart-hooks.tsx"],"sourcesContent":["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 // eslint-disable-next-line @typescript-eslint/no-base-to-string\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"],"names":[],"mappings":";;;;AAiBO,SAAS,eAAe;AAC7B,QAAM,EAAC,cAAc,uBAAuB,oBAAA,IAAuB,QAAQ;AAEpE,SAAA;AAAA,IACL,CAAqB;AAAA,MACnB;AAAA,MACA;AAAA,IAAA,MAIgE;AAChE,YAAM,UAAU,sBAAsB,EAAC,aAAa,QAAO;AAE3D,UAAI,cAAc;AAChB,gBAAQ,4BAA4B,IAAI;AAAA,MAAA;AAIpC,YAAA,aAAa,kBAAkB,SAAS,MAAM;AAC5C,cAAA,2BAA2B,IAAI,WAAW,SAAS;AACnD,cAAA,2BAA2B,IAAI,WAAW,SAAS;AAEpD,aAAA,MAAM,uBAAuB;AAAA,QAClC,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,MAAM,SAAS;AAAA,UACtB;AAAA,QACD,CAAA;AAAA,MACF,CAAA,EACE;AAAA,QACC,CAAC,QACC,IAAI,KAAK;AAAA,MAAA,EAEZ,MAAM,CAAC,UAAU;AACT,eAAA;AAAA,UACL,MAAM;AAAA;AAAA,UAEN,QAAQ,+BAAO;AAAA,QACjB;AAAA,MAAA,CACD;AAAA,IACL;AAAA,IACA,CAAC,uBAAuB,cAAc,mBAAmB;AAAA,EAC3D;AACF;"}
1
+ {"version":3,"file":"cart-hooks.mjs","sources":["../../src/cart-hooks.tsx"],"sourcesContent":["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\nexport function useInstantCheckout(): {\n cart: Cart | undefined;\n checkoutUrl: Cart['checkoutUrl'];\n error: string | undefined;\n createInstantCheckout: (cartInput: CartInput) => Promise<void>;\n} {\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 // eslint-disable-next-line @typescript-eslint/no-base-to-string\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"],"names":[],"mappings":";;;;AAiBO,SAAS,eAAe;AAC7B,QAAM,EAAC,cAAc,uBAAuB,oBAAA,IAAuB,QAAA;AAEnE,SAAO;AAAA,IACL,CAAqB;AAAA,MACnB;AAAA,MACA;AAAA,IAAA,MAIgE;AAChE,YAAM,UAAU,sBAAsB,EAAC,aAAa,QAAO;AAE3D,UAAI,cAAc;AAChB,gBAAQ,4BAA4B,IAAI;AAAA,MAC1C;AAGA,YAAM,aAAa,kBAAkB,SAAS,MAAM;AACpD,cAAQ,2BAA2B,IAAI,WAAW,SAAS;AAC3D,cAAQ,2BAA2B,IAAI,WAAW,SAAS;AAE3D,aAAO,MAAM,uBAAuB;AAAA,QAClC,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,MAAM,SAAA;AAAA,UACb;AAAA,QAAA,CACD;AAAA,MAAA,CACF,EACE;AAAA,QACC,CAAC,QACC,IAAI,KAAA;AAAA,MAAK,EAEZ,MAAM,CAAC,UAAU;AAChB,eAAO;AAAA,UACL,MAAM;AAAA;AAAA,UAEN,QAAQ,+BAAO;AAAA,QAAS;AAAA,MAE5B,CAAC;AAAA,IACL;AAAA,IACA,CAAC,uBAAuB,cAAc,mBAAmB;AAAA,EAAA;AAE7D;"}
@@ -1 +1 @@
1
- {"version":3,"file":"cart-queries.mjs","sources":["../../src/cart-queries.ts"],"sourcesContent":["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"],"names":[],"mappings":"AAAO,MAAM,cAAc,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevE,YAAY;AAAA;AAAA;AAGT,MAAM,aAAa,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IActE,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,0BAA0B,CACrC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,uBAAuB,CAClC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,0BAA0B,CACrC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,YAAY,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYrE,YAAY;AAAA;AAAA;AAGH,MAAA;AAAA;AAAA,EAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"cart-queries.mjs","sources":["../../src/cart-queries.ts"],"sourcesContent":["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"],"names":[],"mappings":"AAAO,MAAM,cAAc,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevE,YAAY;AAAA;AAAA;AAGT,MAAM,aAAa,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IActE,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe1E,YAAY;AAAA;AAAA;AAGT,MAAM,0BAA0B,CACrC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,uBAAuB,CAClC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,0BAA0B,CACrC;AAAA;AAAA,EACyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAevB,YAAY;AAAA;AAAA;AAGT,MAAM,YAAY,CAAC;AAAA;AAAA,EAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYrE,YAAY;AAAA;AAAA;AAGT,MAAM;AAAA;AAAA,EAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.helpers.mjs","sources":["../../src/codegen.helpers.ts"],"sourcesContent":["/**\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-04/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-04/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"],"names":[],"mappings":"AAKO,MAAM,6BAA6B;AAAA;AAAA,EAExC,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,eAAe;AACjB;AAOO,MAAM,kCAAkC;AAAA,EAC7C,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,KAAK;AAAA,EACL,eAAe;AACjB;"}
1
+ {"version":3,"file":"codegen.helpers.mjs","sources":["../../src/codegen.helpers.ts"],"sourcesContent":["/**\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-07/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-07/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"],"names":[],"mappings":"AAKO,MAAM,6BAA6B;AAAA;AAAA,EAExC,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,eAAe;AACjB;AAOO,MAAM,kCAAkC;AAAA,EAC7C,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,KAAK;AAAA,EACL,eAAe;AACjB;"}
@@ -1 +1 @@
1
- {"version":3,"file":"cookies-utils.mjs","sources":["../../src/cookies-utils.tsx"],"sourcesContent":["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"],"names":[],"mappings":";;AAIA,MAAM,YAAY;AAEX,SAAS,YAAoB;AAClC,MAAI,OAAO;AAEP,MAAA;AACF,UAAM,SAAiB,OAAO;AACxB,UAAA,oBAAoB,IAAI,YAAY,EAAE;AAC5C,WAAO,gBAAgB,iBAAiB;AAGxC,QAAI,IAAI;AACR,WAAO,UACJ,QAAQ,QAAQ,CAAC,MAAsB;AAChC,YAAA,IAAI,kBAAkB,CAAC,IAAI;AACjC,YAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC;AACO,aAAA,EAAE,SAAS,EAAE;AAAA,IACrB,CAAA,EACA,YAAY;AAAA,WACR,KAAK;AAEZ,WAAO,UACJ,QAAQ,QAAQ,CAAC,MAAsB;AACtC,YAAM,IAAK,KAAK,OAAO,IAAI,KAAM;AACjC,YAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AAC/B,aAAA,EAAE,SAAS,EAAE;AAAA,IACrB,CAAA,EACA,YAAY;AAAA,EAAA;AAGjB,SAAO,GAAG,QAAA,CAAS,IAAI,IAAI;AAC7B;AAEO,SAAS,UAAkB;AAEhC,MAAI,aAAa;AACjB,MAAI,aAAa;AAGjB,gBAAiB,oBAAA,QAAO,QAAc,MAAA;AAElC,MAAA;AACW,iBAAA,YAAY,UAAU;AAAA,WAC5B,KAAK;AACC,iBAAA;AAAA,EAAA;AAGT,QAAA,SAAS,KAAK,IAAI,aAAa,UAAU,EAC5C,SAAS,EAAE,EACX,YAAY;AAGR,SAAA,OAAO,SAAS,GAAG,GAAG;AAC/B;AAEO,SAAS,kBAAkB,SAAiC;AAC3D,QAAA,aAAa,MAAM,OAAO;AACzB,SAAA;AAAA,IACL,CAAC,SAAS,GAAG,WAAW,SAAS,KAAK;AAAA,IACtC,CAAC,SAAS,GAAG,WAAW,SAAS,KAAK;AAAA,EACxC;AACF;"}
1
+ {"version":3,"file":"cookies-utils.mjs","sources":["../../src/cookies-utils.tsx"],"sourcesContent":["// @ts-ignore - worktop/cookie types not properly exported\nimport {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"],"names":[],"mappings":";;AAKA,MAAM,YAAY;AAEX,SAAS,YAAoB;AAClC,MAAI,OAAO;AAEX,MAAI;AACF,UAAM,SAAiB,OAAO;AAC9B,UAAM,oBAAoB,IAAI,YAAY,EAAE;AAC5C,WAAO,gBAAgB,iBAAiB;AAGxC,QAAI,IAAI;AACR,WAAO,UACJ,QAAQ,QAAQ,CAAC,MAAsB;AACtC,YAAM,IAAI,kBAAkB,CAAC,IAAI;AACjC,YAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC;AACA,aAAO,EAAE,SAAS,EAAE;AAAA,IACtB,CAAC,EACA,YAAA;AAAA,EACL,SAAS,KAAK;AAEZ,WAAO,UACJ,QAAQ,QAAQ,CAAC,MAAsB;AACtC,YAAM,IAAK,KAAK,OAAA,IAAW,KAAM;AACjC,YAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC,aAAO,EAAE,SAAS,EAAE;AAAA,IACtB,CAAC,EACA,YAAA;AAAA,EACL;AAEA,SAAO,GAAG,QAAA,CAAS,IAAI,IAAI;AAC7B;AAEO,SAAS,UAAkB;AAEhC,MAAI,aAAa;AACjB,MAAI,aAAa;AAGjB,gBAAa,oBAAI,QAAO,QAAA,MAAc;AAEtC,MAAI;AACF,iBAAa,YAAY,UAAU;AAAA,EACrC,SAAS,KAAK;AACZ,iBAAa;AAAA,EACf;AAEA,QAAM,SAAS,KAAK,IAAI,aAAa,UAAU,EAC5C,SAAS,EAAE,EACX,YAAA;AAGH,SAAO,OAAO,SAAS,GAAG,GAAG;AAC/B;AAEO,SAAS,kBAAkB,SAAiC;AACjE,QAAM,aAAa,MAAM,OAAO;AAChC,SAAO;AAAA,IACL,CAAC,SAAS,GAAG,WAAW,SAAS,KAAK;AAAA,IACtC,CAAC,SAAS,GAAG,WAAW,SAAS,KAAK;AAAA,EAAA;AAE1C;"}