@aglyn/plugins-commerce 1.0.0-beta.143

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 (417) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +10 -0
  3. package/package.json +57 -0
  4. package/src/index.d.ts +38 -0
  5. package/src/index.js +38 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/account.d.ts +31 -0
  8. package/src/lib/components/account.js +645 -0
  9. package/src/lib/components/account.js.map +1 -0
  10. package/src/lib/components/cart.d.ts +38 -0
  11. package/src/lib/components/cart.js +851 -0
  12. package/src/lib/components/cart.js.map +1 -0
  13. package/src/lib/components/commerce-console-page.d.ts +32 -0
  14. package/src/lib/components/commerce-console-page.js +296 -0
  15. package/src/lib/components/commerce-console-page.js.map +1 -0
  16. package/src/lib/components/commerce-console-sections.d.ts +34 -0
  17. package/src/lib/components/commerce-console-sections.js +62 -0
  18. package/src/lib/components/commerce-console-sections.js.map +1 -0
  19. package/src/lib/components/console/catalog-organization-card.component.d.ts +14 -0
  20. package/src/lib/components/console/catalog-organization-card.component.js +1087 -0
  21. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -0
  22. package/src/lib/components/console/commerce-analytics-card.component.d.ts +27 -0
  23. package/src/lib/components/console/commerce-analytics-card.component.js +310 -0
  24. package/src/lib/components/console/commerce-analytics-card.component.js.map +1 -0
  25. package/src/lib/components/console/commerce-glance-card.component.d.ts +20 -0
  26. package/src/lib/components/console/commerce-glance-card.component.js +340 -0
  27. package/src/lib/components/console/commerce-glance-card.component.js.map +1 -0
  28. package/src/lib/components/console/commerce-stat-tile.component.d.ts +37 -0
  29. package/src/lib/components/console/commerce-stat-tile.component.js +72 -0
  30. package/src/lib/components/console/commerce-stat-tile.component.js.map +1 -0
  31. package/src/lib/components/console/discounts-card.component.d.ts +14 -0
  32. package/src/lib/components/console/discounts-card.component.js +443 -0
  33. package/src/lib/components/console/discounts-card.component.js.map +1 -0
  34. package/src/lib/components/console/entitlement-gate.component.d.ts +76 -0
  35. package/src/lib/components/console/entitlement-gate.component.js +115 -0
  36. package/src/lib/components/console/entitlement-gate.component.js.map +1 -0
  37. package/src/lib/components/console/gift-cards-card.component.d.ts +29 -0
  38. package/src/lib/components/console/gift-cards-card.component.js +379 -0
  39. package/src/lib/components/console/gift-cards-card.component.js.map +1 -0
  40. package/src/lib/components/console/host-coupons-card.component.d.ts +14 -0
  41. package/src/lib/components/console/host-coupons-card.component.js +252 -0
  42. package/src/lib/components/console/host-coupons-card.component.js.map +1 -0
  43. package/src/lib/components/console/host-orders-card.component.d.ts +13 -0
  44. package/src/lib/components/console/host-orders-card.component.js +861 -0
  45. package/src/lib/components/console/host-orders-card.component.js.map +1 -0
  46. package/src/lib/components/console/locations-card.component.d.ts +14 -0
  47. package/src/lib/components/console/locations-card.component.js +256 -0
  48. package/src/lib/components/console/locations-card.component.js.map +1 -0
  49. package/src/lib/components/console/member-posts-card.component.d.ts +8 -0
  50. package/src/lib/components/console/member-posts-card.component.js +283 -0
  51. package/src/lib/components/console/member-posts-card.component.js.map +1 -0
  52. package/src/lib/components/console/newest-site-users-card.component.d.ts +36 -0
  53. package/src/lib/components/console/newest-site-users-card.component.js +126 -0
  54. package/src/lib/components/console/newest-site-users-card.component.js.map +1 -0
  55. package/src/lib/components/console/order-detail-dialog.component.d.ts +28 -0
  56. package/src/lib/components/console/order-detail-dialog.component.js +976 -0
  57. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -0
  58. package/src/lib/components/console/paid-media.d.ts +127 -0
  59. package/src/lib/components/console/paid-media.js +397 -0
  60. package/src/lib/components/console/paid-media.js.map +1 -0
  61. package/src/lib/components/console/payments-settings-card.component.d.ts +13 -0
  62. package/src/lib/components/console/payments-settings-card.component.js +295 -0
  63. package/src/lib/components/console/payments-settings-card.component.js.map +1 -0
  64. package/src/lib/components/console/pos-page.component.d.ts +13 -0
  65. package/src/lib/components/console/pos-page.component.js +916 -0
  66. package/src/lib/components/console/pos-page.component.js.map +1 -0
  67. package/src/lib/components/console/product-editor-dialog.component.d.ts +32 -0
  68. package/src/lib/components/console/product-editor-dialog.component.js +1374 -0
  69. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -0
  70. package/src/lib/components/console/products-hub-card.component.d.ts +16 -0
  71. package/src/lib/components/console/products-hub-card.component.js +1280 -0
  72. package/src/lib/components/console/products-hub-card.component.js.map +1 -0
  73. package/src/lib/components/console/products-hub-zone.component.d.ts +50 -0
  74. package/src/lib/components/console/products-hub-zone.component.js +200 -0
  75. package/src/lib/components/console/products-hub-zone.component.js.map +1 -0
  76. package/src/lib/components/console/recovery-queue-card.component.d.ts +39 -0
  77. package/src/lib/components/console/recovery-queue-card.component.js +262 -0
  78. package/src/lib/components/console/recovery-queue-card.component.js.map +1 -0
  79. package/src/lib/components/console/registers-card.component.d.ts +21 -0
  80. package/src/lib/components/console/registers-card.component.js +296 -0
  81. package/src/lib/components/console/registers-card.component.js.map +1 -0
  82. package/src/lib/components/console/reservations-card.component.d.ts +14 -0
  83. package/src/lib/components/console/reservations-card.component.js +650 -0
  84. package/src/lib/components/console/reservations-card.component.js.map +1 -0
  85. package/src/lib/components/console/reviews-moderation-card.component.d.ts +8 -0
  86. package/src/lib/components/console/reviews-moderation-card.component.js +235 -0
  87. package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -0
  88. package/src/lib/components/console/shipping-settings-card.component.d.ts +38 -0
  89. package/src/lib/components/console/shipping-settings-card.component.js +560 -0
  90. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -0
  91. package/src/lib/components/console/stock-movements-card.component.d.ts +31 -0
  92. package/src/lib/components/console/stock-movements-card.component.js +333 -0
  93. package/src/lib/components/console/stock-movements-card.component.js.map +1 -0
  94. package/src/lib/components/console/store-settings-card.component.d.ts +14 -0
  95. package/src/lib/components/console/store-settings-card.component.js +300 -0
  96. package/src/lib/components/console/store-settings-card.component.js.map +1 -0
  97. package/src/lib/components/console/storefront-tax-summary-card.component.d.ts +73 -0
  98. package/src/lib/components/console/storefront-tax-summary-card.component.js +408 -0
  99. package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -0
  100. package/src/lib/components/console/suppliers-card.component.d.ts +8 -0
  101. package/src/lib/components/console/suppliers-card.component.js +328 -0
  102. package/src/lib/components/console/suppliers-card.component.js.map +1 -0
  103. package/src/lib/components/console/tax-settings-card.component.d.ts +14 -0
  104. package/src/lib/components/console/tax-settings-card.component.js +473 -0
  105. package/src/lib/components/console/tax-settings-card.component.js.map +1 -0
  106. package/src/lib/components/gate.d.ts +39 -0
  107. package/src/lib/components/gate.js +202 -0
  108. package/src/lib/components/gate.js.map +1 -0
  109. package/src/lib/components/gated-video.d.ts +40 -0
  110. package/src/lib/components/gated-video.js +366 -0
  111. package/src/lib/components/gated-video.js.map +1 -0
  112. package/src/lib/components/member-feed.d.ts +32 -0
  113. package/src/lib/components/member-feed.js +198 -0
  114. package/src/lib/components/member-feed.js.map +1 -0
  115. package/src/lib/components/member-recovery.d.ts +35 -0
  116. package/src/lib/components/member-recovery.js +313 -0
  117. package/src/lib/components/member-recovery.js.map +1 -0
  118. package/src/lib/components/member-signin.d.ts +35 -0
  119. package/src/lib/components/member-signin.js +257 -0
  120. package/src/lib/components/member-signin.js.map +1 -0
  121. package/src/lib/components/member-signup.d.ts +34 -0
  122. package/src/lib/components/member-signup.js +287 -0
  123. package/src/lib/components/member-signup.js.map +1 -0
  124. package/src/lib/components/newsletter-signup.d.ts +39 -0
  125. package/src/lib/components/newsletter-signup.js +229 -0
  126. package/src/lib/components/newsletter-signup.js.map +1 -0
  127. package/src/lib/components/product-detail.d.ts +38 -0
  128. package/src/lib/components/product-detail.js +1022 -0
  129. package/src/lib/components/product-detail.js.map +1 -0
  130. package/src/lib/components/product-grid.d.ts +67 -0
  131. package/src/lib/components/product-grid.js +909 -0
  132. package/src/lib/components/product-grid.js.map +1 -0
  133. package/src/lib/components/product-reviews.d.ts +32 -0
  134. package/src/lib/components/product-reviews.js +349 -0
  135. package/src/lib/components/product-reviews.js.map +1 -0
  136. package/src/lib/components/related-products.d.ts +33 -0
  137. package/src/lib/components/related-products.js +232 -0
  138. package/src/lib/components/related-products.js.map +1 -0
  139. package/src/lib/components/reservation-widget.d.ts +33 -0
  140. package/src/lib/components/reservation-widget.js +418 -0
  141. package/src/lib/components/reservation-widget.js.map +1 -0
  142. package/src/lib/components/storefront-payment-element-fallback.d.ts +18 -0
  143. package/src/lib/components/storefront-payment-element-fallback.js +51 -0
  144. package/src/lib/components/storefront-payment-element-fallback.js.map +1 -0
  145. package/src/lib/components/storefront-payment-element.d.ts +78 -0
  146. package/src/lib/components/storefront-payment-element.js +156 -0
  147. package/src/lib/components/storefront-payment-element.js.map +1 -0
  148. package/src/lib/components/wishlist.d.ts +46 -0
  149. package/src/lib/components/wishlist.js +304 -0
  150. package/src/lib/components/wishlist.js.map +1 -0
  151. package/src/lib/constants/bundle-common.d.ts +18 -0
  152. package/src/lib/constants/bundle-common.js +18 -0
  153. package/src/lib/constants/bundle-common.js.map +1 -0
  154. package/src/lib/constants/product-filters.d.ts +35 -0
  155. package/src/lib/constants/product-filters.js +109 -0
  156. package/src/lib/constants/product-filters.js.map +1 -0
  157. package/src/lib/model/commerce-cart.d.ts +52 -0
  158. package/src/lib/model/commerce-cart.js +102 -0
  159. package/src/lib/model/commerce-cart.js.map +1 -0
  160. package/src/lib/model/commerce-connect-transfer.d.ts +243 -0
  161. package/src/lib/model/commerce-connect-transfer.js +231 -0
  162. package/src/lib/model/commerce-connect-transfer.js.map +1 -0
  163. package/src/lib/model/commerce-discounts.d.ts +164 -0
  164. package/src/lib/model/commerce-discounts.js +231 -0
  165. package/src/lib/model/commerce-discounts.js.map +1 -0
  166. package/src/lib/model/commerce-dispute.d.ts +124 -0
  167. package/src/lib/model/commerce-dispute.js +225 -0
  168. package/src/lib/model/commerce-dispute.js.map +1 -0
  169. package/src/lib/model/commerce-gift-cards.d.ts +107 -0
  170. package/src/lib/model/commerce-gift-cards.js +121 -0
  171. package/src/lib/model/commerce-gift-cards.js.map +1 -0
  172. package/src/lib/model/commerce-io.d.ts +36 -0
  173. package/src/lib/model/commerce-io.js +245 -0
  174. package/src/lib/model/commerce-io.js.map +1 -0
  175. package/src/lib/model/commerce-orders.d.ts +1040 -0
  176. package/src/lib/model/commerce-orders.js +1022 -0
  177. package/src/lib/model/commerce-orders.js.map +1 -0
  178. package/src/lib/model/commerce-promotions.d.ts +188 -0
  179. package/src/lib/model/commerce-promotions.js +199 -0
  180. package/src/lib/model/commerce-promotions.js.map +1 -0
  181. package/src/lib/model/commerce-reservations.d.ts +175 -0
  182. package/src/lib/model/commerce-reservations.js +157 -0
  183. package/src/lib/model/commerce-reservations.js.map +1 -0
  184. package/src/lib/model/commerce-shipping.d.ts +316 -0
  185. package/src/lib/model/commerce-shipping.js +484 -0
  186. package/src/lib/model/commerce-shipping.js.map +1 -0
  187. package/src/lib/model/commerce-stock-holds.d.ts +199 -0
  188. package/src/lib/model/commerce-stock-holds.js +190 -0
  189. package/src/lib/model/commerce-stock-holds.js.map +1 -0
  190. package/src/lib/model/commerce-subscription-status.d.ts +67 -0
  191. package/src/lib/model/commerce-subscription-status.js +76 -0
  192. package/src/lib/model/commerce-subscription-status.js.map +1 -0
  193. package/src/lib/model/commerce-tax-decision.d.ts +222 -0
  194. package/src/lib/model/commerce-tax-decision.js +165 -0
  195. package/src/lib/model/commerce-tax-decision.js.map +1 -0
  196. package/src/lib/model/commerce-tax.d.ts +176 -0
  197. package/src/lib/model/commerce-tax.js +92 -0
  198. package/src/lib/model/commerce-tax.js.map +1 -0
  199. package/src/lib/model/commerce.d.ts +551 -0
  200. package/src/lib/model/commerce.js +739 -0
  201. package/src/lib/model/commerce.js.map +1 -0
  202. package/src/lib/model/index.d.ts +40 -0
  203. package/src/lib/model/index.js +40 -0
  204. package/src/lib/model/index.js.map +1 -0
  205. package/src/lib/model/order-figures.d.ts +48 -0
  206. package/src/lib/model/order-figures.js +74 -0
  207. package/src/lib/model/order-figures.js.map +1 -0
  208. package/src/lib/model/plugin-permissions.d.ts +23 -0
  209. package/src/lib/model/plugin-permissions.js +34 -0
  210. package/src/lib/model/plugin-permissions.js.map +1 -0
  211. package/src/lib/model/purchase-analytics.d.ts +186 -0
  212. package/src/lib/model/purchase-analytics.js +216 -0
  213. package/src/lib/model/purchase-analytics.js.map +1 -0
  214. package/src/lib/plugin-config.d.ts +62 -0
  215. package/src/lib/plugin-config.js +78 -0
  216. package/src/lib/plugin-config.js.map +1 -0
  217. package/src/lib/plugin.d.ts +28 -0
  218. package/src/lib/plugin.js +147 -0
  219. package/src/lib/plugin.js.map +1 -0
  220. package/src/lib/server/billing-webhook.d.ts +26 -0
  221. package/src/lib/server/billing-webhook.js +4011 -0
  222. package/src/lib/server/billing-webhook.js.map +1 -0
  223. package/src/lib/server/cancel-order.d.ts +87 -0
  224. package/src/lib/server/cancel-order.js +368 -0
  225. package/src/lib/server/cancel-order.js.map +1 -0
  226. package/src/lib/server/cart-checkout.d.ts +25 -0
  227. package/src/lib/server/cart-checkout.js +976 -0
  228. package/src/lib/server/cart-checkout.js.map +1 -0
  229. package/src/lib/server/cart-cookie.d.ts +32 -0
  230. package/src/lib/server/cart-cookie.js +77 -0
  231. package/src/lib/server/cart-cookie.js.map +1 -0
  232. package/src/lib/server/cart.d.ts +34 -0
  233. package/src/lib/server/cart.js +181 -0
  234. package/src/lib/server/cart.js.map +1 -0
  235. package/src/lib/server/catalog.d.ts +127 -0
  236. package/src/lib/server/catalog.js +277 -0
  237. package/src/lib/server/catalog.js.map +1 -0
  238. package/src/lib/server/checkout.d.ts +36 -0
  239. package/src/lib/server/checkout.js +915 -0
  240. package/src/lib/server/checkout.js.map +1 -0
  241. package/src/lib/server/connect.d.ts +26 -0
  242. package/src/lib/server/connect.js +238 -0
  243. package/src/lib/server/connect.js.map +1 -0
  244. package/src/lib/server/contact-refund.d.ts +117 -0
  245. package/src/lib/server/contact-refund.js +196 -0
  246. package/src/lib/server/contact-refund.js.map +1 -0
  247. package/src/lib/server/download.d.ts +39 -0
  248. package/src/lib/server/download.js +206 -0
  249. package/src/lib/server/download.js.map +1 -0
  250. package/src/lib/server/draft-order.d.ts +26 -0
  251. package/src/lib/server/draft-order.js +706 -0
  252. package/src/lib/server/draft-order.js.map +1 -0
  253. package/src/lib/server/feed.d.ts +24 -0
  254. package/src/lib/server/feed.js +59 -0
  255. package/src/lib/server/feed.js.map +1 -0
  256. package/src/lib/server/fulfill-order.d.ts +97 -0
  257. package/src/lib/server/fulfill-order.js +235 -0
  258. package/src/lib/server/fulfill-order.js.map +1 -0
  259. package/src/lib/server/gate.d.ts +36 -0
  260. package/src/lib/server/gate.js +112 -0
  261. package/src/lib/server/gate.js.map +1 -0
  262. package/src/lib/server/gift-cards.d.ts +42 -0
  263. package/src/lib/server/gift-cards.js +219 -0
  264. package/src/lib/server/gift-cards.js.map +1 -0
  265. package/src/lib/server/low-stock.d.ts +49 -0
  266. package/src/lib/server/low-stock.js +60 -0
  267. package/src/lib/server/low-stock.js.map +1 -0
  268. package/src/lib/server/manual-tax-rate.d.ts +82 -0
  269. package/src/lib/server/manual-tax-rate.js +113 -0
  270. package/src/lib/server/manual-tax-rate.js.map +1 -0
  271. package/src/lib/server/member-feed.d.ts +24 -0
  272. package/src/lib/server/member-feed.js +72 -0
  273. package/src/lib/server/member-feed.js.map +1 -0
  274. package/src/lib/server/member-name-search.d.ts +37 -0
  275. package/src/lib/server/member-name-search.js +42 -0
  276. package/src/lib/server/member-name-search.js.map +1 -0
  277. package/src/lib/server/member-post.d.ts +23 -0
  278. package/src/lib/server/member-post.js +166 -0
  279. package/src/lib/server/member-post.js.map +1 -0
  280. package/src/lib/server/membership-account.d.ts +37 -0
  281. package/src/lib/server/membership-account.js +148 -0
  282. package/src/lib/server/membership-account.js.map +1 -0
  283. package/src/lib/server/membership-admin-password.d.ts +33 -0
  284. package/src/lib/server/membership-admin-password.js +202 -0
  285. package/src/lib/server/membership-admin-password.js.map +1 -0
  286. package/src/lib/server/membership-content.d.ts +23 -0
  287. package/src/lib/server/membership-content.js +105 -0
  288. package/src/lib/server/membership-content.js.map +1 -0
  289. package/src/lib/server/membership-login.d.ts +19 -0
  290. package/src/lib/server/membership-login.js +137 -0
  291. package/src/lib/server/membership-login.js.map +1 -0
  292. package/src/lib/server/membership-logout.d.ts +19 -0
  293. package/src/lib/server/membership-logout.js +35 -0
  294. package/src/lib/server/membership-logout.js.map +1 -0
  295. package/src/lib/server/membership-recover.d.ts +60 -0
  296. package/src/lib/server/membership-recover.js +244 -0
  297. package/src/lib/server/membership-recover.js.map +1 -0
  298. package/src/lib/server/membership-register.d.ts +22 -0
  299. package/src/lib/server/membership-register.js +241 -0
  300. package/src/lib/server/membership-register.js.map +1 -0
  301. package/src/lib/server/membership-reset.d.ts +26 -0
  302. package/src/lib/server/membership-reset.js +88 -0
  303. package/src/lib/server/membership-reset.js.map +1 -0
  304. package/src/lib/server/membership-wishlist.d.ts +23 -0
  305. package/src/lib/server/membership-wishlist.js +89 -0
  306. package/src/lib/server/membership-wishlist.js.map +1 -0
  307. package/src/lib/server/membership.d.ts +96 -0
  308. package/src/lib/server/membership.js +222 -0
  309. package/src/lib/server/membership.js.map +1 -0
  310. package/src/lib/server/native-checkout.d.ts +170 -0
  311. package/src/lib/server/native-checkout.js +193 -0
  312. package/src/lib/server/native-checkout.js.map +1 -0
  313. package/src/lib/server/newsletter.d.ts +23 -0
  314. package/src/lib/server/newsletter.js +323 -0
  315. package/src/lib/server/newsletter.js.map +1 -0
  316. package/src/lib/server/notify-restock.d.ts +22 -0
  317. package/src/lib/server/notify-restock.js +84 -0
  318. package/src/lib/server/notify-restock.js.map +1 -0
  319. package/src/lib/server/order-analytics.d.ts +134 -0
  320. package/src/lib/server/order-analytics.js +263 -0
  321. package/src/lib/server/order-analytics.js.map +1 -0
  322. package/src/lib/server/order-figures.d.ts +33 -0
  323. package/src/lib/server/order-figures.js +220 -0
  324. package/src/lib/server/order-figures.js.map +1 -0
  325. package/src/lib/server/paid-media-delivery.d.ts +173 -0
  326. package/src/lib/server/paid-media-delivery.js +212 -0
  327. package/src/lib/server/paid-media-delivery.js.map +1 -0
  328. package/src/lib/server/pos-order.d.ts +54 -0
  329. package/src/lib/server/pos-order.js +1137 -0
  330. package/src/lib/server/pos-order.js.map +1 -0
  331. package/src/lib/server/process-abandoned.d.ts +54 -0
  332. package/src/lib/server/process-abandoned.js +222 -0
  333. package/src/lib/server/process-abandoned.js.map +1 -0
  334. package/src/lib/server/process-restock.d.ts +42 -0
  335. package/src/lib/server/process-restock.js +219 -0
  336. package/src/lib/server/process-restock.js.map +1 -0
  337. package/src/lib/server/product-card.d.ts +29 -0
  338. package/src/lib/server/product-card.js +54 -0
  339. package/src/lib/server/product-card.js.map +1 -0
  340. package/src/lib/server/product.d.ts +70 -0
  341. package/src/lib/server/product.js +105 -0
  342. package/src/lib/server/product.js.map +1 -0
  343. package/src/lib/server/promotion-hold.d.ts +144 -0
  344. package/src/lib/server/promotion-hold.js +174 -0
  345. package/src/lib/server/promotion-hold.js.map +1 -0
  346. package/src/lib/server/reconcile-stock.d.ts +106 -0
  347. package/src/lib/server/reconcile-stock.js +349 -0
  348. package/src/lib/server/reconcile-stock.js.map +1 -0
  349. package/src/lib/server/refund.d.ts +45 -0
  350. package/src/lib/server/refund.js +607 -0
  351. package/src/lib/server/refund.js.map +1 -0
  352. package/src/lib/server/related.d.ts +24 -0
  353. package/src/lib/server/related.js +104 -0
  354. package/src/lib/server/related.js.map +1 -0
  355. package/src/lib/server/reservation-availability.d.ts +23 -0
  356. package/src/lib/server/reservation-availability.js +111 -0
  357. package/src/lib/server/reservation-availability.js.map +1 -0
  358. package/src/lib/server/reserve-stock.d.ts +156 -0
  359. package/src/lib/server/reserve-stock.js +146 -0
  360. package/src/lib/server/reserve-stock.js.map +1 -0
  361. package/src/lib/server/reserve.d.ts +25 -0
  362. package/src/lib/server/reserve.js +426 -0
  363. package/src/lib/server/reserve.js.map +1 -0
  364. package/src/lib/server/restock-flag.d.ts +202 -0
  365. package/src/lib/server/restock-flag.js +449 -0
  366. package/src/lib/server/restock-flag.js.map +1 -0
  367. package/src/lib/server/reviews.d.ts +51 -0
  368. package/src/lib/server/reviews.js +132 -0
  369. package/src/lib/server/reviews.js.map +1 -0
  370. package/src/lib/server/site-page-enricher.d.ts +42 -0
  371. package/src/lib/server/site-page-enricher.js +149 -0
  372. package/src/lib/server/site-page-enricher.js.map +1 -0
  373. package/src/lib/server/site-page-resolver.d.ts +26 -0
  374. package/src/lib/server/site-page-resolver.js +223 -0
  375. package/src/lib/server/site-page-resolver.js.map +1 -0
  376. package/src/lib/server/stock-hold.d.ts +127 -0
  377. package/src/lib/server/stock-hold.js +258 -0
  378. package/src/lib/server/stock-hold.js.map +1 -0
  379. package/src/lib/server/storefront-tax-record.d.ts +22 -0
  380. package/src/lib/server/storefront-tax-record.js +218 -0
  381. package/src/lib/server/storefront-tax-record.js.map +1 -0
  382. package/src/lib/server/storefront-tax.d.ts +197 -0
  383. package/src/lib/server/storefront-tax.js +245 -0
  384. package/src/lib/server/storefront-tax.js.map +1 -0
  385. package/src/lib/server/stream.d.ts +25 -0
  386. package/src/lib/server/stream.js +191 -0
  387. package/src/lib/server/stream.js.map +1 -0
  388. package/src/lib/server/subscription-portal.d.ts +24 -0
  389. package/src/lib/server/subscription-portal.js +91 -0
  390. package/src/lib/server/subscription-portal.js.map +1 -0
  391. package/src/lib/server/supplier-outbox.d.ts +190 -0
  392. package/src/lib/server/supplier-outbox.js +342 -0
  393. package/src/lib/server/supplier-outbox.js.map +1 -0
  394. package/src/lib/server/supplier-update.d.ts +23 -0
  395. package/src/lib/server/supplier-update.js +289 -0
  396. package/src/lib/server/supplier-update.js.map +1 -0
  397. package/src/lib/server/tax-profile.d.ts +29 -0
  398. package/src/lib/server/tax-profile.js +40 -0
  399. package/src/lib/server/tax-profile.js.map +1 -0
  400. package/src/lib/server.d.ts +32 -0
  401. package/src/lib/server.js +311 -0
  402. package/src/lib/server.js.map +1 -0
  403. package/src/lib/site.d.ts +27 -0
  404. package/src/lib/site.js +134 -0
  405. package/src/lib/site.js.map +1 -0
  406. package/src/lib/utils/escape-html.d.ts +41 -0
  407. package/src/lib/utils/escape-html.js +41 -0
  408. package/src/lib/utils/escape-html.js.map +1 -0
  409. package/src/lib/utils/generate-preset-id.d.ts +19 -0
  410. package/src/lib/utils/generate-preset-id.js +25 -0
  411. package/src/lib/utils/generate-preset-id.js.map +1 -0
  412. package/src/lib/utils/member-continue.d.ts +45 -0
  413. package/src/lib/utils/member-continue.js +49 -0
  414. package/src/lib/utils/member-continue.js.map +1 -0
  415. package/src/lib/utils/use-storefront-purchase-event.d.ts +60 -0
  416. package/src/lib/utils/use-storefront-purchase-event.js +142 -0
  417. package/src/lib/utils/use-storefront-purchase-event.js.map +1 -0
@@ -0,0 +1,484 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * Shipping v1 (AGL-288): zones own countries; rates belong to a zone and
18
+ * price as flat, free-over-threshold, or subtotal/weight tiers. Settings
19
+ * live on `hosts/{hostId}/settings/store` under `shipping`. Pure.
20
+ *
21
+ * `resolveShippingRates` is the per-destination resolver;
22
+ * `resolveCheckoutShippingOptions` is the Stripe Checkout adapter,
23
+ * `planCheckoutShipping` decides which destinations one session may serve,
24
+ * `appendCheckoutShippingParams` emits it onto a session, and
25
+ * `summarizeShippingCoverage` answers the same question for the console, so a
26
+ * merchant can see which destinations their zones refuse. AGL-288 shipped this
27
+ * model with no production call site at all — the doc comment here claimed the
28
+ * cart estimator, checkout and POS pickup used it, and none of them did, so
29
+ * nothing ever read the settings a merchant saved and no shipping was ever
30
+ * charged. Cart checkout calls it (AGL-1707), buy-now calls it for physical
31
+ * one-time products (AGL-1720), and a draft order's payment link calls it for
32
+ * physical products (AGL-1792).
33
+ *
34
+ * POS DOES NOT, AND SHOULD NOT (AGL-1792). A register has no destination
35
+ * anywhere in it — no address field, no delivery choice — and all three
36
+ * tenders settle at the counter: cash, a card QR the customer scans while
37
+ * standing there, and a room folio collected at check-out. There is nothing to
38
+ * price a parcel against, so the only rate POS could resolve is the free
39
+ * `Local pickup` one this module appends, which is 0¢ and would add a step to
40
+ * a register flow in exchange for nothing. A POS sale that must be shipped is
41
+ * a draft order.
42
+ */ import { _ as _extends } from "@swc/helpers/_/_extends";
43
+ /**
44
+ * The rate id appended for local pickup (AGL-2325).
45
+ *
46
+ * Exported because pickup is the one entry in a resolved list that is NOT a
47
+ * shipping promise: it is appended AFTER and INDEPENDENT of zone matching, so
48
+ * it resolves for every destination on earth. Anything asking "does this store
49
+ * ship there" — the checkout refusal, the console coverage card — has to be
50
+ * able to tell it apart from a rate, or it reads a merchant who offers
51
+ * collection as a merchant who delivers worldwide.
52
+ */ export const LOCAL_PICKUP_RATE_ID = 'pickup';
53
+ /**
54
+ * One stored country code, normalised (AGL-2298).
55
+ *
56
+ * TRIMMED as well as upper-cased. The console trims on save, so this only
57
+ * matters for a document written any other way — an import, the REST API, a
58
+ * hand edit — but the failure it produces is silent and expensive: `' US'`
59
+ * upper-cases to `' US'`, matches nothing, and the store refuses every US
60
+ * shopper with "This store does not ship to the United States" while its
61
+ * settings card shows `US` right there.
62
+ */ const zoneCode = (code)=>String(code != null ? code : '').trim().toUpperCase();
63
+ /** Whether a stored code is the rest-of-world wildcard. */ const isWildcard = (code)=>zoneCode(code) === '*';
64
+ function zoneMatches(zone, country) {
65
+ var _zone_countries;
66
+ return ((_zone_countries = zone.countries) != null ? _zone_countries : []).some((code)=>isWildcard(code) || zoneCode(code) === country);
67
+ }
68
+ function tierAmount(tiers, value) {
69
+ const sorted = [
70
+ ...tiers != null ? tiers : []
71
+ ].sort((a, b)=>a.upTo - b.upTo);
72
+ for (const tier of sorted){
73
+ if (value <= tier.upTo) return tier.amountCents;
74
+ }
75
+ // Beyond the last tier the rate does not apply (merchant should add a
76
+ // catch-all tier with a large upTo).
77
+ return null;
78
+ }
79
+ /**
80
+ * Rates available for a destination + cart, cheapest first. Specific
81
+ * country zones beat '*' zones: when any specific zone matches, '*'
82
+ * zones are ignored (rest-of-world semantics).
83
+ *
84
+ * Local pickup is appended AFTER and INDEPENDENT of zone matching, so this
85
+ * list is never empty for a merchant who offers it, at any destination. That
86
+ * is correct for a resolver — a shopper anywhere may choose to come and
87
+ * collect — but it means A NON-EMPTY RESULT IS NOT A PROMISE TO SHIP THERE.
88
+ * Callers deciding whether a destination is served must filter pickup out
89
+ * first; `planCheckoutShipping` and `summarizeShippingCoverage` do (AGL-2325).
90
+ */ export function resolveShippingRates(settings, destinationCountry, cart) {
91
+ var _settings_zones, _settings_rates;
92
+ if (!settings || !destinationCountry) return [];
93
+ const country = destinationCountry.toUpperCase();
94
+ const zones = (_settings_zones = settings.zones) != null ? _settings_zones : [];
95
+ // A zone is SPECIFIC when it names this country outright — not merely when
96
+ // it is "not wildcard-only" (AGL-2298). The old test was `!every(code ===
97
+ // '*')`, so a zone spelled `['*','US']` counted as specific for all six
98
+ // destinations (it matches every country through the `*`) and suppressed
99
+ // every genuine rest-of-world zone globally. Asking the narrower question
100
+ // makes such a zone specific for `US` and wildcard for the rest, which is
101
+ // what its two entries actually say.
102
+ const specific = zones.filter((zone)=>{
103
+ var _zone_countries;
104
+ return ((_zone_countries = zone.countries) != null ? _zone_countries : []).some((code)=>zoneCode(code) === country);
105
+ });
106
+ const matched = specific.length ? specific : zones.filter((zone)=>zoneMatches(zone, country));
107
+ const zoneIds = new Set(matched.map((zone)=>zone.id));
108
+ const resolved = [];
109
+ for (const rate of (_settings_rates = settings.rates) != null ? _settings_rates : []){
110
+ if (!zoneIds.has(rate.zoneId)) continue;
111
+ let amountCents = null;
112
+ switch(rate.kind){
113
+ case 'flat':
114
+ var _rate_amountCents;
115
+ amountCents = Math.max(0, Math.round((_rate_amountCents = rate.amountCents) != null ? _rate_amountCents : 0));
116
+ break;
117
+ case 'free_over':
118
+ var _rate_amountCents1;
119
+ amountCents = rate.freeOverCents != null && cart.subtotalCents >= rate.freeOverCents ? 0 : Math.max(0, Math.round((_rate_amountCents1 = rate.amountCents) != null ? _rate_amountCents1 : 0));
120
+ break;
121
+ case 'price_tiers':
122
+ amountCents = tierAmount(rate.tiers, cart.subtotalCents);
123
+ break;
124
+ case 'weight_tiers':
125
+ var _cart_totalGrams;
126
+ amountCents = tierAmount(rate.tiers, (_cart_totalGrams = cart.totalGrams) != null ? _cart_totalGrams : 0);
127
+ break;
128
+ }
129
+ if (amountCents == null) continue;
130
+ resolved.push({
131
+ rateId: rate.id,
132
+ name: rate.name,
133
+ amountCents
134
+ });
135
+ }
136
+ if (settings.localPickup) {
137
+ resolved.push({
138
+ rateId: LOCAL_PICKUP_RATE_ID,
139
+ name: 'Local pickup',
140
+ amountCents: 0
141
+ });
142
+ }
143
+ return resolved.sort((a, b)=>a.amountCents - b.amountCents);
144
+ }
145
+ /**
146
+ * The resolved options that actually carry a parcel (AGL-2325).
147
+ *
148
+ * Safe to apply AFTER `MAX_CHECKOUT_SHIPPING_OPTIONS` truncation: pickup is
149
+ * 0¢ and sorts first, so it occupies at most one of the five slots and a
150
+ * merchant with any shippable rate at all keeps at least one of them.
151
+ */ function shippableOnly(options) {
152
+ return options.filter((option)=>option.rateId !== LOCAL_PICKUP_RATE_ID);
153
+ }
154
+ /** Stripe Checkout accepts at most 5 `shipping_options` on one session. */ export const MAX_CHECKOUT_SHIPPING_OPTIONS = 5;
155
+ /**
156
+ * Destinations a storefront Checkout Session collects an address for, and
157
+ * therefore the destinations shipping rates are resolved against (AGL-1707).
158
+ *
159
+ * NOT narrowed to the zones the merchant configured: narrowing would block
160
+ * checkouts that complete today, turning a money fix into lost sales. The
161
+ * wider list only means a shopper outside the merchant's zones is offered some
162
+ * rate rather than none. Shared by cart checkout and buy-now (AGL-1720) so the
163
+ * two paths cannot drift into offering different destinations.
164
+ */ export const CHECKOUT_SHIPPING_COUNTRIES = [
165
+ 'US',
166
+ 'CA',
167
+ 'GB',
168
+ 'AU',
169
+ 'DE',
170
+ 'FR'
171
+ ];
172
+ /**
173
+ * The rates to declare as `shipping_options` on a Stripe Checkout Session
174
+ * (AGL-1707), unioned over `destinationCountries`. Stripe charges shipping
175
+ * ONLY when the session declares them.
176
+ *
177
+ * A UNION IS ONLY HONEST OVER DESTINATIONS THE SESSION IS ALSO RESTRICTED TO.
178
+ * Called with every collectable country while the session accepted an address
179
+ * in any of them — which is what AGL-1707 shipped — it offers a shopper in one
180
+ * zone a rate belonging to another, and Stripe applies whichever the shopper
181
+ * picks (a `shipping_rate_data` carries no country of its own, so nothing
182
+ * downstream re-checks it against the address). That is AGL-1721. Callers now
183
+ * reach this through `planCheckoutShipping`, which pairs the country list it
184
+ * unions over with the country list the session allows, so the two cannot
185
+ * disagree. Do not call it directly from a handler.
186
+ *
187
+ * Returns `[]` for a merchant who has configured nothing, and the caller must
188
+ * then declare no `shipping_options` at all rather than an empty array — a
189
+ * merchant who never set shipping up keeps a session identical to today's.
190
+ */ export function resolveCheckoutShippingOptions(settings, destinationCountries, cart) {
191
+ if (!settings) return [];
192
+ const byRateId = new Map();
193
+ for (const country of destinationCountries){
194
+ for (const rate of resolveShippingRates(settings, country, cart)){
195
+ // Stripe requires a display name, and a rate id is the dedupe key —
196
+ // the console lets a merchant add a blank row, so neither is assured.
197
+ if (!rate.rateId || !rate.name) continue;
198
+ const amountCents = Math.max(0, Math.round(Number(rate.amountCents) || 0));
199
+ const existing = byRateId.get(rate.rateId);
200
+ // One rate resolving differently for two countries should not be
201
+ // possible (a zone selects a rate, it does not reprice one), but if it
202
+ // ever is, keep the dearer. Under-charging is the defect being fixed.
203
+ if (!existing || amountCents > existing.amountCents) {
204
+ byRateId.set(rate.rateId, _extends({}, rate, {
205
+ amountCents
206
+ }));
207
+ }
208
+ }
209
+ }
210
+ return [
211
+ ...byRateId.values()
212
+ ]// Cheapest first, id as a tie-break so the emitted params are stable.
213
+ .sort((a, b)=>a.amountCents - b.amountCents || a.rateId.localeCompare(b.rateId))// Past Stripe's cap the dearest are dropped, which is the harmless end
214
+ // to lose: a shopper offered the cheap options would have taken one.
215
+ .slice(0, MAX_CHECKOUT_SHIPPING_OPTIONS);
216
+ }
217
+ /** Shopper-facing names for the collectable destinations (AGL-1721). */ export const CHECKOUT_SHIPPING_COUNTRY_NAMES = {
218
+ US: 'United States',
219
+ CA: 'Canada',
220
+ GB: 'United Kingdom',
221
+ AU: 'Australia',
222
+ DE: 'Germany',
223
+ FR: 'France'
224
+ };
225
+ /**
226
+ * A destination a shopper declared, or `undefined` for anything this session
227
+ * could not collect an address for anyway. Never throws: an unknown code is
228
+ * an undeclared destination, not an error, so a stale storefront that posts
229
+ * one is answered by the plan below rather than by a 400 nobody can act on.
230
+ */ export function normalizeCheckoutShippingCountry(value) {
231
+ // `typeof` rather than `String(value)`: a JSON body is caller-shaped, and
232
+ // `String(['US'])` is 'US'. Coercing would let an array declare a
233
+ // destination, which is not a spelling any storefront sends.
234
+ if (typeof value !== 'string') return undefined;
235
+ const code = value.trim().toUpperCase();
236
+ return CHECKOUT_SHIPPING_COUNTRIES.includes(code) ? code : undefined;
237
+ }
238
+ /**
239
+ * Whether this merchant prices shipping AT ALL (AGL-2232).
240
+ *
241
+ * A pure question about the SETTINGS, deliberately taking no cart, and that is
242
+ * the whole point of it existing. `planCheckoutShipping` used to ask "does any
243
+ * rate resolve for any destination?" and pass the live cart into the probe, so
244
+ * a cart that exhausted every tier made the probe empty too — and an empty
245
+ * probe reads as "this merchant never set shipping up", the one case that must
246
+ * complete with no `shipping_options` and nothing charged. A 3 kg order at a
247
+ * store whose weight tiers stop at 2 kg therefore shipped free, silently, on
248
+ * every one of the three doors.
249
+ *
250
+ * Answered from the stored zones and rates instead: a rate bound to a zone
251
+ * that exists, or local pickup, means the merchant made a shipping decision
252
+ * and a cart their table cannot price is a REFUSAL. A merchant with no zones,
253
+ * no rates and no pickup has made no such decision, and their session stays
254
+ * byte-identical to the one AGL-1707 shipped.
255
+ */ export function merchantPricesShipping(settings) {
256
+ var _settings_zones, _settings_rates;
257
+ if (!settings) return false;
258
+ if (settings.localPickup) return true;
259
+ const zoneIds = new Set(((_settings_zones = settings.zones) != null ? _settings_zones : []).map((zone)=>zone.id));
260
+ // A rate whose `zoneId` names no zone is unreachable by every resolver here,
261
+ // so it is not evidence of a decision — counting it would refuse carts at a
262
+ // store with nothing but orphaned rows.
263
+ return ((_settings_rates = settings.rates) != null ? _settings_rates : []).some((rate)=>zoneIds.has(rate.zoneId));
264
+ }
265
+ /**
266
+ * What a shopper is told when `cart-unpriceable` refuses (AGL-2232).
267
+ *
268
+ * One string, shared by all three doors, because the three used to phrase the
269
+ * two existing refusals identically and drifting here would make the same
270
+ * store say different things depending on which button was pressed. It names
271
+ * the cart rather than the destination on purpose — a `Ship to` select cannot
272
+ * fix a parcel no tier covers, so the refusal deliberately does NOT set
273
+ * `needsShippingCountry`.
274
+ */ export const CART_UNPRICEABLE_SHIPPING_MESSAGE = 'This store cannot price shipping for this order — it falls outside every ' + 'shipping rate the store has set up. Try removing an item, or contact the ' + 'store.';
275
+ /** Identity of a resolved list, for comparing two destinations' offers. */ function optionsKey(options) {
276
+ return options.map((option)=>`${option.rateId}:${option.amountCents}`).join('|');
277
+ }
278
+ /**
279
+ * The whole shipping half of a Checkout Session: which destinations it may
280
+ * accept an address for, and which rates it may charge (AGL-1721).
281
+ *
282
+ * THE INVARIANT IS THAT EVERY RETURNED OPTION IS VALID FOR EVERY RETURNED
283
+ * COUNTRY. Stripe offers a session's `shipping_options` to whoever reaches the
284
+ * page and charges whichever the shopper picks — it does not filter them by
285
+ * the address entered, and there is no field on a `shipping_rate_data` that
286
+ * would let it. So the ONLY place a zone can be enforced is here, by choosing
287
+ * the two lists together: narrowing the allowed countries to the declared
288
+ * destination is what makes the rates offered for it unpickable by anyone
289
+ * else. Filtering the rate list alone would leave a session that still accepts
290
+ * a French address against a US rate.
291
+ *
292
+ * Three shapes come out of it:
293
+ *
294
+ * 1. A merchant whose rates resolve the SAME for every collectable country —
295
+ * one zone, a single '*' zone, or none at all — needs no destination and
296
+ * keeps the session AGL-1707 shipped, byte for byte. The issue notes this
297
+ * is the common configuration, and it is the one that must not regress.
298
+ * 2. A declared destination resolves exactly, and the session is restricted
299
+ * to it. A caller may not skip the restriction: the country arrives in a
300
+ * request body a shopper can craft, so a session that took the country's
301
+ * cheap rate while still accepting any address would hand that shopper
302
+ * the defect on purpose.
303
+ * 3. Otherwise the caller must refuse — see `refusal`. Refusing is not lost
304
+ * revenue in either case: with rates that differ by zone there is no
305
+ * correct amount to charge without knowing where the parcel is going, and
306
+ * the union AGL-1707 shipped chose the wrong one silently.
307
+ *
308
+ * `cart.subtotalCents` is the PRE-discount items total, matching what the cart
309
+ * displays, so a free-over threshold means what the shopper saw it mean.
310
+ */ export function planCheckoutShipping(settings, cart, destinationCountry) {
311
+ const countries = CHECKOUT_SHIPPING_COUNTRIES;
312
+ const destination = normalizeCheckoutShippingCountry(destinationCountry);
313
+ if (destination) {
314
+ const options = resolveCheckoutShippingOptions(settings, [
315
+ destination
316
+ ], cart);
317
+ // REFUSAL IS DECIDED ON SHIPPABLE RATES, PICKUP IS OFFERED AFTERWARDS
318
+ // (AGL-2325). `resolveShippingRates` appends pickup independent of zone
319
+ // matching, so a merchant who turned it on had a non-empty list for every
320
+ // destination on earth and this branch returned before it could refuse
321
+ // anyone: a shopper in France picked `Local pickup — Free` on a physical
322
+ // order from a US-only store, Stripe collected their French address
323
+ // because the session still allowed it, and the merchant was paid nothing
324
+ // to carry the parcel there. Pickup is collection, not delivery, so it
325
+ // cannot answer "do you ship to France".
326
+ //
327
+ // `shipsElsewhere` is the same question the old probe asked, narrowed to
328
+ // shippable rates, and it keeps the same two-way fork: a merchant who
329
+ // configured NO shipping is not refusing anyone, so that store keeps
330
+ // completing exactly as it does today, while a merchant who ships
331
+ // elsewhere but not here is refusing and saying so is the honest answer.
332
+ // A merchant who ships NOWHERE is untouched by this: pickup-only is a
333
+ // real configuration — they deliver to no one and refuse no one — and it
334
+ // falls through to the offer below exactly as it did.
335
+ const shipsElsewhere = countries.some((country)=>shippableOnly(resolveCheckoutShippingOptions(settings, [
336
+ country
337
+ ], cart)).length > 0);
338
+ if (shippableOnly(options).length === 0 && shipsElsewhere) {
339
+ return {
340
+ countries,
341
+ options: [],
342
+ refusal: 'destination-unserved'
343
+ };
344
+ }
345
+ if (options.length > 0) return {
346
+ countries: [
347
+ destination
348
+ ],
349
+ options
350
+ };
351
+ // NOTHING resolves anywhere for this cart, and the two reasons that can be
352
+ // true of are opposite (AGL-2232). Asked of the SETTINGS rather than of
353
+ // this cart, because the probe above cannot tell them apart: a merchant
354
+ // who priced shipping and whose table simply does not reach this order is
355
+ // refusing, and used to be handed the "never set shipping up" branch.
356
+ return merchantPricesShipping(settings) ? {
357
+ countries,
358
+ options: [],
359
+ refusal: 'cart-unpriceable'
360
+ } : {
361
+ countries,
362
+ options: []
363
+ };
364
+ }
365
+ const offers = new Set(countries.map((country)=>optionsKey(resolveCheckoutShippingOptions(settings, [
366
+ country
367
+ ], cart))));
368
+ // Compared as EMITTED — capped and sanitized — because that is the list a
369
+ // shopper can pick from. Two destinations whose rates differ only past
370
+ // Stripe's cap still offer the same five, and offering them is honest.
371
+ if (offers.size > 1) {
372
+ return {
373
+ countries,
374
+ options: [],
375
+ refusal: 'destination-required'
376
+ };
377
+ }
378
+ const union = resolveCheckoutShippingOptions(settings, countries, cart);
379
+ // Every destination agrees, and what they agree on is NOTHING. The same
380
+ // fork as the declared-destination branch above (AGL-2232): a store with no
381
+ // shipping settings completes untouched, a store whose rates cannot reach
382
+ // this cart refuses instead of carrying the parcel for free.
383
+ if (union.length === 0 && merchantPricesShipping(settings)) {
384
+ return {
385
+ countries,
386
+ options: [],
387
+ refusal: 'cart-unpriceable'
388
+ };
389
+ }
390
+ return {
391
+ countries,
392
+ options: union
393
+ };
394
+ }
395
+ /**
396
+ * A cart chosen so that every rate a merchant could have written resolves if
397
+ * it can resolve at all (AGL-1791). The settings page has no cart, and two of
398
+ * the four rate kinds price against one: `tierAmount` takes the first tier
399
+ * whose `upTo` is at least the value, so a zero subtotal and zero weight clear
400
+ * every tier a merchant would write, and a `free_over` rate resolves at any
401
+ * subtotal.
402
+ *
403
+ * That makes a coverage answer a LOWER BOUND on the gaps. A destination
404
+ * reported unserved is unserved for every cart; a destination reported served
405
+ * may still be refused for a cart dearer or heavier than the merchant's last
406
+ * tier. Erring in this direction is the deliberate half: the console must not
407
+ * warn a merchant whose settings are fine.
408
+ */ const COVERAGE_PROBE_CART = {
409
+ subtotalCents: 0,
410
+ totalGrams: 0
411
+ };
412
+ /**
413
+ * Which of the collectable destinations a merchant's settings actually cover
414
+ * (AGL-1791), for a console surface to show them.
415
+ *
416
+ * Measured against `CHECKOUT_SHIPPING_COUNTRIES` and nothing wider: those six
417
+ * are the only destinations a storefront session collects an address for, so
418
+ * they are the only ones a merchant can lose an order to. Counting coverage
419
+ * against every country on earth would report a gap for destinations no
420
+ * shopper can reach checkout from.
421
+ *
422
+ * Answered through `resolveCheckoutShippingOptions` — the same function the
423
+ * session is built from — so a row the console allows but Stripe would reject
424
+ * (blank id, blank name) counts as the nothing it resolves to, and a specific
425
+ * zone with no rates still hides a `*` zone here exactly as it does at
426
+ * checkout.
427
+ */ export function summarizeShippingCoverage(settings) {
428
+ var _ref;
429
+ const served = [];
430
+ const unserved = [];
431
+ const offers = new Set();
432
+ for (const country of CHECKOUT_SHIPPING_COUNTRIES){
433
+ const options = resolveCheckoutShippingOptions(settings, [
434
+ country
435
+ ], COVERAGE_PROBE_CART);
436
+ // `asksDestination` is asked of the FULL list — pickup is a real option a
437
+ // shopper picks, so a merchant whose US destination offers a rate plus
438
+ // pickup while France offers only pickup genuinely does make checkout ask.
439
+ offers.add(optionsKey(options));
440
+ (shippableOnly(options).length > 0 ? served : unserved).push(country);
441
+ }
442
+ return {
443
+ served,
444
+ unserved: served.length > 0 ? unserved : [],
445
+ shipsNowhere: served.length === 0,
446
+ asksDestination: offers.size > 1,
447
+ offersLocalPickup: Boolean(settings == null ? void 0 : settings.localPickup),
448
+ hasRestOfWorldZone: ((_ref = settings == null ? void 0 : settings.zones) != null ? _ref : []).some((zone)=>zone.countries.some((code)=>code === '*'))
449
+ };
450
+ }
451
+ /**
452
+ * Emit `shipping_address_collection[allowed_countries][n]` onto a session's
453
+ * form body. Stripe will not apply a `shipping_options` rate without an
454
+ * address to ship to, so the two always travel together — and the countries
455
+ * are the OTHER half of what makes a rate honest (AGL-1721), so pass the list
456
+ * `planCheckoutShipping` returned rather than defaulting it beside a rate list
457
+ * resolved for something narrower.
458
+ */ export function appendShippingAddressCollectionParams(params, countries = CHECKOUT_SHIPPING_COUNTRIES) {
459
+ countries.forEach((code, index)=>{
460
+ params.set(`shipping_address_collection[allowed_countries][${index}]`, code);
461
+ });
462
+ }
463
+ /**
464
+ * Emit resolved rates as `shipping_options` on a Checkout Session's form body.
465
+ *
466
+ * THIS IS THE ONLY THING THAT MAKES STRIPE CHARGE SHIPPING. Without these keys
467
+ * Stripe presents no shipping choice and `total_details.amount_shipping` is 0
468
+ * however many zones and rates the merchant saved (AGL-1707).
469
+ *
470
+ * An empty list emits NOTHING — not an empty array — so a merchant who
471
+ * configured no shipping keeps a session byte-identical to the one built
472
+ * before shipping was wired at all. That guarantee lives here rather than in
473
+ * each caller, so neither checkout path can lose it independently (AGL-1720).
474
+ */ export function appendCheckoutShippingParams(params, options) {
475
+ options.forEach((option, index)=>{
476
+ const field = `shipping_options[${index}][shipping_rate_data]`;
477
+ params.set(`${field}[type]`, 'fixed_amount');
478
+ params.set(`${field}[display_name]`, option.name.slice(0, 100));
479
+ params.set(`${field}[fixed_amount][amount]`, String(option.amountCents));
480
+ params.set(`${field}[fixed_amount][currency]`, 'usd');
481
+ });
482
+ }
483
+
484
+ //# sourceMappingURL=commerce-shipping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/commerce-shipping.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Shipping v1 (AGL-288): zones own countries; rates belong to a zone and\n * price as flat, free-over-threshold, or subtotal/weight tiers. Settings\n * live on `hosts/{hostId}/settings/store` under `shipping`. Pure.\n *\n * `resolveShippingRates` is the per-destination resolver;\n * `resolveCheckoutShippingOptions` is the Stripe Checkout adapter,\n * `planCheckoutShipping` decides which destinations one session may serve,\n * `appendCheckoutShippingParams` emits it onto a session, and\n * `summarizeShippingCoverage` answers the same question for the console, so a\n * merchant can see which destinations their zones refuse. AGL-288 shipped this\n * model with no production call site at all — the doc comment here claimed the\n * cart estimator, checkout and POS pickup used it, and none of them did, so\n * nothing ever read the settings a merchant saved and no shipping was ever\n * charged. Cart checkout calls it (AGL-1707), buy-now calls it for physical\n * one-time products (AGL-1720), and a draft order's payment link calls it for\n * physical products (AGL-1792).\n *\n * POS DOES NOT, AND SHOULD NOT (AGL-1792). A register has no destination\n * anywhere in it — no address field, no delivery choice — and all three\n * tenders settle at the counter: cash, a card QR the customer scans while\n * standing there, and a room folio collected at check-out. There is nothing to\n * price a parcel against, so the only rate POS could resolve is the free\n * `Local pickup` one this module appends, which is 0¢ and would add a step to\n * a register flow in exchange for nothing. A POS sale that must be shipped is\n * a draft order.\n */\n\nexport interface ShippingZone {\n id: string\n name: string\n /** ISO-3166 alpha-2 codes; '*' = rest of world. */\n countries: string[]\n}\n\nexport interface ShippingTier {\n /** Tier applies while subtotal (cents) or weight (grams) ≤ this. */\n upTo: number\n amountCents: number\n}\n\nexport interface ShippingRate {\n id: string\n zoneId: string\n name: string\n kind: 'flat' | 'free_over' | 'price_tiers' | 'weight_tiers'\n /** flat + free_over base amount. */\n amountCents?: number\n /** free_over: order subtotal (cents) at/above which shipping is free. */\n freeOverCents?: number\n /** price_tiers (upTo = subtotal cents) / weight_tiers (upTo = grams). */\n tiers?: ShippingTier[]\n}\n\nexport interface ShippingSettings {\n zones?: ShippingZone[]\n rates?: ShippingRate[]\n /**\n * Offer free local pickup as a delivery choice. Does NOT widen where the\n * store ships: a destination no rate reaches is still refused (AGL-2325).\n */\n localPickup?: boolean\n}\n\nexport interface ResolvedShippingRate {\n rateId: string\n name: string\n amountCents: number\n}\n\n/**\n * The rate id appended for local pickup (AGL-2325).\n *\n * Exported because pickup is the one entry in a resolved list that is NOT a\n * shipping promise: it is appended AFTER and INDEPENDENT of zone matching, so\n * it resolves for every destination on earth. Anything asking \"does this store\n * ship there\" — the checkout refusal, the console coverage card — has to be\n * able to tell it apart from a rate, or it reads a merchant who offers\n * collection as a merchant who delivers worldwide.\n */\nexport const LOCAL_PICKUP_RATE_ID = 'pickup'\n\n/**\n * One stored country code, normalised (AGL-2298).\n *\n * TRIMMED as well as upper-cased. The console trims on save, so this only\n * matters for a document written any other way — an import, the REST API, a\n * hand edit — but the failure it produces is silent and expensive: `' US'`\n * upper-cases to `' US'`, matches nothing, and the store refuses every US\n * shopper with \"This store does not ship to the United States\" while its\n * settings card shows `US` right there.\n */\nconst zoneCode = (code: unknown): string => String(code ?? '').trim().toUpperCase()\n\n/** Whether a stored code is the rest-of-world wildcard. */\nconst isWildcard = (code: unknown): boolean => zoneCode(code) === '*'\n\nfunction zoneMatches(zone: ShippingZone, country: string): boolean {\n return (zone.countries ?? []).some(\n (code) => isWildcard(code) || zoneCode(code) === country,\n )\n}\n\nfunction tierAmount(\n tiers: ShippingTier[] | undefined,\n value: number,\n): number | null {\n const sorted = [...(tiers ?? [])].sort((a, b) => a.upTo - b.upTo)\n for (const tier of sorted) {\n if (value <= tier.upTo) return tier.amountCents\n }\n // Beyond the last tier the rate does not apply (merchant should add a\n // catch-all tier with a large upTo).\n return null\n}\n\n/**\n * Rates available for a destination + cart, cheapest first. Specific\n * country zones beat '*' zones: when any specific zone matches, '*'\n * zones are ignored (rest-of-world semantics).\n *\n * Local pickup is appended AFTER and INDEPENDENT of zone matching, so this\n * list is never empty for a merchant who offers it, at any destination. That\n * is correct for a resolver — a shopper anywhere may choose to come and\n * collect — but it means A NON-EMPTY RESULT IS NOT A PROMISE TO SHIP THERE.\n * Callers deciding whether a destination is served must filter pickup out\n * first; `planCheckoutShipping` and `summarizeShippingCoverage` do (AGL-2325).\n */\nexport function resolveShippingRates(\n settings: ShippingSettings | undefined,\n destinationCountry: string | undefined,\n cart: { subtotalCents: number; totalGrams?: number },\n): ResolvedShippingRate[] {\n if (!settings || !destinationCountry) return []\n const country = destinationCountry.toUpperCase()\n const zones = settings.zones ?? []\n // A zone is SPECIFIC when it names this country outright — not merely when\n // it is \"not wildcard-only\" (AGL-2298). The old test was `!every(code ===\n // '*')`, so a zone spelled `['*','US']` counted as specific for all six\n // destinations (it matches every country through the `*`) and suppressed\n // every genuine rest-of-world zone globally. Asking the narrower question\n // makes such a zone specific for `US` and wildcard for the rest, which is\n // what its two entries actually say.\n const specific = zones.filter((zone) =>\n (zone.countries ?? []).some((code) => zoneCode(code) === country),\n )\n const matched = specific.length\n ? specific\n : zones.filter((zone) => zoneMatches(zone, country))\n const zoneIds = new Set(matched.map((zone) => zone.id))\n const resolved: ResolvedShippingRate[] = []\n for (const rate of settings.rates ?? []) {\n if (!zoneIds.has(rate.zoneId)) continue\n let amountCents: number | null = null\n switch (rate.kind) {\n case 'flat':\n amountCents = Math.max(0, Math.round(rate.amountCents ?? 0))\n break\n case 'free_over':\n amountCents =\n rate.freeOverCents != null &&\n cart.subtotalCents >= rate.freeOverCents\n ? 0\n : Math.max(0, Math.round(rate.amountCents ?? 0))\n break\n case 'price_tiers':\n amountCents = tierAmount(rate.tiers, cart.subtotalCents)\n break\n case 'weight_tiers':\n amountCents = tierAmount(rate.tiers, cart.totalGrams ?? 0)\n break\n }\n if (amountCents == null) continue\n resolved.push({ rateId: rate.id, name: rate.name, amountCents })\n }\n if (settings.localPickup) {\n resolved.push({\n rateId: LOCAL_PICKUP_RATE_ID,\n name: 'Local pickup',\n amountCents: 0,\n })\n }\n return resolved.sort((a, b) => a.amountCents - b.amountCents)\n}\n\n/**\n * The resolved options that actually carry a parcel (AGL-2325).\n *\n * Safe to apply AFTER `MAX_CHECKOUT_SHIPPING_OPTIONS` truncation: pickup is\n * 0¢ and sorts first, so it occupies at most one of the five slots and a\n * merchant with any shippable rate at all keeps at least one of them.\n */\nfunction shippableOnly(\n options: readonly ResolvedShippingRate[],\n): ResolvedShippingRate[] {\n return options.filter((option) => option.rateId !== LOCAL_PICKUP_RATE_ID)\n}\n\n/** Stripe Checkout accepts at most 5 `shipping_options` on one session. */\nexport const MAX_CHECKOUT_SHIPPING_OPTIONS = 5\n\n/**\n * Destinations a storefront Checkout Session collects an address for, and\n * therefore the destinations shipping rates are resolved against (AGL-1707).\n *\n * NOT narrowed to the zones the merchant configured: narrowing would block\n * checkouts that complete today, turning a money fix into lost sales. The\n * wider list only means a shopper outside the merchant's zones is offered some\n * rate rather than none. Shared by cart checkout and buy-now (AGL-1720) so the\n * two paths cannot drift into offering different destinations.\n */\nexport const CHECKOUT_SHIPPING_COUNTRIES = [\n 'US',\n 'CA',\n 'GB',\n 'AU',\n 'DE',\n 'FR',\n] as const\n\n/**\n * The rates to declare as `shipping_options` on a Stripe Checkout Session\n * (AGL-1707), unioned over `destinationCountries`. Stripe charges shipping\n * ONLY when the session declares them.\n *\n * A UNION IS ONLY HONEST OVER DESTINATIONS THE SESSION IS ALSO RESTRICTED TO.\n * Called with every collectable country while the session accepted an address\n * in any of them — which is what AGL-1707 shipped — it offers a shopper in one\n * zone a rate belonging to another, and Stripe applies whichever the shopper\n * picks (a `shipping_rate_data` carries no country of its own, so nothing\n * downstream re-checks it against the address). That is AGL-1721. Callers now\n * reach this through `planCheckoutShipping`, which pairs the country list it\n * unions over with the country list the session allows, so the two cannot\n * disagree. Do not call it directly from a handler.\n *\n * Returns `[]` for a merchant who has configured nothing, and the caller must\n * then declare no `shipping_options` at all rather than an empty array — a\n * merchant who never set shipping up keeps a session identical to today's.\n */\nexport function resolveCheckoutShippingOptions(\n settings: ShippingSettings | undefined,\n destinationCountries: readonly string[],\n cart: { subtotalCents: number; totalGrams?: number },\n): ResolvedShippingRate[] {\n if (!settings) return []\n const byRateId = new Map<string, ResolvedShippingRate>()\n for (const country of destinationCountries) {\n for (const rate of resolveShippingRates(settings, country, cart)) {\n // Stripe requires a display name, and a rate id is the dedupe key —\n // the console lets a merchant add a blank row, so neither is assured.\n if (!rate.rateId || !rate.name) continue\n const amountCents = Math.max(0, Math.round(Number(rate.amountCents) || 0))\n const existing = byRateId.get(rate.rateId)\n // One rate resolving differently for two countries should not be\n // possible (a zone selects a rate, it does not reprice one), but if it\n // ever is, keep the dearer. Under-charging is the defect being fixed.\n if (!existing || amountCents > existing.amountCents) {\n byRateId.set(rate.rateId, { ...rate, amountCents })\n }\n }\n }\n return (\n [...byRateId.values()]\n // Cheapest first, id as a tie-break so the emitted params are stable.\n .sort(\n (a, b) =>\n a.amountCents - b.amountCents || a.rateId.localeCompare(b.rateId),\n )\n // Past Stripe's cap the dearest are dropped, which is the harmless end\n // to lose: a shopper offered the cheap options would have taken one.\n .slice(0, MAX_CHECKOUT_SHIPPING_OPTIONS)\n )\n}\n\n/** Shopper-facing names for the collectable destinations (AGL-1721). */\nexport const CHECKOUT_SHIPPING_COUNTRY_NAMES: Readonly<Record<string, string>> =\n {\n US: 'United States',\n CA: 'Canada',\n GB: 'United Kingdom',\n AU: 'Australia',\n DE: 'Germany',\n FR: 'France',\n }\n\n/**\n * A destination a shopper declared, or `undefined` for anything this session\n * could not collect an address for anyway. Never throws: an unknown code is\n * an undeclared destination, not an error, so a stale storefront that posts\n * one is answered by the plan below rather than by a 400 nobody can act on.\n */\nexport function normalizeCheckoutShippingCountry(\n value: unknown,\n): string | undefined {\n // `typeof` rather than `String(value)`: a JSON body is caller-shaped, and\n // `String(['US'])` is 'US'. Coercing would let an array declare a\n // destination, which is not a spelling any storefront sends.\n if (typeof value !== 'string') return undefined\n const code = value.trim().toUpperCase()\n return (CHECKOUT_SHIPPING_COUNTRIES as readonly string[]).includes(code)\n ? code\n : undefined\n}\n\nexport interface CheckoutShippingPlan {\n /** `shipping_address_collection[allowed_countries]` for this session. */\n countries: readonly string[]\n /** `shipping_options` for this session — valid for EVERY `countries` entry. */\n options: ResolvedShippingRate[]\n /**\n * Set when no session may be created at all:\n *\n * - `destination-required` — the merchant's rates differ by destination, so\n * there is no set of options honest for every address Stripe would accept.\n * Ask the shopper where they are shipping and plan again.\n * - `destination-unserved` — the merchant ships somewhere, but not there.\n * - `cart-unpriceable` — the merchant priced shipping, but no rate of theirs\n * resolves for THIS cart at ANY destination (AGL-2232). A tier table that\n * stops at 2 kg says nothing about a 3 kg parcel, and the honest answer is\n * to refuse rather than to ship it for nothing.\n */\n refusal?: 'destination-required' | 'destination-unserved' | 'cart-unpriceable'\n}\n\n/**\n * Whether this merchant prices shipping AT ALL (AGL-2232).\n *\n * A pure question about the SETTINGS, deliberately taking no cart, and that is\n * the whole point of it existing. `planCheckoutShipping` used to ask \"does any\n * rate resolve for any destination?\" and pass the live cart into the probe, so\n * a cart that exhausted every tier made the probe empty too — and an empty\n * probe reads as \"this merchant never set shipping up\", the one case that must\n * complete with no `shipping_options` and nothing charged. A 3 kg order at a\n * store whose weight tiers stop at 2 kg therefore shipped free, silently, on\n * every one of the three doors.\n *\n * Answered from the stored zones and rates instead: a rate bound to a zone\n * that exists, or local pickup, means the merchant made a shipping decision\n * and a cart their table cannot price is a REFUSAL. A merchant with no zones,\n * no rates and no pickup has made no such decision, and their session stays\n * byte-identical to the one AGL-1707 shipped.\n */\nexport function merchantPricesShipping(\n settings: ShippingSettings | undefined,\n): boolean {\n if (!settings) return false\n if (settings.localPickup) return true\n const zoneIds = new Set((settings.zones ?? []).map((zone) => zone.id))\n // A rate whose `zoneId` names no zone is unreachable by every resolver here,\n // so it is not evidence of a decision — counting it would refuse carts at a\n // store with nothing but orphaned rows.\n return (settings.rates ?? []).some((rate) => zoneIds.has(rate.zoneId))\n}\n\n/**\n * What a shopper is told when `cart-unpriceable` refuses (AGL-2232).\n *\n * One string, shared by all three doors, because the three used to phrase the\n * two existing refusals identically and drifting here would make the same\n * store say different things depending on which button was pressed. It names\n * the cart rather than the destination on purpose — a `Ship to` select cannot\n * fix a parcel no tier covers, so the refusal deliberately does NOT set\n * `needsShippingCountry`.\n */\nexport const CART_UNPRICEABLE_SHIPPING_MESSAGE =\n 'This store cannot price shipping for this order — it falls outside every ' +\n 'shipping rate the store has set up. Try removing an item, or contact the ' +\n 'store.'\n\n/** Identity of a resolved list, for comparing two destinations' offers. */\nfunction optionsKey(options: readonly ResolvedShippingRate[]): string {\n return options\n .map((option) => `${option.rateId}:${option.amountCents}`)\n .join('|')\n}\n\n/**\n * The whole shipping half of a Checkout Session: which destinations it may\n * accept an address for, and which rates it may charge (AGL-1721).\n *\n * THE INVARIANT IS THAT EVERY RETURNED OPTION IS VALID FOR EVERY RETURNED\n * COUNTRY. Stripe offers a session's `shipping_options` to whoever reaches the\n * page and charges whichever the shopper picks — it does not filter them by\n * the address entered, and there is no field on a `shipping_rate_data` that\n * would let it. So the ONLY place a zone can be enforced is here, by choosing\n * the two lists together: narrowing the allowed countries to the declared\n * destination is what makes the rates offered for it unpickable by anyone\n * else. Filtering the rate list alone would leave a session that still accepts\n * a French address against a US rate.\n *\n * Three shapes come out of it:\n *\n * 1. A merchant whose rates resolve the SAME for every collectable country —\n * one zone, a single '*' zone, or none at all — needs no destination and\n * keeps the session AGL-1707 shipped, byte for byte. The issue notes this\n * is the common configuration, and it is the one that must not regress.\n * 2. A declared destination resolves exactly, and the session is restricted\n * to it. A caller may not skip the restriction: the country arrives in a\n * request body a shopper can craft, so a session that took the country's\n * cheap rate while still accepting any address would hand that shopper\n * the defect on purpose.\n * 3. Otherwise the caller must refuse — see `refusal`. Refusing is not lost\n * revenue in either case: with rates that differ by zone there is no\n * correct amount to charge without knowing where the parcel is going, and\n * the union AGL-1707 shipped chose the wrong one silently.\n *\n * `cart.subtotalCents` is the PRE-discount items total, matching what the cart\n * displays, so a free-over threshold means what the shopper saw it mean.\n */\nexport function planCheckoutShipping(\n settings: ShippingSettings | undefined,\n cart: { subtotalCents: number; totalGrams?: number },\n destinationCountry?: unknown,\n): CheckoutShippingPlan {\n const countries = CHECKOUT_SHIPPING_COUNTRIES as readonly string[]\n const destination = normalizeCheckoutShippingCountry(destinationCountry)\n if (destination) {\n const options = resolveCheckoutShippingOptions(\n settings,\n [destination],\n cart,\n )\n // REFUSAL IS DECIDED ON SHIPPABLE RATES, PICKUP IS OFFERED AFTERWARDS\n // (AGL-2325). `resolveShippingRates` appends pickup independent of zone\n // matching, so a merchant who turned it on had a non-empty list for every\n // destination on earth and this branch returned before it could refuse\n // anyone: a shopper in France picked `Local pickup — Free` on a physical\n // order from a US-only store, Stripe collected their French address\n // because the session still allowed it, and the merchant was paid nothing\n // to carry the parcel there. Pickup is collection, not delivery, so it\n // cannot answer \"do you ship to France\".\n //\n // `shipsElsewhere` is the same question the old probe asked, narrowed to\n // shippable rates, and it keeps the same two-way fork: a merchant who\n // configured NO shipping is not refusing anyone, so that store keeps\n // completing exactly as it does today, while a merchant who ships\n // elsewhere but not here is refusing and saying so is the honest answer.\n // A merchant who ships NOWHERE is untouched by this: pickup-only is a\n // real configuration — they deliver to no one and refuse no one — and it\n // falls through to the offer below exactly as it did.\n const shipsElsewhere = countries.some(\n (country) =>\n shippableOnly(resolveCheckoutShippingOptions(settings, [country], cart))\n .length > 0,\n )\n if (shippableOnly(options).length === 0 && shipsElsewhere) {\n return { countries, options: [], refusal: 'destination-unserved' }\n }\n if (options.length > 0) return { countries: [destination], options }\n // NOTHING resolves anywhere for this cart, and the two reasons that can be\n // true of are opposite (AGL-2232). Asked of the SETTINGS rather than of\n // this cart, because the probe above cannot tell them apart: a merchant\n // who priced shipping and whose table simply does not reach this order is\n // refusing, and used to be handed the \"never set shipping up\" branch.\n return merchantPricesShipping(settings)\n ? { countries, options: [], refusal: 'cart-unpriceable' }\n : { countries, options: [] }\n }\n const offers = new Set(\n countries.map((country) =>\n optionsKey(resolveCheckoutShippingOptions(settings, [country], cart)),\n ),\n )\n // Compared as EMITTED — capped and sanitized — because that is the list a\n // shopper can pick from. Two destinations whose rates differ only past\n // Stripe's cap still offer the same five, and offering them is honest.\n if (offers.size > 1) {\n return { countries, options: [], refusal: 'destination-required' }\n }\n const union = resolveCheckoutShippingOptions(settings, countries, cart)\n // Every destination agrees, and what they agree on is NOTHING. The same\n // fork as the declared-destination branch above (AGL-2232): a store with no\n // shipping settings completes untouched, a store whose rates cannot reach\n // this cart refuses instead of carrying the parcel for free.\n if (union.length === 0 && merchantPricesShipping(settings)) {\n return { countries, options: [], refusal: 'cart-unpriceable' }\n }\n return { countries, options: union }\n}\n\n/**\n * A cart chosen so that every rate a merchant could have written resolves if\n * it can resolve at all (AGL-1791). The settings page has no cart, and two of\n * the four rate kinds price against one: `tierAmount` takes the first tier\n * whose `upTo` is at least the value, so a zero subtotal and zero weight clear\n * every tier a merchant would write, and a `free_over` rate resolves at any\n * subtotal.\n *\n * That makes a coverage answer a LOWER BOUND on the gaps. A destination\n * reported unserved is unserved for every cart; a destination reported served\n * may still be refused for a cart dearer or heavier than the merchant's last\n * tier. Erring in this direction is the deliberate half: the console must not\n * warn a merchant whose settings are fine.\n */\nconst COVERAGE_PROBE_CART = { subtotalCents: 0, totalGrams: 0 }\n\n/** What a merchant's saved zones and rates cost their shoppers (AGL-1791). */\nexport interface ShippingCoverage {\n /** Collectable destinations at least one rate reaches. */\n served: string[]\n /**\n * Collectable destinations CHECKOUT REFUSES — `destination-unserved`.\n *\n * EMPTY FOR A MERCHANT WHOSE RATES REACH NOWHERE, who is not misconfigured:\n * `planCheckoutShipping` refuses nobody when no rate resolves anywhere, so\n * that store charges no shipping and completes exactly as it always has.\n * The rule lives here rather than in the caller because reading `served`\n * against a bare partition is how a surface comes to warn every store that\n * does not ship.\n */\n unserved: string[]\n /** No rate reaches anywhere: no shipping is charged, and nobody refused. */\n shipsNowhere: boolean\n /**\n * Rates differ by destination, so the storefront asks the shopper where the\n * parcel is going before it can price one — a checkout step the merchant\n * added by saving these zones, and never chose.\n */\n asksDestination: boolean\n /** Some zone already claims rest of world, so `*` is not the missing piece. */\n hasRestOfWorldZone: boolean\n /**\n * The merchant offers local pickup, so checkout presents a free collection\n * choice at every destination it does not refuse (AGL-2325).\n *\n * Deliberately NOT folded into `served`: pickup resolves for every country\n * because it is appended independent of zone matching, so counting it as\n * coverage told a US-only merchant who had switched it on that checkout\n * \"can price shipping to every destination\", which is the sentence that\n * hid the defect. It is reported alongside instead, so the card can say\n * both true things: these destinations are refused, and pickup is offered\n * to the ones that are not.\n */\n offersLocalPickup: boolean\n}\n\n/**\n * Which of the collectable destinations a merchant's settings actually cover\n * (AGL-1791), for a console surface to show them.\n *\n * Measured against `CHECKOUT_SHIPPING_COUNTRIES` and nothing wider: those six\n * are the only destinations a storefront session collects an address for, so\n * they are the only ones a merchant can lose an order to. Counting coverage\n * against every country on earth would report a gap for destinations no\n * shopper can reach checkout from.\n *\n * Answered through `resolveCheckoutShippingOptions` — the same function the\n * session is built from — so a row the console allows but Stripe would reject\n * (blank id, blank name) counts as the nothing it resolves to, and a specific\n * zone with no rates still hides a `*` zone here exactly as it does at\n * checkout.\n */\nexport function summarizeShippingCoverage(\n settings: ShippingSettings | undefined,\n): ShippingCoverage {\n const served: string[] = []\n const unserved: string[] = []\n const offers = new Set<string>()\n for (const country of CHECKOUT_SHIPPING_COUNTRIES) {\n const options = resolveCheckoutShippingOptions(\n settings,\n [country],\n COVERAGE_PROBE_CART,\n )\n // `asksDestination` is asked of the FULL list — pickup is a real option a\n // shopper picks, so a merchant whose US destination offers a rate plus\n // pickup while France offers only pickup genuinely does make checkout ask.\n offers.add(optionsKey(options))\n // `served` is asked of the SHIPPABLE list, so that it answers the same\n // question `planCheckoutShipping` refuses on (AGL-2325).\n ;(shippableOnly(options).length > 0 ? served : unserved).push(country)\n }\n return {\n served,\n unserved: served.length > 0 ? unserved : [],\n shipsNowhere: served.length === 0,\n asksDestination: offers.size > 1,\n offersLocalPickup: Boolean(settings?.localPickup),\n hasRestOfWorldZone: (settings?.zones ?? []).some((zone) =>\n zone.countries.some((code) => code === '*'),\n ),\n }\n}\n\n/**\n * Emit `shipping_address_collection[allowed_countries][n]` onto a session's\n * form body. Stripe will not apply a `shipping_options` rate without an\n * address to ship to, so the two always travel together — and the countries\n * are the OTHER half of what makes a rate honest (AGL-1721), so pass the list\n * `planCheckoutShipping` returned rather than defaulting it beside a rate list\n * resolved for something narrower.\n */\nexport function appendShippingAddressCollectionParams(\n params: URLSearchParams,\n countries: readonly string[] = CHECKOUT_SHIPPING_COUNTRIES,\n): void {\n countries.forEach((code, index) => {\n params.set(`shipping_address_collection[allowed_countries][${index}]`, code)\n })\n}\n\n/**\n * Emit resolved rates as `shipping_options` on a Checkout Session's form body.\n *\n * THIS IS THE ONLY THING THAT MAKES STRIPE CHARGE SHIPPING. Without these keys\n * Stripe presents no shipping choice and `total_details.amount_shipping` is 0\n * however many zones and rates the merchant saved (AGL-1707).\n *\n * An empty list emits NOTHING — not an empty array — so a merchant who\n * configured no shipping keeps a session byte-identical to the one built\n * before shipping was wired at all. That guarantee lives here rather than in\n * each caller, so neither checkout path can lose it independently (AGL-1720).\n */\nexport function appendCheckoutShippingParams(\n params: URLSearchParams,\n options: readonly ResolvedShippingRate[],\n): void {\n options.forEach((option, index) => {\n const field = `shipping_options[${index}][shipping_rate_data]`\n params.set(`${field}[type]`, 'fixed_amount')\n params.set(`${field}[display_name]`, option.name.slice(0, 100))\n params.set(`${field}[fixed_amount][amount]`, String(option.amountCents))\n params.set(`${field}[fixed_amount][currency]`, 'usd')\n })\n}\n"],"names":["LOCAL_PICKUP_RATE_ID","zoneCode","code","String","trim","toUpperCase","isWildcard","zoneMatches","zone","country","countries","some","tierAmount","tiers","value","sorted","sort","a","b","upTo","tier","amountCents","resolveShippingRates","settings","destinationCountry","cart","zones","specific","filter","matched","length","zoneIds","Set","map","id","resolved","rate","rates","has","zoneId","kind","Math","max","round","freeOverCents","subtotalCents","totalGrams","push","rateId","name","localPickup","shippableOnly","options","option","MAX_CHECKOUT_SHIPPING_OPTIONS","CHECKOUT_SHIPPING_COUNTRIES","resolveCheckoutShippingOptions","destinationCountries","byRateId","Map","Number","existing","get","set","values","localeCompare","slice","CHECKOUT_SHIPPING_COUNTRY_NAMES","US","CA","GB","AU","DE","FR","normalizeCheckoutShippingCountry","undefined","includes","merchantPricesShipping","CART_UNPRICEABLE_SHIPPING_MESSAGE","optionsKey","join","planCheckoutShipping","destination","shipsElsewhere","refusal","offers","size","union","COVERAGE_PROBE_CART","summarizeShippingCoverage","served","unserved","add","shipsNowhere","asksDestination","offersLocalPickup","Boolean","hasRestOfWorldZone","appendShippingAddressCollectionParams","params","forEach","index","appendCheckoutShippingParams","field"],"mappings":"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"}