@shopify/hydrogen 2026.10.0-preview.4 → 2026.10.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 (437) hide show
  1. package/dist/cli/index.mjs +23 -12
  2. package/dist/client/client.d.mts +18 -15
  3. package/dist/client/client.mjs +8 -3
  4. package/dist/client/client.mjs.map +1 -1
  5. package/dist/client/errors.d.mts +35 -13
  6. package/dist/client/errors.mjs +23 -13
  7. package/dist/client/errors.mjs.map +1 -1
  8. package/dist/client/types.d.mts +140 -90
  9. package/dist/core/analytics/cart-tracker.d.mts +19 -10
  10. package/dist/core/analytics/cart-tracker.mjs +18 -10
  11. package/dist/core/analytics/cart-tracker.mjs.map +1 -1
  12. package/dist/core/analytics/events.d.mts +17 -11
  13. package/dist/core/analytics/events.mjs +13 -4
  14. package/dist/core/analytics/events.mjs.map +1 -1
  15. package/dist/core/analytics/types.d.mts +207 -118
  16. package/dist/core/analytics/utils/flatten-connection.d.mts +11 -9
  17. package/dist/core/analytics/utils/flatten-connection.mjs +7 -6
  18. package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -1
  19. package/dist/core/cache/fetch-with-cache.d.mts +24 -4
  20. package/dist/core/cache/fetch-with-cache.mjs +17 -2
  21. package/dist/core/cache/fetch-with-cache.mjs.map +1 -1
  22. package/dist/core/cache/key.d.mts +2 -0
  23. package/dist/core/cache/key.mjs.map +1 -1
  24. package/dist/core/cache/run-with-cache.d.mts +56 -8
  25. package/dist/core/cache/run-with-cache.mjs +17 -6
  26. package/dist/core/cache/run-with-cache.mjs.map +1 -1
  27. package/dist/core/cache/store.d.mts +8 -6
  28. package/dist/core/cache/store.mjs.map +1 -1
  29. package/dist/core/cache/strategies.d.mts +27 -2
  30. package/dist/core/cache/strategies.mjs +6 -0
  31. package/dist/core/cache/strategies.mjs.map +1 -1
  32. package/dist/core/cart/actions.d.mts +37 -30
  33. package/dist/core/cart/actions.mjs +21 -9
  34. package/dist/core/cart/actions.mjs.map +1 -1
  35. package/dist/core/cart/attach-quantity-input.d.mts +8 -7
  36. package/dist/core/cart/attach-quantity-input.mjs +8 -7
  37. package/dist/core/cart/attach-quantity-input.mjs.map +1 -1
  38. package/dist/core/cart/buyer-identity-sync.d.mts +7 -6
  39. package/dist/core/cart/buyer-identity-sync.mjs.map +1 -1
  40. package/dist/core/cart/cart.d.mts +59 -46
  41. package/dist/core/cart/cart.mjs +46 -29
  42. package/dist/core/cart/cart.mjs.map +1 -1
  43. package/dist/core/cart/cookie.d.mts +8 -4
  44. package/dist/core/cart/cookie.mjs +8 -4
  45. package/dist/core/cart/cookie.mjs.map +1 -1
  46. package/dist/core/cart/form.d.mts +34 -20
  47. package/dist/core/cart/form.mjs +6 -4
  48. package/dist/core/cart/form.mjs.map +1 -1
  49. package/dist/core/cart/get-cart.d.mts +27 -15
  50. package/dist/core/cart/get-cart.mjs +13 -8
  51. package/dist/core/cart/get-cart.mjs.map +1 -1
  52. package/dist/core/cart/quantity.d.mts +16 -5
  53. package/dist/core/cart/quantity.mjs +16 -5
  54. package/dist/core/cart/quantity.mjs.map +1 -1
  55. package/dist/core/cart/queries.d.mts +25 -19
  56. package/dist/core/cart/queries.mjs +15 -1
  57. package/dist/core/cart/queries.mjs.map +1 -1
  58. package/dist/core/cart/server-handlers.d.mts +82 -45
  59. package/dist/core/cart/server-handlers.mjs +4 -0
  60. package/dist/core/cart/server-handlers.mjs.map +1 -1
  61. package/dist/core/cart/state.d.mts +110 -64
  62. package/dist/core/cart/state.mjs +24 -6
  63. package/dist/core/cart/state.mjs.map +1 -1
  64. package/dist/core/collection/collection.d.mts +52 -53
  65. package/dist/core/collection/collection.mjs +5 -3
  66. package/dist/core/collection/collection.mjs.map +1 -1
  67. package/dist/core/collection/reconciler.d.mts +23 -16
  68. package/dist/core/collection/reconciler.mjs +8 -4
  69. package/dist/core/collection/reconciler.mjs.map +1 -1
  70. package/dist/core/collection/state.d.mts +31 -26
  71. package/dist/core/collection/state.mjs +4 -3
  72. package/dist/core/collection/state.mjs.map +1 -1
  73. package/dist/core/collection/url.d.mts +70 -29
  74. package/dist/core/collection/url.mjs +63 -25
  75. package/dist/core/collection/url.mjs.map +1 -1
  76. package/dist/core/constants.d.mts +1 -0
  77. package/dist/core/constants.mjs +1 -0
  78. package/dist/core/constants.mjs.map +1 -1
  79. package/dist/core/logging/logging.d.mts +14 -8
  80. package/dist/core/logging/logging.mjs +15 -10
  81. package/dist/core/logging/logging.mjs.map +1 -1
  82. package/dist/core/logging/types.d.mts +28 -11
  83. package/dist/core/logging/types.mjs.map +1 -1
  84. package/dist/core/money/format.d.mts +6 -4
  85. package/dist/core/money/format.mjs +19 -9
  86. package/dist/core/money/format.mjs.map +1 -1
  87. package/dist/core/money/types.d.mts +41 -25
  88. package/dist/core/predictive-search/form.d.mts +37 -7
  89. package/dist/core/predictive-search/form.mjs +21 -3
  90. package/dist/core/predictive-search/form.mjs.map +1 -1
  91. package/dist/core/predictive-search/queries.d.mts +18 -30
  92. package/dist/core/predictive-search/queries.mjs +7 -3
  93. package/dist/core/predictive-search/queries.mjs.map +1 -1
  94. package/dist/core/predictive-search/search.d.mts +25 -27
  95. package/dist/core/predictive-search/search.mjs +20 -19
  96. package/dist/core/predictive-search/search.mjs.map +1 -1
  97. package/dist/core/predictive-search/server-handlers.d.mts +25 -26
  98. package/dist/core/predictive-search/server-handlers.mjs +4 -0
  99. package/dist/core/predictive-search/server-handlers.mjs.map +1 -1
  100. package/dist/core/predictive-search/store.d.mts +65 -24
  101. package/dist/core/predictive-search/store.mjs +12 -1
  102. package/dist/core/predictive-search/store.mjs.map +1 -1
  103. package/dist/core/predictive-search/url.d.mts +36 -37
  104. package/dist/core/predictive-search/url.mjs +14 -6
  105. package/dist/core/predictive-search/url.mjs.map +1 -1
  106. package/dist/core/product/form.d.mts +63 -16
  107. package/dist/core/product/form.mjs +8 -2
  108. package/dist/core/product/form.mjs.map +1 -1
  109. package/dist/core/product/options.d.mts +8 -10
  110. package/dist/core/product/options.mjs +8 -10
  111. package/dist/core/product/options.mjs.map +1 -1
  112. package/dist/core/product/product-form.d.mts +77 -29
  113. package/dist/core/product/product-form.mjs +32 -10
  114. package/dist/core/product/product-form.mjs.map +1 -1
  115. package/dist/core/product/state.d.mts +55 -32
  116. package/dist/core/product/url.d.mts +19 -13
  117. package/dist/core/product/url.mjs +10 -10
  118. package/dist/core/product/url.mjs.map +1 -1
  119. package/dist/core/request-context.d.mts +77 -19
  120. package/dist/core/request-context.mjs +5 -1
  121. package/dist/core/request-context.mjs.map +1 -1
  122. package/dist/core/request-routing/handle-shopify-redirects.d.mts +12 -4
  123. package/dist/core/request-routing/handle-shopify-redirects.mjs +9 -2
  124. package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
  125. package/dist/core/request-routing/handle-shopify-routes.d.mts +5 -5
  126. package/dist/core/request-routing/handle-shopify-routes.mjs +7 -5
  127. package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -1
  128. package/dist/core/request-routing/interceptors/proxy.mjs +79 -43
  129. package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -1
  130. package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
  131. package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
  132. package/dist/core/request-routing/interceptors/url-redirects.mjs +6 -1
  133. package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
  134. package/dist/core/request-routing/interceptors/well-known.mjs +1 -1
  135. package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -1
  136. package/dist/core/request-routing/registered-routes.d.mts +12 -0
  137. package/dist/core/request-routing/registered-routes.mjs +12 -0
  138. package/dist/core/request-routing/registered-routes.mjs.map +1 -1
  139. package/dist/core/request-routing/route-types.d.mts +43 -18
  140. package/dist/core/shop-pay/shop-pay.d.mts +71 -35
  141. package/dist/core/shop-pay/shop-pay.mjs +36 -10
  142. package/dist/core/shop-pay/shop-pay.mjs.map +1 -1
  143. package/dist/core/shopify-scripts/index.d.mts +15 -5
  144. package/dist/core/shopify-scripts/index.mjs +15 -5
  145. package/dist/core/shopify-scripts/index.mjs.map +1 -1
  146. package/dist/core/shopify-scripts/initialize.d.mts +12 -4
  147. package/dist/core/shopify-scripts/initialize.mjs +12 -4
  148. package/dist/core/shopify-scripts/initialize.mjs.map +1 -1
  149. package/dist/core/shopify-scripts/types.d.mts +58 -25
  150. package/dist/core/standard-routes/build.d.mts +11 -12
  151. package/dist/core/standard-routes/build.mjs +11 -12
  152. package/dist/core/standard-routes/build.mjs.map +1 -1
  153. package/dist/core/standard-routes/types.d.mts +30 -24
  154. package/dist/core/url.mjs +2 -1
  155. package/dist/core/url.mjs.map +1 -1
  156. package/dist/customer-account/client.d.mts +36 -69
  157. package/dist/customer-account/client.mjs +7 -8
  158. package/dist/customer-account/client.mjs.map +1 -1
  159. package/dist/customer-account/errors.d.mts +45 -36
  160. package/dist/customer-account/errors.mjs +21 -36
  161. package/dist/customer-account/errors.mjs.map +1 -1
  162. package/dist/customer-account/graphql.d.mts +11 -23
  163. package/dist/customer-account/graphql.mjs +3 -9
  164. package/dist/customer-account/graphql.mjs.map +1 -1
  165. package/dist/customer-account/session.d.mts +130 -100
  166. package/dist/customer-account/session.mjs +32 -10
  167. package/dist/customer-account/session.mjs.map +1 -1
  168. package/dist/customer-account/type-resolver.d.mts +7 -8
  169. package/dist/development/client/client.d.mts +18 -15
  170. package/dist/development/client/client.mjs +8 -3
  171. package/dist/development/client/client.mjs.map +1 -1
  172. package/dist/development/client/errors.d.mts +35 -13
  173. package/dist/development/client/errors.mjs +23 -13
  174. package/dist/development/client/errors.mjs.map +1 -1
  175. package/dist/development/client/types.d.mts +140 -90
  176. package/dist/development/core/analytics/cart-tracker.d.mts +19 -10
  177. package/dist/development/core/analytics/cart-tracker.mjs +18 -10
  178. package/dist/development/core/analytics/cart-tracker.mjs.map +1 -1
  179. package/dist/development/core/analytics/events.d.mts +17 -11
  180. package/dist/development/core/analytics/events.mjs +13 -4
  181. package/dist/development/core/analytics/events.mjs.map +1 -1
  182. package/dist/development/core/analytics/types.d.mts +207 -118
  183. package/dist/development/core/analytics/utils/flatten-connection.d.mts +11 -9
  184. package/dist/development/core/analytics/utils/flatten-connection.mjs +7 -6
  185. package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -1
  186. package/dist/development/core/cache/fetch-with-cache.d.mts +24 -4
  187. package/dist/development/core/cache/fetch-with-cache.mjs +17 -2
  188. package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -1
  189. package/dist/development/core/cache/key.d.mts +2 -0
  190. package/dist/development/core/cache/key.mjs.map +1 -1
  191. package/dist/development/core/cache/run-with-cache.d.mts +56 -8
  192. package/dist/development/core/cache/run-with-cache.mjs +17 -6
  193. package/dist/development/core/cache/run-with-cache.mjs.map +1 -1
  194. package/dist/development/core/cache/store.d.mts +8 -6
  195. package/dist/development/core/cache/store.mjs.map +1 -1
  196. package/dist/development/core/cache/strategies.d.mts +27 -2
  197. package/dist/development/core/cache/strategies.mjs +6 -0
  198. package/dist/development/core/cache/strategies.mjs.map +1 -1
  199. package/dist/development/core/cart/actions.d.mts +37 -30
  200. package/dist/development/core/cart/actions.mjs +21 -9
  201. package/dist/development/core/cart/actions.mjs.map +1 -1
  202. package/dist/development/core/cart/attach-quantity-input.d.mts +8 -7
  203. package/dist/development/core/cart/attach-quantity-input.mjs +8 -7
  204. package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -1
  205. package/dist/development/core/cart/buyer-identity-sync.d.mts +6 -5
  206. package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -1
  207. package/dist/development/core/cart/cart.d.mts +59 -46
  208. package/dist/development/core/cart/cart.mjs +46 -29
  209. package/dist/development/core/cart/cart.mjs.map +1 -1
  210. package/dist/development/core/cart/cookie.d.mts +8 -4
  211. package/dist/development/core/cart/cookie.mjs +8 -4
  212. package/dist/development/core/cart/cookie.mjs.map +1 -1
  213. package/dist/development/core/cart/form.d.mts +34 -20
  214. package/dist/development/core/cart/form.mjs +6 -4
  215. package/dist/development/core/cart/form.mjs.map +1 -1
  216. package/dist/development/core/cart/get-cart.d.mts +27 -15
  217. package/dist/development/core/cart/get-cart.mjs +13 -8
  218. package/dist/development/core/cart/get-cart.mjs.map +1 -1
  219. package/dist/development/core/cart/quantity.d.mts +16 -5
  220. package/dist/development/core/cart/quantity.mjs +16 -5
  221. package/dist/development/core/cart/quantity.mjs.map +1 -1
  222. package/dist/development/core/cart/queries.d.mts +25 -19
  223. package/dist/development/core/cart/queries.mjs +15 -1
  224. package/dist/development/core/cart/queries.mjs.map +1 -1
  225. package/dist/development/core/cart/server-handlers.d.mts +82 -45
  226. package/dist/development/core/cart/server-handlers.mjs +4 -0
  227. package/dist/development/core/cart/server-handlers.mjs.map +1 -1
  228. package/dist/development/core/cart/state.d.mts +110 -64
  229. package/dist/development/core/cart/state.mjs +24 -6
  230. package/dist/development/core/cart/state.mjs.map +1 -1
  231. package/dist/development/core/collection/collection.d.mts +52 -53
  232. package/dist/development/core/collection/collection.mjs +5 -3
  233. package/dist/development/core/collection/collection.mjs.map +1 -1
  234. package/dist/development/core/collection/reconciler.d.mts +23 -16
  235. package/dist/development/core/collection/reconciler.mjs +8 -4
  236. package/dist/development/core/collection/reconciler.mjs.map +1 -1
  237. package/dist/development/core/collection/state.d.mts +31 -26
  238. package/dist/development/core/collection/state.mjs +4 -3
  239. package/dist/development/core/collection/state.mjs.map +1 -1
  240. package/dist/development/core/collection/url.d.mts +70 -29
  241. package/dist/development/core/collection/url.mjs +63 -25
  242. package/dist/development/core/collection/url.mjs.map +1 -1
  243. package/dist/development/core/constants.mjs.map +1 -1
  244. package/dist/development/core/logging/logging.d.mts +14 -8
  245. package/dist/development/core/logging/logging.mjs +15 -10
  246. package/dist/development/core/logging/logging.mjs.map +1 -1
  247. package/dist/development/core/logging/types.d.mts +28 -11
  248. package/dist/development/core/logging/types.mjs.map +1 -1
  249. package/dist/development/core/money/format.d.mts +6 -4
  250. package/dist/development/core/money/format.mjs +19 -9
  251. package/dist/development/core/money/format.mjs.map +1 -1
  252. package/dist/development/core/money/types.d.mts +41 -25
  253. package/dist/development/core/predictive-search/form.d.mts +37 -7
  254. package/dist/development/core/predictive-search/form.mjs +21 -3
  255. package/dist/development/core/predictive-search/form.mjs.map +1 -1
  256. package/dist/development/core/predictive-search/queries.d.mts +18 -30
  257. package/dist/development/core/predictive-search/queries.mjs +7 -3
  258. package/dist/development/core/predictive-search/queries.mjs.map +1 -1
  259. package/dist/development/core/predictive-search/search.d.mts +25 -27
  260. package/dist/development/core/predictive-search/search.mjs +20 -19
  261. package/dist/development/core/predictive-search/search.mjs.map +1 -1
  262. package/dist/development/core/predictive-search/server-handlers.d.mts +25 -26
  263. package/dist/development/core/predictive-search/server-handlers.mjs +4 -0
  264. package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -1
  265. package/dist/development/core/predictive-search/store.d.mts +65 -24
  266. package/dist/development/core/predictive-search/store.mjs +12 -1
  267. package/dist/development/core/predictive-search/store.mjs.map +1 -1
  268. package/dist/development/core/predictive-search/url.d.mts +36 -37
  269. package/dist/development/core/predictive-search/url.mjs +14 -6
  270. package/dist/development/core/predictive-search/url.mjs.map +1 -1
  271. package/dist/development/core/product/form.d.mts +63 -16
  272. package/dist/development/core/product/form.mjs +8 -2
  273. package/dist/development/core/product/form.mjs.map +1 -1
  274. package/dist/development/core/product/options.d.mts +8 -10
  275. package/dist/development/core/product/options.mjs +8 -10
  276. package/dist/development/core/product/options.mjs.map +1 -1
  277. package/dist/development/core/product/product-form.d.mts +77 -29
  278. package/dist/development/core/product/product-form.mjs +32 -10
  279. package/dist/development/core/product/product-form.mjs.map +1 -1
  280. package/dist/development/core/product/state.d.mts +55 -32
  281. package/dist/development/core/product/url.d.mts +19 -13
  282. package/dist/development/core/product/url.mjs +10 -10
  283. package/dist/development/core/product/url.mjs.map +1 -1
  284. package/dist/development/core/request-context.d.mts +77 -19
  285. package/dist/development/core/request-context.mjs +5 -1
  286. package/dist/development/core/request-context.mjs.map +1 -1
  287. package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +12 -4
  288. package/dist/development/core/request-routing/handle-shopify-redirects.mjs +9 -2
  289. package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
  290. package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +9 -1
  291. package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +7 -0
  292. package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -1
  293. package/dist/development/core/request-routing/handle-shopify-routes.mjs +7 -5
  294. package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -1
  295. package/dist/development/core/request-routing/interceptors/proxy.mjs +79 -43
  296. package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -1
  297. package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
  298. package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
  299. package/dist/development/core/request-routing/interceptors/url-redirects.mjs +6 -1
  300. package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
  301. package/dist/development/core/request-routing/interceptors/well-known.mjs +1 -1
  302. package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -1
  303. package/dist/development/core/request-routing/registered-routes.d.mts +12 -0
  304. package/dist/development/core/request-routing/registered-routes.mjs +12 -0
  305. package/dist/development/core/request-routing/registered-routes.mjs.map +1 -1
  306. package/dist/development/core/request-routing/route-types.d.mts +43 -18
  307. package/dist/development/core/shop-pay/shop-pay.d.mts +71 -35
  308. package/dist/development/core/shop-pay/shop-pay.mjs +36 -10
  309. package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -1
  310. package/dist/development/core/shopify-scripts/index.d.mts +15 -5
  311. package/dist/development/core/shopify-scripts/index.mjs +15 -5
  312. package/dist/development/core/shopify-scripts/index.mjs.map +1 -1
  313. package/dist/development/core/shopify-scripts/initialize.d.mts +12 -4
  314. package/dist/development/core/shopify-scripts/initialize.mjs +12 -4
  315. package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -1
  316. package/dist/development/core/shopify-scripts/types.d.mts +58 -25
  317. package/dist/development/core/standard-routes/build.d.mts +11 -12
  318. package/dist/development/core/standard-routes/build.mjs +11 -12
  319. package/dist/development/core/standard-routes/build.mjs.map +1 -1
  320. package/dist/development/core/standard-routes/types.d.mts +30 -24
  321. package/dist/development/core/url.mjs +2 -1
  322. package/dist/development/core/url.mjs.map +1 -1
  323. package/dist/development/customer-account/session.d.mts +45 -54
  324. package/dist/development/customer-account/session.mjs +20 -4
  325. package/dist/development/customer-account/session.mjs.map +1 -1
  326. package/dist/development/globals.d.mts +20 -11
  327. package/dist/development/graphql/generated/storefront-api-types.d.mts +127 -1
  328. package/dist/development/graphql/graphql.d.mts +17 -16
  329. package/dist/development/graphql/graphql.mjs +7 -8
  330. package/dist/development/graphql/graphql.mjs.map +1 -1
  331. package/dist/development/graphql/type-resolver.d.mts +15 -8
  332. package/dist/development/react/cart.d.mts +78 -32
  333. package/dist/development/react/cart.mjs +56 -29
  334. package/dist/development/react/cart.mjs.map +1 -1
  335. package/dist/development/react/collection.d.mts +40 -22
  336. package/dist/development/react/collection.mjs +27 -7
  337. package/dist/development/react/collection.mjs.map +1 -1
  338. package/dist/development/react/predictive-search.d.mts +65 -50
  339. package/dist/development/react/predictive-search.mjs +23 -21
  340. package/dist/development/react/predictive-search.mjs.map +1 -1
  341. package/dist/development/react/product.d.mts +45 -16
  342. package/dist/development/react/product.mjs +13 -11
  343. package/dist/development/react/product.mjs.map +1 -1
  344. package/dist/development/react/shop-pay.d.mts +15 -0
  345. package/dist/development/react/shop-pay.mjs +9 -0
  346. package/dist/development/react/shop-pay.mjs.map +1 -1
  347. package/dist/development/react/shopify-scripts.d.mts +23 -2
  348. package/dist/development/react/shopify-scripts.mjs +9 -0
  349. package/dist/development/react/shopify-scripts.mjs.map +1 -1
  350. package/dist/development/vue/cart.d.mts +28 -23
  351. package/dist/development/vue/cart.mjs +42 -25
  352. package/dist/development/vue/cart.mjs.map +1 -1
  353. package/dist/development/vue/collection.d.mts +20 -12
  354. package/dist/development/vue/collection.mjs +15 -7
  355. package/dist/development/vue/collection.mjs.map +1 -1
  356. package/dist/development/vue/index.d.mts +2 -2
  357. package/dist/development/vue/index.mjs +2 -2
  358. package/dist/development/vue/predictive-search.d.mts +31 -36
  359. package/dist/development/vue/predictive-search.mjs +16 -22
  360. package/dist/development/vue/predictive-search.mjs.map +1 -1
  361. package/dist/development/vue/product.d.mts +16 -15
  362. package/dist/development/vue/product.mjs +11 -11
  363. package/dist/development/vue/product.mjs.map +1 -1
  364. package/dist/development/vue/shop-pay.d.mts +14 -17
  365. package/dist/development/vue/shop-pay.mjs +8 -0
  366. package/dist/development/vue/shop-pay.mjs.map +1 -1
  367. package/dist/development/vue/shopify-scripts.d.mts +11 -0
  368. package/dist/development/vue/shopify-scripts.mjs +6 -0
  369. package/dist/development/vue/shopify-scripts.mjs.map +1 -1
  370. package/dist/globals.d.mts +20 -11
  371. package/dist/graphql/generated/storefront-api-types.d.mts +127 -1
  372. package/dist/graphql/graphql.d.mts +17 -16
  373. package/dist/graphql/graphql.mjs +7 -8
  374. package/dist/graphql/graphql.mjs.map +1 -1
  375. package/dist/graphql/type-resolver.d.mts +15 -8
  376. package/dist/react/cart.d.mts +78 -32
  377. package/dist/react/cart.mjs +56 -29
  378. package/dist/react/cart.mjs.map +1 -1
  379. package/dist/react/collection.d.mts +40 -22
  380. package/dist/react/collection.mjs +27 -7
  381. package/dist/react/collection.mjs.map +1 -1
  382. package/dist/react/predictive-search.d.mts +65 -50
  383. package/dist/react/predictive-search.mjs +23 -21
  384. package/dist/react/predictive-search.mjs.map +1 -1
  385. package/dist/react/product.d.mts +45 -16
  386. package/dist/react/product.mjs +13 -11
  387. package/dist/react/product.mjs.map +1 -1
  388. package/dist/react/shop-pay.d.mts +15 -0
  389. package/dist/react/shop-pay.mjs +9 -0
  390. package/dist/react/shop-pay.mjs.map +1 -1
  391. package/dist/react/shopify-scripts.d.mts +23 -2
  392. package/dist/react/shopify-scripts.mjs +9 -0
  393. package/dist/react/shopify-scripts.mjs.map +1 -1
  394. package/dist/ts-plugin/index.cjs +6 -0
  395. package/dist/ts-plugin/index.cjs.map +1 -1
  396. package/dist/ts-plugin/index.d.cts +6 -0
  397. package/dist/vite/local-https.d.mts +51 -17
  398. package/dist/vite/local-https.mjs +26 -5
  399. package/dist/vite/local-https.mjs.map +1 -1
  400. package/dist/vue/cart.d.mts +28 -23
  401. package/dist/vue/cart.mjs +42 -25
  402. package/dist/vue/cart.mjs.map +1 -1
  403. package/dist/vue/collection.d.mts +20 -12
  404. package/dist/vue/collection.mjs +15 -7
  405. package/dist/vue/collection.mjs.map +1 -1
  406. package/dist/vue/index.d.mts +2 -2
  407. package/dist/vue/index.mjs +2 -2
  408. package/dist/vue/predictive-search.d.mts +31 -36
  409. package/dist/vue/predictive-search.mjs +16 -22
  410. package/dist/vue/predictive-search.mjs.map +1 -1
  411. package/dist/vue/product.d.mts +16 -15
  412. package/dist/vue/product.mjs +11 -11
  413. package/dist/vue/product.mjs.map +1 -1
  414. package/dist/vue/shop-pay.d.mts +14 -17
  415. package/dist/vue/shop-pay.mjs +8 -0
  416. package/dist/vue/shop-pay.mjs.map +1 -1
  417. package/dist/vue/shopify-scripts.d.mts +11 -0
  418. package/dist/vue/shopify-scripts.mjs +6 -0
  419. package/dist/vue/shopify-scripts.mjs.map +1 -1
  420. package/package.json +3 -1
  421. package/skills/hydrogen-analytics/SKILL.md +1 -1
  422. package/skills/hydrogen-cart-ui/SKILL.md +28 -2
  423. package/skills/hydrogen-collection-browser/SKILL.md +9 -1
  424. package/skills/hydrogen-collection-browser/references/nextjs.md +1 -1
  425. package/skills/hydrogen-collection-browser/references/nuxt.md +1 -1
  426. package/skills/hydrogen-collection-browser/references/react.md +151 -32
  427. package/skills/hydrogen-customer-account/SKILL.md +2 -0
  428. package/skills/hydrogen-request-handlers/SKILL.md +21 -11
  429. package/skills/hydrogen-setup/references/analytics.md +14 -8
  430. package/skills/hydrogen-setup/steps/1-inspect-app.md +2 -2
  431. package/skills/hydrogen-setup/steps/6-product-detail-page.md +21 -11
  432. package/skills/hydrogen-storefront-client/SKILL.md +1 -1
  433. package/skills/hydrogen-storefront-client/references/caching.md +2 -0
  434. package/skills/hydrogen-variant-form/SKILL.md +25 -7
  435. package/skills/hydrogen-variant-form/references/nextjs.md +39 -4
  436. package/skills/hydrogen-variant-form/references/nuxt.md +83 -42
  437. package/skills/hydrogen-variant-form/references/react.md +45 -9
@@ -13,72 +13,103 @@ declare const CART_API_PATH: "/api/cart";
13
13
  declare const CART_GET_METHOD: "GET";
14
14
  declare const CART_POST_METHOD: "POST";
15
15
  declare const cartServerHandlersCartQuery: unique symbol;
16
- /** Response shape from the cart GET handler — the fetched cart plus any GraphQL errors. */
16
+ /**
17
+ * The response body that the cart GET handler returns.
18
+ *
19
+ * @publicDocs
20
+ */
17
21
  type CartGetData<TCart = CartData> = {
18
- cart: TCart | null;
22
+ /** The cart, or `null` when the request has no cart ID, the cart doesn't exist, or the cart query returns GraphQL errors. */cart: TCart | null; /** GraphQL errors from the cart query. The handler also logs the errors on the server. */
19
23
  errors?: Array<{
20
24
  message: string;
21
25
  }>;
22
26
  };
23
- /** Full route result from the cart GET handler — JSON with {@link CartGetData} payload and response headers. */
27
+ /**
28
+ * The JSON result that the cart GET handler returns. The handler sets private cache headers that keep CDNs and shared caches from storing the cart.
29
+ *
30
+ * @publicDocs
31
+ */
24
32
  type CartGetResult<TCart = CartData> = ShopifyRouteJsonResult<CartGetData<TCart>>;
25
- /** Machine-readable error codes returned by the cart POST handler. */
33
+ /**
34
+ * Error codes that the cart POST handler returns. The handler returns `invalid_cart_request` when it can't parse a JSON request, and `missing_cart` when a JSON request changes the cart but has no cart ID. With `customerSession`, the handler returns `cart_mutation_failed` when a mutation fails after the handler refreshes the customer's access token.
35
+ */
26
36
  type CartErrorCode = "invalid_cart_request" | "missing_cart" | "cart_mutation_failed";
27
- /** A cart route error carrying a {@link CartErrorCode} for programmatic handling. */
28
- type CartError = ShopifyRouteError & {
37
+ /**
38
+ * An error that the cart POST handler returns, with a code that identifies the failure.
39
+ *
40
+ * @publicDocs
41
+ */
42
+ interface CartError extends ShopifyRouteError {
43
+ /** The code that identifies the failure. */
29
44
  code: CartErrorCode;
30
- };
45
+ }
31
46
  /**
32
- * Result from the cart POST handler — one of:
33
- * - JSON with the mutation payload (programmatic clients)
34
- * - 303 redirect back to the referrer (HTML form submissions)
35
- * - An error with a {@link CartErrorCode}
47
+ * The route result that the cart POST handler returns. Check `type` to tell the results apart:
48
+ * - `json` answers a JSON request. The result's `data` holds the mutation's `cart`, `userErrors`, and `warnings`.
49
+ * - `redirect` answers a form submission with a `303` redirect to the referring page.
50
+ * - `error` holds a cart error with a code that identifies the failure.
51
+ *
52
+ * @publicDocs
36
53
  */
37
54
  type CartPostResult = ShopifyRouteJsonResult<Record<string, unknown>> | ShopifyRouteRedirectResult | ShopifyRouteErrorResult<CartError>;
55
+ /** The context that you pass to the cart GET handler. */
38
56
  type CartGetHandlerContext = {
39
- storefrontClient: StorefrontClient;
57
+ /** The Storefront API client that runs the cart query. */storefrontClient: StorefrontClient; /** The incoming request. Omit the request to read the cart ID from the Storefront API client's request context. */
40
58
  request?: Request;
41
59
  };
60
+ /** The context that you pass to the cart POST handler. */
42
61
  type CartPostHandlerContext = {
43
- request: Request;
62
+ /** The cart request, with a JSON, URL-encoded form, or multipart form body. */request: Request; /** The Storefront API client that runs the cart mutation. */
44
63
  storefrontClient: StorefrontClient;
45
64
  };
65
+ /** The extra context that the GET handler needs when you create the handlers with `customerSession`. */
46
66
  type CartCustomerSessionReadContext = {
47
- sessionManager: ReadonlyCustomerSessionManager;
67
+ /** The session storage that holds the customer's tokens. */sessionManager: ReadonlyCustomerSessionManager; /** The current request's context, for checking the customer's login state. */
48
68
  requestContext: ShopifyRequestContext;
49
69
  };
70
+ /** The extra context that the POST handler needs when you create the handlers with `customerSession`. */
50
71
  type CartCustomerSessionWriteContext = {
51
- sessionManager: WritableCustomerSessionManager;
72
+ /** The session storage that holds the customer's tokens. After a token refresh, the handler commits the session and adds its `Set-Cookie` headers to the response. */sessionManager: WritableCustomerSessionManager; /** The current request's context, for reading or refreshing the customer's access token. */
52
73
  requestContext: ShopifyRequestContext;
53
74
  };
75
+ /** The customer session from `createCustomerSession`. The cart handlers read the customer's login state and access token from the session. */
54
76
  type CartCustomerSession = CustomerSession;
55
- /** GET handler for the `/api/cart` route — fetches the current cart from the Storefront API. */
77
+ /** Handles GET requests to `/api/cart` and returns the current cart. */
56
78
  type CartGetHandler<TCart = CartData, TContext extends CartGetHandlerContext = CartGetHandlerContext> = CallableRouteHandler<TContext, CartGetResult<TCart>, typeof CART_API_PATH, typeof CART_GET_METHOD>;
57
- /** POST handler for the `/api/cart` route — processes cart mutations from JSON or FormData bodies. */
79
+ /** Handles POST requests to `/api/cart` and runs the cart change that the request body describes. */
58
80
  type CartPostHandler<TContext extends CartPostHandlerContext = CartPostHandlerContext> = CallableRouteHandler<TContext, CartPostResult, typeof CART_API_PATH, typeof CART_POST_METHOD>;
59
81
  /**
60
- * GET and POST handlers for the `/api/cart` route.
82
+ * The cart route handlers that `createCartServerHandlers` returns.
61
83
  *
62
- * Created by {@link createCartServerHandlers}. Register these with your
63
- * framework's router so the client cart store can communicate with the
64
- * Storefront API.
84
+ * Register the handlers with `handleShopifyRoutes` to serve the `/api/cart` route that the cart store calls.
65
85
  */
66
86
  type CartServerHandlers<TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart, TCart extends CartData = CartDataFromQuery<TCartQuery>> = {
67
- readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;
87
+ /** The cart query document that the handlers run. */readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;
88
+ /**
89
+ * Returns the current cart. The handler reads the cart ID from the request's `cartId` search parameter or `cart` cookie. Without a request, the handler reads the cart ID from the Storefront API client's request context.
90
+ *
91
+ * GraphQL errors return a `null` cart with the errors in the response body. The handler throws when the Storefront API request fails.
92
+ */
68
93
  get: CartGetHandler<TCart>;
94
+ /**
95
+ * Runs the cart change that the request describes and returns the updated cart. An add without a cart creates a cart and sets the `cart` cookie. Other changes without a cart return a `missing_cart` error for a JSON request and a redirect for a form submission.
96
+ *
97
+ * When a JSON body names a cart other than the cookie's cart, the handler leaves the cookie unchanged. The handler throws GraphQL and network errors from the mutation.
98
+ */
69
99
  post: CartPostHandler;
70
100
  };
71
101
  /**
72
- * {@link CartServerHandlers} variant that additionally syncs the cart's buyer
73
- * identity with a customer session — the handler contexts require a session
74
- * manager and request context.
102
+ * The cart route handlers that `createCartServerHandlers` returns when you pass `customerSession`. The handlers connect carts to the logged-in customer.
75
103
  *
76
- * Created by passing `customerSession` to {@link createCartServerHandlers}.
104
+ * Pass `sessionManager` and `requestContext` in each handler's context. A handler throws when it reads the customer session and either value is missing.
77
105
  */
78
106
  type CartServerHandlersWithCustomerSession<TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart, TCart extends CartData = CartDataFromQuery<TCartQuery>> = {
79
- readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;
80
- readonly [cartBuyerIdentitySync]: CartBuyerIdentitySync;
107
+ /** The cart query document that the handlers run. */readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;
108
+ readonly [cartBuyerIdentitySync]: CartBuyerIdentitySync; /** Returns the cart like the GET handler in `CartServerHandlers`. For a logged-in customer, the handler adds `logged_in=true` to the checkout URL. */
81
109
  get: CartGetHandler<TCart, CartGetHandlerContext & CartCustomerSessionReadContext>;
110
+ /**
111
+ * Runs cart changes like the POST handler in `CartServerHandlers`. When an add creates a cart for a logged-in customer, the handler attaches the customer to the new cart. When the handler refreshes the customer's access token and the mutation then fails, the handler returns a `cart_mutation_failed` error with status `500`.
112
+ */
82
113
  post: CartPostHandler<CartPostHandlerContext & CartCustomerSessionWriteContext>;
83
114
  };
84
115
  type AsyncHandlerResult<THandler> = THandler extends ((...args: infer _Args) => Promise<infer TResult>) ? TResult : never;
@@ -91,10 +122,9 @@ type CartDataFromHandlerResult<TResult> = [TResult] extends [never] ? never : TR
91
122
  };
92
123
  } ? NonNullable<TCart> extends CartData ? NonNullable<TCart> : CartData : CartData;
93
124
  /**
94
- * Infers the {@link CartData} shape from a {@link CartServerHandlers} instance.
125
+ * Gets the cart data type from the type of your cart server handlers, including the fields from your custom cart fragment.
95
126
  *
96
- * Use this to type framework components and hooks so they match the server
97
- * handler's custom cart query without repeating the generic parameter.
127
+ * Pass `typeof cartHandlers` to type cart data in your own components and functions.
98
128
  *
99
129
  * @example
100
130
  * ```ts
@@ -102,31 +132,37 @@ type CartDataFromHandlerResult<TResult> = [TResult] extends [never] ? never : TR
102
132
  * ```
103
133
  */
104
134
  type CartDataFromHandlers<THandlers> = CartDataFromHandlerResult<CartGetHandlerResult<THandlers>>;
105
- /** Options for {@link createCartServerHandlers}. */
106
- type CreateCartServerHandlersOptions<TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString> = {
135
+ /** The cart fragment option for cart server handlers. */
136
+ interface CartServerHandlersBaseOptions<TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString> {
107
137
  /**
108
- * Custom cart GraphQL fragment spread into every query and mutation response.
109
- * The fragment must be named `CartFragment` and target `Cart`.
138
+ * A cart fragment that adds fields to the cart in every cart query and mutation response.
139
+ * Name the fragment `CartFragment` on the `Cart` type.
140
+ *
141
+ * `createCartServerHandlers` throws for any other fragment name or type.
110
142
  */
111
143
  readonly fragment?: TCartFragment;
112
- } & ({
144
+ }
145
+ /** Options for cart server handlers that attach the logged-in customer to new carts. */
146
+ interface CartServerHandlersOptionsWithCustomerSession<TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString> extends CartServerHandlersBaseOptions<TCartFragment> {
147
+ /** The customer session from `createCustomerSession`. Pass the session to attach the logged-in customer to new carts. */
113
148
  readonly customerSession: CartCustomerSession;
114
- } | {
149
+ }
150
+ /** Options for cart server handlers without a customer session. */
151
+ interface CartServerHandlersOptionsWithoutCustomerSession<TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString> extends CartServerHandlersBaseOptions<TCartFragment> {
152
+ /** Leave the option out to create carts without a customer. */
115
153
  readonly customerSession?: undefined;
116
- });
154
+ }
155
+ /** Options for creating cart server handlers. */
156
+ type CreateCartServerHandlersOptions<TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString> = CartServerHandlersOptionsWithCustomerSession<TCartFragment> | CartServerHandlersOptionsWithoutCustomerSession<TCartFragment>;
117
157
  type CartServerHandlersForOptions<TOptions> = TOptions extends {
118
158
  readonly customerSession: CartCustomerSession;
119
159
  } ? CartServerHandlersWithCustomerSession<CartQueriesForOptions<TOptions>["cart"], CartDataForOptions<TOptions>> : CartServerHandlers<CartQueriesForOptions<TOptions>["cart"], CartDataForOptions<TOptions>>;
120
160
  /**
121
- * Creates GET and POST handlers for the `/api/cart` route.
161
+ * Creates the handlers for the `/api/cart` route, which loads and changes the customer's cart.
122
162
  *
123
- * The handlers parse incoming requests (JSON or FormData), resolve the cart
124
- * identity from a cookie, execute the matching Storefront API mutation, and
125
- * return either JSON (programmatic clients) or a 303 redirect (form submissions).
163
+ * The handlers read the cart ID from the `cart` cookie and set the cookie when they create a cart. A JSON request gets a JSON response, and a form submission gets a `303` redirect to the referring page.
126
164
  *
127
- * Pass `customerSession` to additionally sync the cart's buyer identity with
128
- * the logged-in customer — the returned handlers then require a session manager
129
- * in their context.
165
+ * Pass `customerSession` to connect carts to the logged-in customer. The handlers then need `sessionManager` and `requestContext` in their context.
130
166
  *
131
167
  * @example
132
168
  * ```ts
@@ -143,6 +179,7 @@ type CartServerHandlersForOptions<TOptions> = TOptions extends {
143
179
  * customerSession,
144
180
  * });
145
181
  * ```
182
+ * @publicDocs
146
183
  */
147
184
  declare function createCartServerHandlers(): CartServerHandlers<typeof cartQueries.cart>;
148
185
  declare function createCartServerHandlers<const TOptions extends CreateCartServerHandlersOptions>(options: TOptions): CartServerHandlersForOptions<TOptions>;
@@ -18,6 +18,10 @@ const CART_POST_METHOD = "POST";
18
18
  const CART_MUTATION_FAILED_STATUS = 500;
19
19
  const CART_MUTATION_FAILED_MESSAGE = "Cart mutation failed. Please try again.";
20
20
  const cartServerHandlersCartQuery = Symbol("hydrogen.cartQuery");
21
+ /**
22
+ * @param options A custom cart fragment and the customer session.
23
+ * @returns The GET and POST handlers to register with `handleShopifyRoutes`.
24
+ */
21
25
  function createCartServerHandlers(options) {
22
26
  const queries = options?.fragment ? makeCartQueries({ fragment: options.fragment }) : cartQueries;
23
27
  const runtimeQueries = queries;
@@ -1 +1 @@
1
- {"version":3,"file":"server-handlers.mjs","names":["_exhaustive"],"sources":["../../../src/core/cart/server-handlers.ts"],"sourcesContent":["import type { GraphQLFormattedError, StorefrontClient } from \"../../client\";\nimport type {\n CustomerSession,\n ReadonlyCustomerSessionManager,\n WritableCustomerSessionManager,\n} from \"../../customer-account/session\";\nimport { getCustomerSessionRefreshResult } from \"../../customer-account/session\";\nimport type { AnyStorefrontQueryString } from \"../../graphql\";\nimport { applyPrivateResponseCacheHeaders } from \"../headers\";\nimport { getLogger } from \"../logging\";\nimport type { ShopifyRequestContext } from \"../request-context\";\nimport { createProxyResponseHeaders } from \"../request-routing/interceptors/proxy\";\nimport type {\n CallableRouteHandler,\n ShopifyRouteError,\n ShopifyRouteErrorResult,\n ShopifyRouteJsonResult,\n ShopifyRouteRedirectResult,\n} from \"../request-routing/registered-routes\";\nimport { createCallableRouteHandler } from \"../request-routing/registered-routes\";\nimport { getSameOriginPath } from \"../url\";\nimport { parseCartRequest } from \"./actions\";\nimport type { CartAction, CartLineAddInput } from \"./actions\";\nimport {\n cartBuyerIdentitySync,\n type CartBuyerIdentitySync,\n type CartBuyerIdentitySyncContext,\n} from \"./buyer-identity-sync\";\nimport { getCartIdFromCookie, createCartCookie, createExpiredCartCookie } from \"./cookie\";\nimport { getCart, getCartId, type CartDataFromQuery } from \"./get-cart\";\nimport {\n cartBuyerIdentityUpdateMutation,\n cartQueries,\n makeCartQueries,\n type CartDataForOptions,\n type CartQueriesForOptions,\n type CreateCartQueriesOptions,\n} from \"./queries\";\nimport type { CartData } from \"./state\";\nconst log = getLogger(\"cart-api\");\n\nconst CART_API_PATH = \"/api/cart\" as const;\nconst CART_GET_METHOD = \"GET\" as const;\nconst CART_POST_METHOD = \"POST\" as const;\nconst CART_MUTATION_FAILED_STATUS = 500;\nconst CART_MUTATION_FAILED_MESSAGE = \"Cart mutation failed. Please try again.\";\nconst cartServerHandlersCartQuery: unique symbol = Symbol(\"hydrogen.cartQuery\");\n\n/** Response shape from the cart GET handler — the fetched cart plus any GraphQL errors. */\nexport type CartGetData<TCart = CartData> = {\n cart: TCart | null;\n errors?: Array<{ message: string }>;\n};\n\n/** Full route result from the cart GET handler — JSON with {@link CartGetData} payload and response headers. */\nexport type CartGetResult<TCart = CartData> = ShopifyRouteJsonResult<CartGetData<TCart>>;\n\n/** Machine-readable error codes returned by the cart POST handler. */\nexport type CartErrorCode = \"invalid_cart_request\" | \"missing_cart\" | \"cart_mutation_failed\";\n\n/** A cart route error carrying a {@link CartErrorCode} for programmatic handling. */\nexport type CartError = ShopifyRouteError & {\n code: CartErrorCode;\n};\n\n/**\n * Result from the cart POST handler — one of:\n * - JSON with the mutation payload (programmatic clients)\n * - 303 redirect back to the referrer (HTML form submissions)\n * - An error with a {@link CartErrorCode}\n */\nexport type CartPostResult =\n | ShopifyRouteJsonResult<Record<string, unknown>>\n | ShopifyRouteRedirectResult\n | ShopifyRouteErrorResult<CartError>;\n\ntype CartCustomerAccessTokenResult = {\n accessToken?: string;\n commitSession: boolean;\n};\n\ntype ParsedCartRequestResult =\n | { type: \"action\"; action: CartAction; bodyCartId: string | null }\n | { type: \"response\"; response: CartPostResult };\n\ntype CartGetHandlerContext = {\n storefrontClient: StorefrontClient;\n request?: Request;\n};\n\ntype CartPostHandlerContext = {\n request: Request;\n storefrontClient: StorefrontClient;\n};\n\ntype CartCustomerSessionReadContext = {\n sessionManager: ReadonlyCustomerSessionManager;\n requestContext: ShopifyRequestContext;\n};\n\ntype CartCustomerSessionWriteContext = {\n sessionManager: WritableCustomerSessionManager;\n requestContext: ShopifyRequestContext;\n};\n\ntype CartCustomerSession = CustomerSession;\n\n/** GET handler for the `/api/cart` route — fetches the current cart from the Storefront API. */\nexport type CartGetHandler<\n TCart = CartData,\n TContext extends CartGetHandlerContext = CartGetHandlerContext,\n> = CallableRouteHandler<\n TContext,\n CartGetResult<TCart>,\n typeof CART_API_PATH,\n typeof CART_GET_METHOD\n>;\n\n/** POST handler for the `/api/cart` route — processes cart mutations from JSON or FormData bodies. */\nexport type CartPostHandler<TContext extends CartPostHandlerContext = CartPostHandlerContext> =\n CallableRouteHandler<TContext, CartPostResult, typeof CART_API_PATH, typeof CART_POST_METHOD>;\n\n/**\n * GET and POST handlers for the `/api/cart` route.\n *\n * Created by {@link createCartServerHandlers}. Register these with your\n * framework's router so the client cart store can communicate with the\n * Storefront API.\n */\nexport type CartServerHandlers<\n TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart,\n TCart extends CartData = CartDataFromQuery<TCartQuery>,\n> = {\n readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;\n get: CartGetHandler<TCart>;\n post: CartPostHandler;\n};\n\n/**\n * {@link CartServerHandlers} variant that additionally syncs the cart's buyer\n * identity with a customer session — the handler contexts require a session\n * manager and request context.\n *\n * Created by passing `customerSession` to {@link createCartServerHandlers}.\n */\nexport type CartServerHandlersWithCustomerSession<\n TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart,\n TCart extends CartData = CartDataFromQuery<TCartQuery>,\n> = {\n readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;\n readonly [cartBuyerIdentitySync]: CartBuyerIdentitySync;\n get: CartGetHandler<TCart, CartGetHandlerContext & CartCustomerSessionReadContext>;\n post: CartPostHandler<CartPostHandlerContext & CartCustomerSessionWriteContext>;\n};\n\ntype AsyncHandlerResult<THandler> = THandler extends (\n ...args: infer _Args\n) => Promise<infer TResult>\n ? TResult\n : never;\n\ntype CartGetHandlerResult<THandlers> = THandlers extends { get: infer THandler }\n ? AsyncHandlerResult<THandler>\n : never;\n\ntype CartDataFromHandlerResult<TResult> = [TResult] extends [never]\n ? never\n : TResult extends { data: { cart: infer TCart } }\n ? NonNullable<TCart> extends CartData\n ? NonNullable<TCart>\n : CartData\n : CartData;\n\n/**\n * Infers the {@link CartData} shape from a {@link CartServerHandlers} instance.\n *\n * Use this to type framework components and hooks so they match the server\n * handler's custom cart query without repeating the generic parameter.\n *\n * @example\n * ```ts\n * type MyCartData = CartDataFromHandlers<typeof cartHandlers>;\n * ```\n */\nexport type CartDataFromHandlers<THandlers> = CartDataFromHandlerResult<\n CartGetHandlerResult<THandlers>\n>;\n\n/** Options for {@link createCartServerHandlers}. */\nexport type CreateCartServerHandlersOptions<\n TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString,\n> = {\n /**\n * Custom cart GraphQL fragment spread into every query and mutation response.\n * The fragment must be named `CartFragment` and target `Cart`.\n */\n readonly fragment?: TCartFragment;\n} & ({ readonly customerSession: CartCustomerSession } | { readonly customerSession?: undefined });\n\ntype CartServerHandlersForOptions<TOptions> = TOptions extends {\n readonly customerSession: CartCustomerSession;\n}\n ? CartServerHandlersWithCustomerSession<\n CartQueriesForOptions<TOptions>[\"cart\"],\n CartDataForOptions<TOptions>\n >\n : CartServerHandlers<CartQueriesForOptions<TOptions>[\"cart\"], CartDataForOptions<TOptions>>;\n\n/**\n * Creates GET and POST handlers for the `/api/cart` route.\n *\n * The handlers parse incoming requests (JSON or FormData), resolve the cart\n * identity from a cookie, execute the matching Storefront API mutation, and\n * return either JSON (programmatic clients) or a 303 redirect (form submissions).\n *\n * Pass `customerSession` to additionally sync the cart's buyer identity with\n * the logged-in customer — the returned handlers then require a session manager\n * in their context.\n *\n * @example\n * ```ts\n * // Basic setup\n * const cartHandlers = createCartServerHandlers();\n *\n * // With a custom cart fragment\n * const cartHandlers = createCartServerHandlers({\n * fragment: CART_FRAGMENT,\n * });\n *\n * // With customer session for buyer identity sync\n * const cartHandlers = createCartServerHandlers({\n * customerSession,\n * });\n * ```\n */\nexport function createCartServerHandlers(): CartServerHandlers<typeof cartQueries.cart>;\nexport function createCartServerHandlers<const TOptions extends CreateCartServerHandlersOptions>(\n options: TOptions,\n): CartServerHandlersForOptions<TOptions>;\nexport function createCartServerHandlers(\n options?: CreateCartServerHandlersOptions,\n): CartServerHandlers | CartServerHandlersWithCustomerSession {\n const queries = options?.fragment\n ? makeCartQueries({ fragment: options.fragment } as CreateCartQueriesOptions)\n : cartQueries;\n const runtimeQueries = queries as RuntimeCartQueries;\n const customerSession = options?.customerSession;\n\n const handlers = {\n get: createCallableRouteHandler(\n CART_API_PATH,\n CART_GET_METHOD,\n (context: CartGetHandlerContext & Partial<CartCustomerSessionReadContext>) =>\n handleGet(context, runtimeQueries, customerSession),\n ),\n post: createCallableRouteHandler(\n CART_API_PATH,\n CART_POST_METHOD,\n (context: CartPostHandlerContext & Partial<CartCustomerSessionWriteContext>) =>\n handlePost(context, runtimeQueries, customerSession),\n ),\n };\n\n Object.defineProperty(handlers, cartServerHandlersCartQuery, { value: queries.cart });\n if (customerSession) {\n // Symbol-keyed and non-enumerable so the capability never registers as a\n // route in handleShopifyRoutes and stays uncallable outside Hydrogen wiring.\n Object.defineProperty(handlers, cartBuyerIdentitySync, {\n value: createCartBuyerIdentitySync(),\n });\n }\n return handlers as CartServerHandlers | CartServerHandlersWithCustomerSession;\n}\n\nfunction createCartBuyerIdentitySync(): CartBuyerIdentitySync {\n return {\n updateBuyerIdentity: updateCartBuyerIdentity,\n expiredCartCookie: createExpiredCartCookie(),\n };\n}\n\nasync function updateCartBuyerIdentity(\n context: CartBuyerIdentitySyncContext,\n customerAccessToken: string | null,\n): Promise<void> {\n const cartId = getCartIdFromCookie(context.request);\n if (!cartId) return;\n\n const result = await context.storefrontClient.graphql(cartBuyerIdentityUpdateMutation, {\n variables: { cartId, buyerIdentity: { customerAccessToken } },\n });\n const { userErrors } = assertMutationData(result, \"cartBuyerIdentityUpdate\");\n if (userErrors.length > 0) {\n throw new Error(userErrors.map(({ message }) => message).join(\"\\n\"));\n }\n}\n\ntype RuntimeCartQueries = typeof cartQueries;\n\nasync function handleGet(\n context: CartGetHandlerContext & Partial<CartCustomerSessionReadContext>,\n queries: RuntimeCartQueries,\n customerSession?: CartCustomerSession,\n): Promise<CartGetResult> {\n const { request, storefrontClient } = context;\n const cartIdSource = request ?? storefrontClient.requestContext;\n const result = await getCart(getCartId(cartIdSource), storefrontClient, queries.cart);\n logCartErrors(result.errors);\n const cart = await addLoggedInCheckoutParam(result.cart, context, customerSession);\n const data = { cart, ...(result.errors && { errors: result.errors }) };\n const headers = createProxyResponseHeaders(result.headers);\n applyPrivateResponseCacheHeaders(headers);\n\n return {\n type: \"json\",\n data,\n headers,\n };\n}\n\nfunction logCartErrors(errors: CartGetData[\"errors\"]): void {\n if (!errors?.length) return;\n log.error(errors.map(({ message }) => message).join(\"\\n\"));\n}\n\nasync function handlePost(\n context: CartPostHandlerContext & Partial<CartCustomerSessionWriteContext>,\n queries: RuntimeCartQueries,\n customerSession?: CartCustomerSession,\n): Promise<CartPostResult> {\n const { request, storefrontClient } = context;\n const isFormRequest = !request.headers.get(\"content-type\")?.includes(\"application/json\");\n const redirectTarget = safeRedirectTarget(request);\n\n const parsedCartRequest = await parseCartAction(request, isFormRequest, redirectTarget);\n if (parsedCartRequest.type === \"response\") return parsedCartRequest.response;\n\n const cookieCartId = getCartIdFromCookie(request);\n const cartId = parsedCartRequest.bodyCartId ?? cookieCartId;\n const missingCartResponse = getMissingCartResponse(\n parsedCartRequest.action,\n cartId,\n isFormRequest,\n redirectTarget,\n );\n if (missingCartResponse) return missingCartResponse;\n\n const { action } = parsedCartRequest;\n const customerAccess = await getCartCreateCustomerAccess(\n parsedCartRequest.action,\n cartId,\n context,\n customerSession,\n );\n const customerSessionHeaders = customerAccess.commitSession\n ? await getCustomerSessionHeaders(context)\n : undefined;\n const result = await executeCartMutation(\n action,\n cartId,\n storefrontClient,\n queries,\n customerAccess.accessToken,\n customerSessionHeaders,\n );\n if (result.type !== \"mutation\") return result.response;\n\n const headers = createProxyResponseHeaders(result.headers);\n appendHeaders(headers, customerSessionHeaders);\n\n // Only persist carts the browser already owns, including newly-created carts.\n if (cartId === cookieCartId && result.cartId !== null && result.cartId !== cookieCartId) {\n headers.append(\"set-cookie\", createCartCookie(result.cartId));\n }\n\n if (isFormRequest) return redirectResult(redirectTarget, headers);\n return jsonResult(result.data, headers);\n}\n\nasync function parseCartAction(\n request: Request,\n isFormRequest: boolean,\n redirectTarget: string,\n): Promise<ParsedCartRequestResult> {\n try {\n const { action, cartId: bodyCartId } = await parseCartRequest(request);\n return { type: \"action\", action, bodyCartId };\n } catch (error) {\n if (isFormRequest) return { type: \"response\", response: redirectResult(redirectTarget) };\n return {\n type: \"response\",\n response: errorResult(\"invalid_cart_request\", getErrorMessage(error, \"Bad Request\")),\n };\n }\n}\n\nfunction getMissingCartResponse(\n action: CartAction,\n cartId: string | null,\n isFormRequest: boolean,\n redirectTarget: string,\n): CartPostResult | undefined {\n if (action.intent === \"add\" || cartId) return undefined;\n if (isFormRequest) return redirectResult(redirectTarget);\n return errorResult(\"missing_cart\", \"No cart exists. Add an item first.\");\n}\n\nasync function executeCartMutation(\n action: CartAction,\n cartId: string | null,\n storefrontClient: StorefrontClient,\n queries: RuntimeCartQueries,\n customerAccessToken: string | undefined,\n customerSessionHeaders: Headers | undefined,\n): Promise<\n ({ type: \"mutation\" } & MutationResult) | { type: \"response\"; response: CartPostResult }\n> {\n try {\n return {\n type: \"mutation\",\n ...(await executeMutation(action, cartId, storefrontClient, queries, customerAccessToken)),\n };\n } catch (error) {\n if (!customerSessionHeaders) throw error;\n log.error(\"cart mutation failed\", { error });\n return {\n type: \"response\",\n response: errorResult(\n \"cart_mutation_failed\",\n CART_MUTATION_FAILED_MESSAGE,\n customerSessionHeaders,\n CART_MUTATION_FAILED_STATUS,\n ),\n };\n }\n}\n\nasync function getCustomerSessionHeaders(\n context: Partial<CartCustomerSessionWriteContext>,\n): Promise<Headers | undefined> {\n assertCustomerSessionWriteContext(context);\n const sessionHeaders = await context.sessionManager.commit?.();\n if (!sessionHeaders) return undefined;\n return new Headers(sessionHeaders);\n}\n\nfunction appendHeaders(headers: Headers, headersToAppend: Headers | undefined) {\n if (!headersToAppend) return;\n for (const [key, value] of headersToAppend) {\n if (key !== \"set-cookie\") headers.append(key, value);\n }\n for (const setCookie of headersToAppend.getSetCookie()) {\n headers.append(\"set-cookie\", setCookie);\n }\n}\n\nfunction safeRedirectTarget(request: Request): string {\n return getSameOriginPath(request.headers.get(\"referer\"), new URL(request.url).origin) ?? \"/\";\n}\n\ntype MutationResult = {\n data: Record<string, unknown>;\n cartId: string | null;\n headers: Headers;\n};\n\ntype GraphQLResult<D> = {\n data: D | null;\n errors?: GraphQLFormattedError[];\n headers: Headers;\n};\n\nfunction assertGraphQLData<D>(result: GraphQLResult<D>): NonNullable<D> {\n if (result.errors || !result.data) {\n const message = result.errors?.[0]?.message ?? \"GraphQL error\";\n throw new Error(message);\n }\n return result.data as NonNullable<D>;\n}\n\nfunction assertMutationData<D, K extends keyof NonNullable<D>>(\n result: GraphQLResult<D>,\n key: K,\n): NonNullable<NonNullable<D>[K]> {\n const data = assertGraphQLData(result);\n const payload = data[key];\n if (payload == null) {\n throw new Error(`Missing ${String(key)} in mutation response`);\n }\n return payload as NonNullable<NonNullable<D>[K]>;\n}\n\nfunction createMutationResult(\n cart: unknown,\n userErrors: unknown,\n warnings: unknown,\n headers: Headers,\n): MutationResult {\n const storefrontCart = (cart ?? null) as Record<string, unknown> | null;\n\n return {\n data: { cart: storefrontCart, userErrors, warnings },\n cartId: typeof storefrontCart?.id === \"string\" ? storefrontCart.id : null,\n headers,\n };\n}\n\ntype CartMutationClient = Pick<StorefrontClient, \"graphql\">;\n\nasync function executeMutation(\n action: CartAction,\n cartId: string | null,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n customerAccessToken?: string,\n): Promise<MutationResult> {\n if (action.intent === \"add\") {\n return executeAdd(action.lines, cartId, storefront, queries, customerAccessToken);\n }\n\n if (!cartId) {\n throw new Error(\"cartId is required for non-add mutations\");\n }\n\n switch (action.intent) {\n case \"update\": {\n const result = await storefront.graphql(queries.cartLinesUpdate, {\n variables: { cartId, lines: action.lines },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"remove\": {\n const result = await storefront.graphql(queries.cartLinesRemove, {\n variables: { cartId, lineIds: action.lineIds },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesRemove\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"discount-update\": {\n const result = await storefront.graphql(queries.cartDiscountCodesUpdate, {\n variables: { cartId, discountCodes: action.discountCodes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartDiscountCodesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"discount-apply\":\n return executeDiscountModify(cartId, \"apply\", action.code, storefront, queries);\n case \"discount-remove\":\n return executeDiscountModify(cartId, \"remove\", action.code, storefront, queries);\n case \"note-update\": {\n const result = await storefront.graphql(queries.cartNoteUpdate, {\n variables: { cartId, note: action.note },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartNoteUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"attributes-update\": {\n const result = await storefront.graphql(queries.cartAttributesUpdate, {\n variables: { cartId, attributes: action.attributes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartAttributesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n default: {\n const _exhaustive: never = action;\n throw new Error(`Unhandled cart action intent: ${(_exhaustive as CartAction).intent}`);\n }\n }\n}\n\nasync function executeAdd(\n lines: CartLineAddInput[],\n cartId: string | null,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n customerAccessToken?: string,\n): Promise<MutationResult> {\n if (cartId) {\n const result = await storefront.graphql(queries.cartLinesAdd, {\n variables: { cartId, lines },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesAdd\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n\n const result = await storefront.graphql(queries.cartCreate, {\n variables: {\n input: {\n lines,\n ...(customerAccessToken && { buyerIdentity: { customerAccessToken } }),\n },\n },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartCreate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n}\n\nasync function getCartCreateCustomerAccess(\n action: CartAction,\n cartId: string | null,\n context: Partial<CartCustomerSessionWriteContext>,\n customerSession?: CartCustomerSession,\n): Promise<CartCustomerAccessTokenResult> {\n if (action.intent !== \"add\" || cartId || !customerSession) {\n return { commitSession: false };\n }\n\n assertCustomerSessionWriteContext(context);\n const accessToken = await customerSession.getAccessToken(\n context.sessionManager,\n context.requestContext,\n );\n if (accessToken) return { accessToken, commitSession: false };\n\n const isLoggedIn = await customerSession.isLoggedIn(\n context.sessionManager,\n context.requestContext,\n );\n if (!isLoggedIn) return { commitSession: false };\n\n const refreshResult = await getCustomerSessionRefreshResult(\n customerSession,\n context.sessionManager,\n context.requestContext,\n );\n if (refreshResult) {\n return {\n accessToken: refreshResult.accessToken,\n commitSession: refreshResult.status !== \"transient\",\n };\n }\n\n const refreshedAccessToken = await customerSession.getOrRefreshAccessToken(\n context.sessionManager,\n context.requestContext,\n );\n return {\n accessToken: refreshedAccessToken,\n commitSession: true,\n };\n}\n\nasync function addLoggedInCheckoutParam<TCart extends CartData>(\n cart: TCart | null,\n context: Partial<CartCustomerSessionReadContext>,\n customerSession?: CartCustomerSession,\n): Promise<TCart | null> {\n if (!cart || !customerSession) return cart;\n assertCustomerSessionReadContext(context);\n if (!(await customerSession.isLoggedIn(context.sessionManager, context.requestContext)))\n return cart;\n if (!cart.checkoutUrl) return cart;\n\n const checkoutUrl = new URL(cart.checkoutUrl);\n checkoutUrl.searchParams.set(\"logged_in\", \"true\");\n return { ...cart, checkoutUrl: checkoutUrl.toString() };\n}\n\nfunction assertCustomerSessionContext(\n context: Partial<CartCustomerSessionReadContext | CartCustomerSessionWriteContext>,\n): void {\n if (context.sessionManager && context.requestContext) return;\n throw new Error(\n \"Cart handlers configured with customerSession require sessionManager and requestContext.\",\n );\n}\n\nfunction assertCustomerSessionReadContext(\n context: Partial<CartCustomerSessionReadContext>,\n): asserts context is CartCustomerSessionReadContext {\n assertCustomerSessionContext(context);\n}\n\nfunction assertCustomerSessionWriteContext(\n context: Partial<CartCustomerSessionWriteContext>,\n): asserts context is CartCustomerSessionWriteContext {\n assertCustomerSessionContext(context);\n}\n\nasync function executeDiscountModify(\n cartId: string,\n mode: \"apply\" | \"remove\",\n code: string,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n): Promise<MutationResult> {\n // Read-then-write: SFAPI has no atomic discount modify endpoint, so concurrent\n // requests can overwrite each other's discount codes.\n const cartResult = await storefront.graphql(queries.cart, {\n variables: { id: cartId },\n });\n const cartData = assertGraphQLData(cartResult);\n\n const currentCodes: string[] = (cartData.cart?.discountCodes ?? []).map((dc) => dc.code);\n\n const updatedCodes =\n mode === \"apply\" ? [...currentCodes, code] : currentCodes.filter((c) => c !== code);\n\n const result = await storefront.graphql(queries.cartDiscountCodesUpdate, {\n variables: { cartId, discountCodes: updatedCodes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartDiscountCodesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n}\n\nfunction jsonResult<TData>(data: TData, headers: HeadersInit = {}): ShopifyRouteJsonResult<TData> {\n return { type: \"json\", data, headers };\n}\n\nfunction redirectResult(location: string, headers: HeadersInit = {}): ShopifyRouteRedirectResult {\n return { type: \"redirect\", location, headers };\n}\n\nfunction errorResult(\n code: CartErrorCode,\n message: string,\n headers?: HeadersInit,\n status?: number,\n): ShopifyRouteErrorResult<CartError> {\n return {\n type: \"error\",\n error: { code, message },\n ...(headers && { headers }),\n ...(status !== undefined && { status }),\n };\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error) return error.message;\n return fallback;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"server-handlers.mjs","names":["_exhaustive"],"sources":["../../../src/core/cart/server-handlers.ts"],"sourcesContent":["import type { GraphQLFormattedError, StorefrontClient } from \"../../client\";\nimport type {\n CustomerSession,\n ReadonlyCustomerSessionManager,\n WritableCustomerSessionManager,\n} from \"../../customer-account/session\";\nimport { getCustomerSessionRefreshResult } from \"../../customer-account/session\";\nimport type { AnyStorefrontQueryString } from \"../../graphql\";\nimport { applyPrivateResponseCacheHeaders } from \"../headers\";\nimport { getLogger } from \"../logging\";\nimport type { ShopifyRequestContext } from \"../request-context\";\nimport { createProxyResponseHeaders } from \"../request-routing/interceptors/proxy\";\nimport type {\n CallableRouteHandler,\n ShopifyRouteError,\n ShopifyRouteErrorResult,\n ShopifyRouteJsonResult,\n ShopifyRouteRedirectResult,\n} from \"../request-routing/registered-routes\";\nimport { createCallableRouteHandler } from \"../request-routing/registered-routes\";\nimport { getSameOriginPath } from \"../url\";\nimport { parseCartRequest } from \"./actions\";\nimport type { CartAction, CartLineAddInput } from \"./actions\";\nimport {\n cartBuyerIdentitySync,\n type CartBuyerIdentitySync,\n type CartBuyerIdentitySyncContext,\n} from \"./buyer-identity-sync\";\nimport { getCartIdFromCookie, createCartCookie, createExpiredCartCookie } from \"./cookie\";\nimport { getCart, getCartId, type CartDataFromQuery } from \"./get-cart\";\nimport {\n cartBuyerIdentityUpdateMutation,\n cartQueries,\n makeCartQueries,\n type CartDataForOptions,\n type CartQueriesForOptions,\n type CreateCartQueriesOptions,\n} from \"./queries\";\nimport type { CartData } from \"./state\";\nconst log = getLogger(\"cart-api\");\n\nconst CART_API_PATH = \"/api/cart\" as const;\nconst CART_GET_METHOD = \"GET\" as const;\nconst CART_POST_METHOD = \"POST\" as const;\nconst CART_MUTATION_FAILED_STATUS = 500;\nconst CART_MUTATION_FAILED_MESSAGE = \"Cart mutation failed. Please try again.\";\nconst cartServerHandlersCartQuery: unique symbol = Symbol(\"hydrogen.cartQuery\");\n\n/**\n * The response body that the cart GET handler returns.\n *\n * @publicDocs\n */\nexport type CartGetData<TCart = CartData> = {\n /** The cart, or `null` when the request has no cart ID, the cart doesn't exist, or the cart query returns GraphQL errors. */\n cart: TCart | null;\n /** GraphQL errors from the cart query. The handler also logs the errors on the server. */\n errors?: Array<{ message: string }>;\n};\n\n/**\n * The JSON result that the cart GET handler returns. The handler sets private cache headers that keep CDNs and shared caches from storing the cart.\n *\n * @publicDocs\n */\nexport type CartGetResult<TCart = CartData> = ShopifyRouteJsonResult<CartGetData<TCart>>;\n\n/**\n * Error codes that the cart POST handler returns. The handler returns `invalid_cart_request` when it can't parse a JSON request, and `missing_cart` when a JSON request changes the cart but has no cart ID. With `customerSession`, the handler returns `cart_mutation_failed` when a mutation fails after the handler refreshes the customer's access token.\n */\nexport type CartErrorCode = \"invalid_cart_request\" | \"missing_cart\" | \"cart_mutation_failed\";\n\n/**\n * An error that the cart POST handler returns, with a code that identifies the failure.\n *\n * @publicDocs\n */\nexport interface CartError extends ShopifyRouteError {\n /** The code that identifies the failure. */\n code: CartErrorCode;\n}\n\n/**\n * The route result that the cart POST handler returns. Check `type` to tell the results apart:\n * - `json` answers a JSON request. The result's `data` holds the mutation's `cart`, `userErrors`, and `warnings`.\n * - `redirect` answers a form submission with a `303` redirect to the referring page.\n * - `error` holds a cart error with a code that identifies the failure.\n *\n * @publicDocs\n */\nexport type CartPostResult =\n | ShopifyRouteJsonResult<Record<string, unknown>>\n | ShopifyRouteRedirectResult\n | ShopifyRouteErrorResult<CartError>;\n\ntype CartCustomerAccessTokenResult = {\n accessToken?: string;\n commitSession: boolean;\n};\n\ntype ParsedCartRequestResult =\n | { type: \"action\"; action: CartAction; bodyCartId: string | null }\n | { type: \"response\"; response: CartPostResult };\n\n/** The context that you pass to the cart GET handler. */\ntype CartGetHandlerContext = {\n /** The Storefront API client that runs the cart query. */\n storefrontClient: StorefrontClient;\n /** The incoming request. Omit the request to read the cart ID from the Storefront API client's request context. */\n request?: Request;\n};\n\n/** The context that you pass to the cart POST handler. */\ntype CartPostHandlerContext = {\n /** The cart request, with a JSON, URL-encoded form, or multipart form body. */\n request: Request;\n /** The Storefront API client that runs the cart mutation. */\n storefrontClient: StorefrontClient;\n};\n\n/** The extra context that the GET handler needs when you create the handlers with `customerSession`. */\ntype CartCustomerSessionReadContext = {\n /** The session storage that holds the customer's tokens. */\n sessionManager: ReadonlyCustomerSessionManager;\n /** The current request's context, for checking the customer's login state. */\n requestContext: ShopifyRequestContext;\n};\n\n/** The extra context that the POST handler needs when you create the handlers with `customerSession`. */\ntype CartCustomerSessionWriteContext = {\n /** The session storage that holds the customer's tokens. After a token refresh, the handler commits the session and adds its `Set-Cookie` headers to the response. */\n sessionManager: WritableCustomerSessionManager;\n /** The current request's context, for reading or refreshing the customer's access token. */\n requestContext: ShopifyRequestContext;\n};\n\n/** The customer session from `createCustomerSession`. The cart handlers read the customer's login state and access token from the session. */\ntype CartCustomerSession = CustomerSession;\n\n/** Handles GET requests to `/api/cart` and returns the current cart. */\nexport type CartGetHandler<\n TCart = CartData,\n TContext extends CartGetHandlerContext = CartGetHandlerContext,\n> = CallableRouteHandler<\n TContext,\n CartGetResult<TCart>,\n typeof CART_API_PATH,\n typeof CART_GET_METHOD\n>;\n\n/** Handles POST requests to `/api/cart` and runs the cart change that the request body describes. */\nexport type CartPostHandler<TContext extends CartPostHandlerContext = CartPostHandlerContext> =\n CallableRouteHandler<TContext, CartPostResult, typeof CART_API_PATH, typeof CART_POST_METHOD>;\n\n/**\n * The cart route handlers that `createCartServerHandlers` returns.\n *\n * Register the handlers with `handleShopifyRoutes` to serve the `/api/cart` route that the cart store calls.\n */\nexport type CartServerHandlers<\n TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart,\n TCart extends CartData = CartDataFromQuery<TCartQuery>,\n> = {\n /** The cart query document that the handlers run. */\n readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;\n /**\n * Returns the current cart. The handler reads the cart ID from the request's `cartId` search parameter or `cart` cookie. Without a request, the handler reads the cart ID from the Storefront API client's request context.\n *\n * GraphQL errors return a `null` cart with the errors in the response body. The handler throws when the Storefront API request fails.\n */\n get: CartGetHandler<TCart>;\n /**\n * Runs the cart change that the request describes and returns the updated cart. An add without a cart creates a cart and sets the `cart` cookie. Other changes without a cart return a `missing_cart` error for a JSON request and a redirect for a form submission.\n *\n * When a JSON body names a cart other than the cookie's cart, the handler leaves the cookie unchanged. The handler throws GraphQL and network errors from the mutation.\n */\n post: CartPostHandler;\n};\n\n/**\n * The cart route handlers that `createCartServerHandlers` returns when you pass `customerSession`. The handlers connect carts to the logged-in customer.\n *\n * Pass `sessionManager` and `requestContext` in each handler's context. A handler throws when it reads the customer session and either value is missing.\n */\nexport type CartServerHandlersWithCustomerSession<\n TCartQuery extends AnyStorefrontQueryString = typeof cartQueries.cart,\n TCart extends CartData = CartDataFromQuery<TCartQuery>,\n> = {\n /** The cart query document that the handlers run. */\n readonly [cartServerHandlersCartQuery]: TCartQuery | undefined;\n readonly [cartBuyerIdentitySync]: CartBuyerIdentitySync;\n /** Returns the cart like the GET handler in `CartServerHandlers`. For a logged-in customer, the handler adds `logged_in=true` to the checkout URL. */\n get: CartGetHandler<TCart, CartGetHandlerContext & CartCustomerSessionReadContext>;\n /**\n * Runs cart changes like the POST handler in `CartServerHandlers`. When an add creates a cart for a logged-in customer, the handler attaches the customer to the new cart. When the handler refreshes the customer's access token and the mutation then fails, the handler returns a `cart_mutation_failed` error with status `500`.\n */\n post: CartPostHandler<CartPostHandlerContext & CartCustomerSessionWriteContext>;\n};\n\ntype AsyncHandlerResult<THandler> = THandler extends (\n ...args: infer _Args\n) => Promise<infer TResult>\n ? TResult\n : never;\n\ntype CartGetHandlerResult<THandlers> = THandlers extends { get: infer THandler }\n ? AsyncHandlerResult<THandler>\n : never;\n\ntype CartDataFromHandlerResult<TResult> = [TResult] extends [never]\n ? never\n : TResult extends { data: { cart: infer TCart } }\n ? NonNullable<TCart> extends CartData\n ? NonNullable<TCart>\n : CartData\n : CartData;\n\n/**\n * Gets the cart data type from the type of your cart server handlers, including the fields from your custom cart fragment.\n *\n * Pass `typeof cartHandlers` to type cart data in your own components and functions.\n *\n * @example\n * ```ts\n * type MyCartData = CartDataFromHandlers<typeof cartHandlers>;\n * ```\n */\nexport type CartDataFromHandlers<THandlers> = CartDataFromHandlerResult<\n CartGetHandlerResult<THandlers>\n>;\n\n/** The cart fragment option for cart server handlers. */\ninterface CartServerHandlersBaseOptions<\n TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString,\n> {\n /**\n * A cart fragment that adds fields to the cart in every cart query and mutation response.\n * Name the fragment `CartFragment` on the `Cart` type.\n *\n * `createCartServerHandlers` throws for any other fragment name or type.\n */\n readonly fragment?: TCartFragment;\n}\n\n/** Options for cart server handlers that attach the logged-in customer to new carts. */\ninterface CartServerHandlersOptionsWithCustomerSession<\n TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString,\n> extends CartServerHandlersBaseOptions<TCartFragment> {\n /** The customer session from `createCustomerSession`. Pass the session to attach the logged-in customer to new carts. */\n readonly customerSession: CartCustomerSession;\n}\n\n/** Options for cart server handlers without a customer session. */\ninterface CartServerHandlersOptionsWithoutCustomerSession<\n TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString,\n> extends CartServerHandlersBaseOptions<TCartFragment> {\n /** Leave the option out to create carts without a customer. */\n readonly customerSession?: undefined;\n}\n\n/** Options for creating cart server handlers. */\nexport type CreateCartServerHandlersOptions<\n TCartFragment extends AnyStorefrontQueryString = AnyStorefrontQueryString,\n> =\n | CartServerHandlersOptionsWithCustomerSession<TCartFragment>\n | CartServerHandlersOptionsWithoutCustomerSession<TCartFragment>;\n\ntype CartServerHandlersForOptions<TOptions> = TOptions extends {\n readonly customerSession: CartCustomerSession;\n}\n ? CartServerHandlersWithCustomerSession<\n CartQueriesForOptions<TOptions>[\"cart\"],\n CartDataForOptions<TOptions>\n >\n : CartServerHandlers<CartQueriesForOptions<TOptions>[\"cart\"], CartDataForOptions<TOptions>>;\n\n/**\n * Creates the handlers for the `/api/cart` route, which loads and changes the customer's cart.\n *\n * The handlers read the cart ID from the `cart` cookie and set the cookie when they create a cart. A JSON request gets a JSON response, and a form submission gets a `303` redirect to the referring page.\n *\n * Pass `customerSession` to connect carts to the logged-in customer. The handlers then need `sessionManager` and `requestContext` in their context.\n *\n * @example\n * ```ts\n * // Basic setup\n * const cartHandlers = createCartServerHandlers();\n *\n * // With a custom cart fragment\n * const cartHandlers = createCartServerHandlers({\n * fragment: CART_FRAGMENT,\n * });\n *\n * // With customer session for buyer identity sync\n * const cartHandlers = createCartServerHandlers({\n * customerSession,\n * });\n * ```\n * @publicDocs\n */\nexport function createCartServerHandlers(): CartServerHandlers<typeof cartQueries.cart>;\nexport function createCartServerHandlers<const TOptions extends CreateCartServerHandlersOptions>(\n options: TOptions,\n): CartServerHandlersForOptions<TOptions>;\n/**\n * @param options A custom cart fragment and the customer session.\n * @returns The GET and POST handlers to register with `handleShopifyRoutes`.\n */\nexport function createCartServerHandlers(\n options?: CreateCartServerHandlersOptions,\n): CartServerHandlers | CartServerHandlersWithCustomerSession {\n const queries = options?.fragment\n ? makeCartQueries({ fragment: options.fragment } as CreateCartQueriesOptions)\n : cartQueries;\n const runtimeQueries = queries as RuntimeCartQueries;\n const customerSession = options?.customerSession;\n\n const handlers = {\n get: createCallableRouteHandler(\n CART_API_PATH,\n CART_GET_METHOD,\n (context: CartGetHandlerContext & Partial<CartCustomerSessionReadContext>) =>\n handleGet(context, runtimeQueries, customerSession),\n ),\n post: createCallableRouteHandler(\n CART_API_PATH,\n CART_POST_METHOD,\n (context: CartPostHandlerContext & Partial<CartCustomerSessionWriteContext>) =>\n handlePost(context, runtimeQueries, customerSession),\n ),\n };\n\n Object.defineProperty(handlers, cartServerHandlersCartQuery, { value: queries.cart });\n if (customerSession) {\n // Symbol-keyed and non-enumerable so the capability never registers as a\n // route in handleShopifyRoutes and stays uncallable outside Hydrogen wiring.\n Object.defineProperty(handlers, cartBuyerIdentitySync, {\n value: createCartBuyerIdentitySync(),\n });\n }\n return handlers as CartServerHandlers | CartServerHandlersWithCustomerSession;\n}\n\nfunction createCartBuyerIdentitySync(): CartBuyerIdentitySync {\n return {\n updateBuyerIdentity: updateCartBuyerIdentity,\n expiredCartCookie: createExpiredCartCookie(),\n };\n}\n\nasync function updateCartBuyerIdentity(\n context: CartBuyerIdentitySyncContext,\n customerAccessToken: string | null,\n): Promise<void> {\n const cartId = getCartIdFromCookie(context.request);\n if (!cartId) return;\n\n const result = await context.storefrontClient.graphql(cartBuyerIdentityUpdateMutation, {\n variables: { cartId, buyerIdentity: { customerAccessToken } },\n });\n const { userErrors } = assertMutationData(result, \"cartBuyerIdentityUpdate\");\n if (userErrors.length > 0) {\n throw new Error(userErrors.map(({ message }) => message).join(\"\\n\"));\n }\n}\n\ntype RuntimeCartQueries = typeof cartQueries;\n\nasync function handleGet(\n context: CartGetHandlerContext & Partial<CartCustomerSessionReadContext>,\n queries: RuntimeCartQueries,\n customerSession?: CartCustomerSession,\n): Promise<CartGetResult> {\n const { request, storefrontClient } = context;\n const cartIdSource = request ?? storefrontClient.requestContext;\n const result = await getCart(getCartId(cartIdSource), storefrontClient, queries.cart);\n logCartErrors(result.errors);\n const cart = await addLoggedInCheckoutParam(result.cart, context, customerSession);\n const data = { cart, ...(result.errors && { errors: result.errors }) };\n const headers = createProxyResponseHeaders(result.headers);\n applyPrivateResponseCacheHeaders(headers);\n\n return {\n type: \"json\",\n data,\n headers,\n };\n}\n\nfunction logCartErrors(errors: CartGetData[\"errors\"]): void {\n if (!errors?.length) return;\n log.error(errors.map(({ message }) => message).join(\"\\n\"));\n}\n\nasync function handlePost(\n context: CartPostHandlerContext & Partial<CartCustomerSessionWriteContext>,\n queries: RuntimeCartQueries,\n customerSession?: CartCustomerSession,\n): Promise<CartPostResult> {\n const { request, storefrontClient } = context;\n const isFormRequest = !request.headers.get(\"content-type\")?.includes(\"application/json\");\n const redirectTarget = safeRedirectTarget(request);\n\n const parsedCartRequest = await parseCartAction(request, isFormRequest, redirectTarget);\n if (parsedCartRequest.type === \"response\") return parsedCartRequest.response;\n\n const cookieCartId = getCartIdFromCookie(request);\n const cartId = parsedCartRequest.bodyCartId ?? cookieCartId;\n const missingCartResponse = getMissingCartResponse(\n parsedCartRequest.action,\n cartId,\n isFormRequest,\n redirectTarget,\n );\n if (missingCartResponse) return missingCartResponse;\n\n const { action } = parsedCartRequest;\n const customerAccess = await getCartCreateCustomerAccess(\n parsedCartRequest.action,\n cartId,\n context,\n customerSession,\n );\n const customerSessionHeaders = customerAccess.commitSession\n ? await getCustomerSessionHeaders(context)\n : undefined;\n const result = await executeCartMutation(\n action,\n cartId,\n storefrontClient,\n queries,\n customerAccess.accessToken,\n customerSessionHeaders,\n );\n if (result.type !== \"mutation\") return result.response;\n\n const headers = createProxyResponseHeaders(result.headers);\n appendHeaders(headers, customerSessionHeaders);\n\n // Only persist carts the browser already owns, including newly-created carts.\n if (cartId === cookieCartId && result.cartId !== null && result.cartId !== cookieCartId) {\n headers.append(\"set-cookie\", createCartCookie(result.cartId));\n }\n\n if (isFormRequest) return redirectResult(redirectTarget, headers);\n return jsonResult(result.data, headers);\n}\n\nasync function parseCartAction(\n request: Request,\n isFormRequest: boolean,\n redirectTarget: string,\n): Promise<ParsedCartRequestResult> {\n try {\n const { action, cartId: bodyCartId } = await parseCartRequest(request);\n return { type: \"action\", action, bodyCartId };\n } catch (error) {\n if (isFormRequest) return { type: \"response\", response: redirectResult(redirectTarget) };\n return {\n type: \"response\",\n response: errorResult(\"invalid_cart_request\", getErrorMessage(error, \"Bad Request\")),\n };\n }\n}\n\nfunction getMissingCartResponse(\n action: CartAction,\n cartId: string | null,\n isFormRequest: boolean,\n redirectTarget: string,\n): CartPostResult | undefined {\n if (action.intent === \"add\" || cartId) return undefined;\n if (isFormRequest) return redirectResult(redirectTarget);\n return errorResult(\"missing_cart\", \"No cart exists. Add an item first.\");\n}\n\nasync function executeCartMutation(\n action: CartAction,\n cartId: string | null,\n storefrontClient: StorefrontClient,\n queries: RuntimeCartQueries,\n customerAccessToken: string | undefined,\n customerSessionHeaders: Headers | undefined,\n): Promise<\n ({ type: \"mutation\" } & MutationResult) | { type: \"response\"; response: CartPostResult }\n> {\n try {\n return {\n type: \"mutation\",\n ...(await executeMutation(action, cartId, storefrontClient, queries, customerAccessToken)),\n };\n } catch (error) {\n if (!customerSessionHeaders) throw error;\n log.error(\"cart mutation failed\", { error });\n return {\n type: \"response\",\n response: errorResult(\n \"cart_mutation_failed\",\n CART_MUTATION_FAILED_MESSAGE,\n customerSessionHeaders,\n CART_MUTATION_FAILED_STATUS,\n ),\n };\n }\n}\n\nasync function getCustomerSessionHeaders(\n context: Partial<CartCustomerSessionWriteContext>,\n): Promise<Headers | undefined> {\n assertCustomerSessionWriteContext(context);\n const sessionHeaders = await context.sessionManager.commit?.();\n if (!sessionHeaders) return undefined;\n return new Headers(sessionHeaders);\n}\n\nfunction appendHeaders(headers: Headers, headersToAppend: Headers | undefined) {\n if (!headersToAppend) return;\n for (const [key, value] of headersToAppend) {\n if (key !== \"set-cookie\") headers.append(key, value);\n }\n for (const setCookie of headersToAppend.getSetCookie()) {\n headers.append(\"set-cookie\", setCookie);\n }\n}\n\nfunction safeRedirectTarget(request: Request): string {\n return getSameOriginPath(request.headers.get(\"referer\"), new URL(request.url).origin) ?? \"/\";\n}\n\ntype MutationResult = {\n data: Record<string, unknown>;\n cartId: string | null;\n headers: Headers;\n};\n\ntype GraphQLResult<D> = {\n data: D | null;\n errors?: GraphQLFormattedError[];\n headers: Headers;\n};\n\nfunction assertGraphQLData<D>(result: GraphQLResult<D>): NonNullable<D> {\n if (result.errors || !result.data) {\n const message = result.errors?.[0]?.message ?? \"GraphQL error\";\n throw new Error(message);\n }\n return result.data as NonNullable<D>;\n}\n\nfunction assertMutationData<D, K extends keyof NonNullable<D>>(\n result: GraphQLResult<D>,\n key: K,\n): NonNullable<NonNullable<D>[K]> {\n const data = assertGraphQLData(result);\n const payload = data[key];\n if (payload == null) {\n throw new Error(`Missing ${String(key)} in mutation response`);\n }\n return payload as NonNullable<NonNullable<D>[K]>;\n}\n\nfunction createMutationResult(\n cart: unknown,\n userErrors: unknown,\n warnings: unknown,\n headers: Headers,\n): MutationResult {\n const storefrontCart = (cart ?? null) as Record<string, unknown> | null;\n\n return {\n data: { cart: storefrontCart, userErrors, warnings },\n cartId: typeof storefrontCart?.id === \"string\" ? storefrontCart.id : null,\n headers,\n };\n}\n\ntype CartMutationClient = Pick<StorefrontClient, \"graphql\">;\n\nasync function executeMutation(\n action: CartAction,\n cartId: string | null,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n customerAccessToken?: string,\n): Promise<MutationResult> {\n if (action.intent === \"add\") {\n return executeAdd(action.lines, cartId, storefront, queries, customerAccessToken);\n }\n\n if (!cartId) {\n throw new Error(\"cartId is required for non-add mutations\");\n }\n\n switch (action.intent) {\n case \"update\": {\n const result = await storefront.graphql(queries.cartLinesUpdate, {\n variables: { cartId, lines: action.lines },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"remove\": {\n const result = await storefront.graphql(queries.cartLinesRemove, {\n variables: { cartId, lineIds: action.lineIds },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesRemove\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"discount-update\": {\n const result = await storefront.graphql(queries.cartDiscountCodesUpdate, {\n variables: { cartId, discountCodes: action.discountCodes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartDiscountCodesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"discount-apply\":\n return executeDiscountModify(cartId, \"apply\", action.code, storefront, queries);\n case \"discount-remove\":\n return executeDiscountModify(cartId, \"remove\", action.code, storefront, queries);\n case \"note-update\": {\n const result = await storefront.graphql(queries.cartNoteUpdate, {\n variables: { cartId, note: action.note },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartNoteUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n case \"attributes-update\": {\n const result = await storefront.graphql(queries.cartAttributesUpdate, {\n variables: { cartId, attributes: action.attributes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartAttributesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n default: {\n const _exhaustive: never = action;\n throw new Error(`Unhandled cart action intent: ${(_exhaustive as CartAction).intent}`);\n }\n }\n}\n\nasync function executeAdd(\n lines: CartLineAddInput[],\n cartId: string | null,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n customerAccessToken?: string,\n): Promise<MutationResult> {\n if (cartId) {\n const result = await storefront.graphql(queries.cartLinesAdd, {\n variables: { cartId, lines },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartLinesAdd\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n }\n\n const result = await storefront.graphql(queries.cartCreate, {\n variables: {\n input: {\n lines,\n ...(customerAccessToken && { buyerIdentity: { customerAccessToken } }),\n },\n },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartCreate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n}\n\nasync function getCartCreateCustomerAccess(\n action: CartAction,\n cartId: string | null,\n context: Partial<CartCustomerSessionWriteContext>,\n customerSession?: CartCustomerSession,\n): Promise<CartCustomerAccessTokenResult> {\n if (action.intent !== \"add\" || cartId || !customerSession) {\n return { commitSession: false };\n }\n\n assertCustomerSessionWriteContext(context);\n const accessToken = await customerSession.getAccessToken(\n context.sessionManager,\n context.requestContext,\n );\n if (accessToken) return { accessToken, commitSession: false };\n\n const isLoggedIn = await customerSession.isLoggedIn(\n context.sessionManager,\n context.requestContext,\n );\n if (!isLoggedIn) return { commitSession: false };\n\n const refreshResult = await getCustomerSessionRefreshResult(\n customerSession,\n context.sessionManager,\n context.requestContext,\n );\n if (refreshResult) {\n return {\n accessToken: refreshResult.accessToken,\n commitSession: refreshResult.status !== \"transient\",\n };\n }\n\n const refreshedAccessToken = await customerSession.getOrRefreshAccessToken(\n context.sessionManager,\n context.requestContext,\n );\n return {\n accessToken: refreshedAccessToken,\n commitSession: true,\n };\n}\n\nasync function addLoggedInCheckoutParam<TCart extends CartData>(\n cart: TCart | null,\n context: Partial<CartCustomerSessionReadContext>,\n customerSession?: CartCustomerSession,\n): Promise<TCart | null> {\n if (!cart || !customerSession) return cart;\n assertCustomerSessionReadContext(context);\n if (!(await customerSession.isLoggedIn(context.sessionManager, context.requestContext)))\n return cart;\n if (!cart.checkoutUrl) return cart;\n\n const checkoutUrl = new URL(cart.checkoutUrl);\n checkoutUrl.searchParams.set(\"logged_in\", \"true\");\n return { ...cart, checkoutUrl: checkoutUrl.toString() };\n}\n\nfunction assertCustomerSessionContext(\n context: Partial<CartCustomerSessionReadContext | CartCustomerSessionWriteContext>,\n): void {\n if (context.sessionManager && context.requestContext) return;\n throw new Error(\n \"Cart handlers configured with customerSession require sessionManager and requestContext.\",\n );\n}\n\nfunction assertCustomerSessionReadContext(\n context: Partial<CartCustomerSessionReadContext>,\n): asserts context is CartCustomerSessionReadContext {\n assertCustomerSessionContext(context);\n}\n\nfunction assertCustomerSessionWriteContext(\n context: Partial<CartCustomerSessionWriteContext>,\n): asserts context is CartCustomerSessionWriteContext {\n assertCustomerSessionContext(context);\n}\n\nasync function executeDiscountModify(\n cartId: string,\n mode: \"apply\" | \"remove\",\n code: string,\n storefront: CartMutationClient,\n queries: RuntimeCartQueries,\n): Promise<MutationResult> {\n // Read-then-write: SFAPI has no atomic discount modify endpoint, so concurrent\n // requests can overwrite each other's discount codes.\n const cartResult = await storefront.graphql(queries.cart, {\n variables: { id: cartId },\n });\n const cartData = assertGraphQLData(cartResult);\n\n const currentCodes: string[] = (cartData.cart?.discountCodes ?? []).map((dc) => dc.code);\n\n const updatedCodes =\n mode === \"apply\" ? [...currentCodes, code] : currentCodes.filter((c) => c !== code);\n\n const result = await storefront.graphql(queries.cartDiscountCodesUpdate, {\n variables: { cartId, discountCodes: updatedCodes },\n });\n const { cart, userErrors, warnings } = assertMutationData(result, \"cartDiscountCodesUpdate\");\n return createMutationResult(cart, userErrors, warnings, result.headers);\n}\n\nfunction jsonResult<TData>(data: TData, headers: HeadersInit = {}): ShopifyRouteJsonResult<TData> {\n return { type: \"json\", data, headers };\n}\n\nfunction redirectResult(location: string, headers: HeadersInit = {}): ShopifyRouteRedirectResult {\n return { type: \"redirect\", location, headers };\n}\n\nfunction errorResult(\n code: CartErrorCode,\n message: string,\n headers?: HeadersInit,\n status?: number,\n): ShopifyRouteErrorResult<CartError> {\n return {\n type: \"error\",\n error: { code, message },\n ...(headers && { headers }),\n ...(status !== undefined && { status }),\n };\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error) return error.message;\n return fallback;\n}\n"],"mappings":"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"}