@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,706 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import * as Aglyn from "@aglyn/aglyn/server";
18
+ import * as CommerceModel from "../model/index.js";
19
+ import { firebaseAdmin, getOrgForHost } from "@aglyn/tenant-data-admin";
20
+ import { connectLinkageIsReady } from "@aglyn/tenant-data-admin/server/stripe-account-mode";
21
+ import { resolveManualTaxRateId } from "./manual-tax-rate.js";
22
+ import { holdPromotionSlot, promotionHoldKey } from "./promotion-hold.js";
23
+ import { buildRoute, claimAttempt, Route } from "@aglyn/aglyn/server";
24
+ /**
25
+ * Draft orders (AGL-287, Shopify parity): a manager builds an order in
26
+ * the console and sends the buyer a payment link. Creates the order doc
27
+ * (status `pending`, channel `draft`) with a sequential number, then a
28
+ * Stripe Checkout session on the merchant's connected account whose
29
+ * webhook completion flips the SAME doc to `paid`
30
+ * (metadata type `commerce-draft`).
31
+ */ export const draftOrderHandler = async (req, res)=>{
32
+ var _req_headers_authorization, _req_body, _body_hostId, _body_productId, _body_variantId, _body_quantity, _body_email, _body_couponCode, _ref, _req_headers_idempotencykey;
33
+ if (req.method !== 'POST') {
34
+ return res.status(405).json({
35
+ error: 'Method not allowed'
36
+ });
37
+ }
38
+ if (!process.env.STRIPE_SECRET_KEY) {
39
+ return res.status(501).json({
40
+ error: 'Payments are not configured.'
41
+ });
42
+ }
43
+ const authorization = String((_req_headers_authorization = req.headers.authorization) != null ? _req_headers_authorization : '');
44
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
45
+ if (!idToken) return res.status(401).json({
46
+ error: 'Unauthenticated'
47
+ });
48
+ const body = typeof req.body === 'string' ? JSON.parse(req.body) : (_req_body = req.body) != null ? _req_body : {};
49
+ const hostId = String((_body_hostId = body.hostId) != null ? _body_hostId : '');
50
+ const productId = String((_body_productId = body.productId) != null ? _body_productId : '');
51
+ const variantId = String((_body_variantId = body.variantId) != null ? _body_variantId : '');
52
+ const quantity = Math.max(1, Math.min(99, Math.round(Number((_body_quantity = body.quantity) != null ? _body_quantity : 1))));
53
+ const email = String((_body_email = body.email) != null ? _body_email : '').trim();
54
+ // A code the MERCHANT types while composing the order (AGL-305). The
55
+ // storefront doors read this same field name, so one resolver answers it the
56
+ // same way whoever pressed the button.
57
+ const couponCode = String((_body_couponCode = body.couponCode) != null ? _body_couponCode : '').trim();
58
+ // One draft attempt, minted by the console dialog (AGL-1697). Node
59
+ // lowercases incoming headers, but read both spellings — the plugin API
60
+ // request type makes no promise about casing.
61
+ const idempotencyKey = String((_ref = (_req_headers_idempotencykey = req.headers['idempotency-key']) != null ? _req_headers_idempotencykey : req.headers['Idempotency-Key']) != null ? _ref : '').trim().slice(0, 200);
62
+ if (!hostId || !productId) {
63
+ return res.status(400).json({
64
+ error: 'Missing hostId or productId'
65
+ });
66
+ }
67
+ let claim = null;
68
+ /**
69
+ * The redemption slot this attempt reserved (AGL-305), hoisted so every
70
+ * refusal below the claim — and the catch — can hand it back. A throw after
71
+ * the hold is placed is exactly the case where a slot would otherwise stand
72
+ * invisibly against the merchant's cap until its TTL lapsed, and this path
73
+ * rolls its order document back on two of those refusals already.
74
+ */ let discountSlot = null;
75
+ let discountHoldKey = '';
76
+ const releaseDiscountSlot = async ()=>{
77
+ const slot = discountSlot;
78
+ discountSlot = null;
79
+ discountHoldKey = '';
80
+ if (slot) await slot.release();
81
+ };
82
+ try {
83
+ var _hostSnapshot_get, _req_headers_origin, _storeSettings_get, _taxSettings_origin, _product_type, _variant_weightGrams, _product_type1, _ref1;
84
+ var _ownerOrg_org, _ownerOrg_org1, _product_variants_, _ownerOrg_org2;
85
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
86
+ const firestore = firebaseAdmin.app().firestore();
87
+ const hostRef = firestore.collection('hosts').doc(hostId);
88
+ const hostSnapshot = await hostRef.get();
89
+ if (!hostSnapshot.exists) {
90
+ return res.status(404).json({
91
+ error: 'Unknown site'
92
+ });
93
+ }
94
+ // AN ALLOWLIST (AGL-2262), matching `cancel-order.ts`, `fulfill-order.ts`
95
+ // and the Firestore rules, whose host-write predicate is
96
+ // `hostMemberRole(hostId) in ['admin','editor']`. The old
97
+ // `!role || role === 'viewer'` denylist caught the stranger but admitted
98
+ // every OTHER string — a legacy value, a typo, any role added later — on
99
+ // the one route that mints a live Stripe payment link. `HostAccessRole`
100
+ // has since grown an `author` (AGL-2334), which this allowlist refuses on
101
+ // purpose — an author edits content and does not mint payment links — and
102
+ // which the old denylist would have admitted. That is the allowlist form
103
+ // earning its keep on a union that changed under it.
104
+ const memberRole = ((_hostSnapshot_get = hostSnapshot.get('memberRoles')) != null ? _hostSnapshot_get : {})[decoded.uid];
105
+ if (memberRole !== 'admin' && memberRole !== 'editor') {
106
+ return res.status(403).json({
107
+ error: 'Not permitted'
108
+ });
109
+ }
110
+ const productSnapshot = await hostRef.collection('products').doc(productId).get();
111
+ const raw = productSnapshot.data();
112
+ if (!raw || raw.deletedAt) {
113
+ return res.status(404).json({
114
+ error: 'Unknown product'
115
+ });
116
+ }
117
+ const product = CommerceModel.liftLegacyProduct(raw);
118
+ const variant = variantId ? product.variants.find((item)=>item.id === variantId) : product.variants[0];
119
+ if (!variant) return res.status(404).json({
120
+ error: 'Unknown variant'
121
+ });
122
+ // A variant with no price yet (AGL-2916) cannot be invoiced: the link
123
+ // would ask for nothing, or for no amount at all.
124
+ if (!CommerceModel.variantHasPrice(variant)) {
125
+ return res.status(400).json({
126
+ error: `Set a price for ${product.name} before selling it.`
127
+ });
128
+ }
129
+ // Merchant account like the storefront checkout (AGL-284).
130
+ const ownerOrg = await getOrgForHost(hostId);
131
+ // Plan gate, re-asked per request exactly as the storefront checkout
132
+ // asks it (AGL-1873, the AGL-481 pattern): a free or lapsed org must not
133
+ // keep minting payment links — at the free plan's 0% transaction fee —
134
+ // through the one commerce door that skipped the entitlement. Sits
135
+ // ABOVE the attempt claim with the other deterministic refusals, so it
136
+ // never burns the merchant's idempotency key.
137
+ if (!Aglyn.checkEntitlement(ownerOrg == null ? void 0 : ownerOrg.org, 'commerce')) {
138
+ return res.status(403).json({
139
+ error: 'Selling is not enabled'
140
+ });
141
+ }
142
+ const ownerId = ownerOrg == null ? void 0 : (_ownerOrg_org = ownerOrg.org) == null ? void 0 : _ownerOrg_org.ownerUid;
143
+ const ownerProfile = ownerId ? await firestore.collection('profiles').doc(String(ownerId)).get() : null;
144
+ const accountId = ownerProfile == null ? void 0 : ownerProfile.get('stripeAccountId');
145
+ if (!connectLinkageIsReady({
146
+ accountId,
147
+ chargesEnabled: ownerProfile == null ? void 0 : ownerProfile.get('stripeChargesEnabled'),
148
+ accountLivemode: ownerProfile == null ? void 0 : ownerProfile.get('stripeAccountLivemode')
149
+ }, {
150
+ subject: `draft order host ${hostId}`
151
+ })) {
152
+ return res.status(409).json({
153
+ error: 'Payments are not set up yet'
154
+ });
155
+ }
156
+ // Stripe returns the merchant to the console Products page. This was
157
+ // `/{hostDocId}/products`, the pre-AGL-621/622 shape, so paying (or
158
+ // cancelling) a draft order landed on a 404 (AGL-685). Console products
159
+ // is the plugin route keyed by org slug + host SUBDOMAIN; server code
160
+ // cannot call useConsoleHostRoute, so resolve them here. Without both,
161
+ // fall back to the origin root rather than a fabricated dead path.
162
+ const consoleSubdomain = (await firestore.collection('hostIndex').doc(hostId).get()).get('subdomain');
163
+ const consoleOrgSlug = ownerOrg == null ? void 0 : (_ownerOrg_org1 = ownerOrg.org) == null ? void 0 : _ownerOrg_org1.slug;
164
+ const origin = (_req_headers_origin = req.headers.origin) != null ? _req_headers_origin : `https://${req.headers.host}`;
165
+ const consoleProductsUrl = consoleOrgSlug && consoleSubdomain ? `${origin}${buildRoute(Route.HOST_PLUGIN, {
166
+ orgSlug: consoleOrgSlug,
167
+ host: consoleSubdomain,
168
+ pluginSlug: 'products'
169
+ })}` : origin;
170
+ // WHAT THE COUNT SAYS, said out loud (AGL-2452).
171
+ //
172
+ // This handler contained no `canPurchase` and no `stockShortfall` — no
173
+ // reference to inventory of any kind. It is the door that mints a LIVE,
174
+ // payable Stripe link, and it would mint one for a sold-out variant whose
175
+ // merchant had chosen `oversellPolicy: 'deny'`, with the `commerce-draft`
176
+ // webhook branch then completing it into a `paid` order. `pos-order.ts`'s
177
+ // own comment asserts "every storefront door gates on it"; that claim was
178
+ // false for this one.
179
+ //
180
+ // WARN, NEVER BLOCK, matching the register (AGL-2357, the decision).
181
+ // Both of these are MERCHANT-initiated doors rather than shopper-initiated
182
+ // ones — the merchant may well be taking a deliberate pre-order or
183
+ // backorder — so a stale count must not refuse a sale the merchant means to
184
+ // make. What the merchant is entitled to is to be TOLD, which is the part
185
+ // that was missing entirely. The refusal variant is a separate decision and
186
+ // is not taken here.
187
+ //
188
+ // Computed from the SERVER's product document, and reported on the same
189
+ // `stockWarnings` key and in the same `StockShortfall` shape the register
190
+ // already returns, so one console surface can read either door.
191
+ const shortfall = CommerceModel.stockShortfall(product, variantId || ((_product_variants_ = product.variants[0]) == null ? void 0 : _product_variants_.id), quantity);
192
+ const stockWarnings = shortfall ? [
193
+ _extends({
194
+ productId
195
+ }, variantId ? {
196
+ variantId
197
+ } : {}, {
198
+ name: product.name,
199
+ requested: quantity,
200
+ available: shortfall.available
201
+ })
202
+ ] : [];
203
+ const unitAmountCents = Math.round(Number(variant.priceUsd) * 100);
204
+ const lineItems = [
205
+ _extends({
206
+ productId
207
+ }, variantId ? {
208
+ variantId
209
+ } : {}, {
210
+ name: product.name
211
+ }, variant.sku ? {
212
+ sku: variant.sku
213
+ } : {}, {
214
+ productType: product.type,
215
+ quantity,
216
+ unitAmountCents
217
+ })
218
+ ];
219
+ const itemsCents = unitAmountCents * quantity;
220
+ // THE DISCOUNTS HUB, ON THIS PATH TOO (AGL-305).
221
+ //
222
+ // `hosts/{hostId}/discounts` reached the cart and buy-now and stopped
223
+ // there, so a store running "Summer sale, 10% off" sold at 10% off through
224
+ // both storefront doors and at FULL price the moment the merchant invoiced
225
+ // the same buyer for the same goods through a payment link. No code has to
226
+ // be typed for that gap to open: an automatic promotion applies itself on
227
+ // the storefront and applied itself nowhere here, so the merchant's own
228
+ // payment link quietly undercut — and here overcharged against — their own
229
+ // advertised price.
230
+ //
231
+ // Resolved through the SAME `resolveDiscount` the other doors use, so one
232
+ // code cannot mean two amounts.
233
+ //
234
+ // RESOLVED BEFORE THE TAX BLOCK BELOW, and that ordering is the whole
235
+ // point rather than a convenience: the manual rate is computed against
236
+ // `chargedItemsCents`, so the discount lands BEFORE tax and the taxable
237
+ // base is the discounted one. It has to be — the session applies that same
238
+ // rate as `line_items[0][tax_rates][0]`, which Stripe evaluates against the
239
+ // line amount it actually charges. Reducing the line while taxing the list
240
+ // price would make our stored `taxCents` disagree with the tax Stripe
241
+ // collects, on every discounted draft.
242
+ const draftDiscountLines = [
243
+ {
244
+ productId,
245
+ amountCents: itemsCents
246
+ }
247
+ ];
248
+ const hubDiscounts = await hostRef.collection('discounts').limit(100).get();
249
+ const resolvedDiscount = CommerceModel.resolveDiscount(hubDiscounts.docs.map((docSnapshot)=>_extends({}, docSnapshot.data(), {
250
+ $id: docSnapshot.id
251
+ })), _extends({}, couponCode ? {
252
+ code: couponCode
253
+ } : {}, {
254
+ subtotalCents: itemsCents,
255
+ productIds: [
256
+ productId
257
+ ],
258
+ lines: draftDiscountLines
259
+ }));
260
+ // Above the claim and above the order write with every other deterministic
261
+ // refusal, so a merchant who fixes the code and presses Send again strands
262
+ // no `pending` draft and burns no key. A code that RESOLVES but confers
263
+ // nothing leaves through here too — `codeProblem` carries the benefit's own
264
+ // reason — which is what stops this door repeating the defect that charged
265
+ // full shipping on a free-shipping code.
266
+ if (resolvedDiscount == null ? void 0 : resolvedDiscount.codeProblem) {
267
+ return res.status(400).json({
268
+ error: resolvedDiscount.codeProblem
269
+ });
270
+ }
271
+ const appliedDiscountId = resolvedDiscount && resolvedDiscount.benefit.kind !== 'none' ? resolvedDiscount.discountId : '';
272
+ const discountCents = appliedDiscountId ? resolvedDiscount.discountCents : 0;
273
+ // Stripe's charge minimum is 50¢ — never price a payment link below it,
274
+ // the same floor buy-now applies.
275
+ const chargedItemsCents = discountCents ? Math.max(50, itemsCents - discountCents) : itemsCents;
276
+ // What was ACTUALLY taken off, after that floor. The stored totals record
277
+ // this rather than the resolver's figure, so the parts sum to the total on
278
+ // a draft the floor moved.
279
+ const appliedDiscountCents = itemsCents - chargedItemsCents;
280
+ // The fee and `totals` are both built BELOW the shipping plan (AGL-2152):
281
+ // Stripe's card cost rides the whole payment-link total, so neither can be
282
+ // known until the tax (AGL-1953) and the shipping options are.
283
+ // Shipping (AGL-1792), from the same settings document the two storefront
284
+ // paths read. This handler contained no `shipping` string at all: a
285
+ // merchant who configured zones and rates collected them on a cart
286
+ // (AGL-1707) and on buy-now (AGL-1720), and nothing when they invoiced the
287
+ // same buyer for the same parcel through a payment link. The session
288
+ // collected no address either, so the merchant was not even told where to
289
+ // send it — the webhook records one now that Stripe is asked for it.
290
+ //
291
+ // The premise AGL-1792 filed this under was that "the destination IS known
292
+ // — the merchant typed it". It is not: the draft dialog collects a product,
293
+ // a variant, a quantity and an email, and this handler reads exactly those.
294
+ // So the destination is as unknown here as it is in the cart, and the same
295
+ // asking machinery applies rather than none of it.
296
+ //
297
+ // CONDITIONAL on the product being physical, exactly as buy-now is: this
298
+ // dialog invoices downloads and consulting too, and charging that buyer
299
+ // postage would be worse than the bug. A missing `type` reads as physical,
300
+ // matching the fee ladder above — the two reads must not disagree about
301
+ // what a part-migrated doc is. The one-time condition buy-now also carries
302
+ // is structural here: this path only ever builds `mode: 'payment'`.
303
+ //
304
+ // RESOLVED BEFORE THE ORDER DOCUMENT, because the plan can refuse and the
305
+ // order is written before Stripe is called. Refusing after it would strand
306
+ // a `pending` draft on the merchant's orders list for every attempt —
307
+ // this path's version of the orphaned coupon AGL-1721 kept out of the cart.
308
+ const storeSettings = await hostRef.collection('settings').doc('store').get();
309
+ const shippingSettings = storeSettings.get('shipping');
310
+ // Taxes (AGL-1953), from the same settings document. This handler had no
311
+ // tax code at all in either mode, so a merchant who invoiced a buyer for
312
+ // the same product they sell on the storefront charged them no tax — the
313
+ // cart's defect, one door over, and worse here because the merchant
314
+ // composed this order deliberately and would reasonably assume it matched
315
+ // their store.
316
+ //
317
+ // Origin-based, exactly as buy-now and the cart resolve it. The AGL-1792
318
+ // note above already established the premise: this dialog collects a
319
+ // product, a variant, a quantity and an email, so the DESTINATION is as
320
+ // unknown here as it is in the cart.
321
+ //
322
+ // Computed pure and BEFORE the claim so the stored totals can carry it;
323
+ // the Stripe object it needs is minted below the point of no return.
324
+ const taxSettings = (_storeSettings_get = storeSettings.get('tax')) != null ? _storeSettings_get : {};
325
+ // AGL-1999: an unset tax mode is NOT a decision, and it must not sell.
326
+ // `mode` was `undefined` for every store whose owner never opened the
327
+ // Taxes card — the default state of every new storefront — and each
328
+ // branch below tested for a specific string, so no branch was taken, no
329
+ // tax was computed, and the shopper was charged an untaxed total. See
330
+ // `commerce-tax-decision.ts` for why refusing beats defaulting to either
331
+ // mode. `mode: 'none'` is the explicit opt-out and passes straight
332
+ // through.
333
+ const taxDecision = CommerceModel.storefrontTaxDecision({
334
+ settings: taxSettings,
335
+ taxExempt: product.taxExempt
336
+ });
337
+ if (taxDecision.kind === 'undecided') {
338
+ return res.status(409).json({
339
+ error: CommerceModel.STOREFRONT_TAX_UNDECIDED_MESSAGE
340
+ });
341
+ }
342
+ const taxMisconfigured = CommerceModel.storefrontTaxMisconfiguration(taxSettings);
343
+ if (taxMisconfigured) {
344
+ // AGL-2145: the merchant DECIDED to collect and the sale would have
345
+ // charged zero anyway — an unfinished settings card, not a
346
+ // jurisdiction miss. Refused in the same words and the same place as
347
+ // the undecided case above.
348
+ return res.status(409).json({
349
+ error: taxMisconfigured
350
+ });
351
+ }
352
+ const useStripeTax = taxDecision.kind === 'stripe-automatic';
353
+ const manualRate = taxDecision.kind === 'manual' && !taxSettings.pricesIncludeTax ? CommerceModel.resolveTaxRate(taxSettings, (_taxSettings_origin = taxSettings.origin) != null ? _taxSettings_origin : {}) : null;
354
+ // THE DISCOUNTED BASE (AGL-305). `chargedItemsCents` is what the line
355
+ // will actually be worth, and the session applies this same rate to that
356
+ // line as a Stripe Tax Rate — so taxing `itemsCents` here would record a
357
+ // figure Stripe never charges.
358
+ const taxCents = manualRate ? CommerceModel.computeTaxCents(chargedItemsCents, manualRate.pct) : 0;
359
+ // Stripe Tax mode leaves this 0 at composition time and the webhook folds
360
+ // the computed figure in — the same additive shape AGL-1792 used for
361
+ // shipping, and for the same reason: only Stripe knows it.
362
+ const shippingPlan = ((_product_type = product.type) != null ? _product_type : 'physical') === 'physical' ? CommerceModel.planCheckoutShipping(shippingSettings, {
363
+ subtotalCents: itemsCents,
364
+ totalGrams: Math.max(0, Number((_variant_weightGrams = variant.weightGrams) != null ? _variant_weightGrams : 0)) * quantity
365
+ }, body.shippingCountry) : {
366
+ countries: CommerceModel.CHECKOUT_SHIPPING_COUNTRIES,
367
+ options: []
368
+ };
369
+ if (shippingPlan.refusal === 'destination-required') {
370
+ return res.status(400).json({
371
+ error: 'Choose where this order ships to.',
372
+ needsShippingCountry: true,
373
+ shippingCountries: [
374
+ ...CommerceModel.CHECKOUT_SHIPPING_COUNTRIES
375
+ ]
376
+ });
377
+ }
378
+ if (shippingPlan.refusal === 'destination-unserved') {
379
+ var _CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_declared;
380
+ const declared = CommerceModel.normalizeCheckoutShippingCountry(body.shippingCountry);
381
+ return res.status(409).json({
382
+ error: `This store does not ship to ${(_CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_declared = CommerceModel.CHECKOUT_SHIPPING_COUNTRY_NAMES[declared]) != null ? _CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_declared : 'that country'}.`,
383
+ needsShippingCountry: true,
384
+ shippingCountries: [
385
+ ...CommerceModel.CHECKOUT_SHIPPING_COUNTRIES
386
+ ]
387
+ });
388
+ }
389
+ // No rate of the merchant's reaches this order (AGL-2232). Above the
390
+ // order write and the payment link, like every other refusal here, so a
391
+ // manager who fixes the tier table and presses Send again strands nothing.
392
+ if (shippingPlan.refusal === 'cart-unpriceable') {
393
+ return res.status(409).json({
394
+ error: CommerceModel.CART_UNPRICEABLE_SHIPPING_MESSAGE
395
+ });
396
+ }
397
+ // FREE SHIPPING IS A ZEROED RATE, NOT A REDUCTION (AGL-305), the same
398
+ // construction the cart uses and for the same reason: nothing has picked a
399
+ // rate yet, so there is no amount to take off. The buyer chooses after the
400
+ // link is minted, so the only exact answer is to offer every rate at zero.
401
+ //
402
+ // Every rate rather than the cheapest, because `free_shipping` carries no
403
+ // field naming one — and zeroing them all keeps the fee, the transfer floor
404
+ // and the ceiling below honest, since all three read these same options.
405
+ //
406
+ // Derived from `shippingPlan.options` and read EVERYWHERE below in its
407
+ // place; a reader that reached past this to `shippingPlan.options` would
408
+ // price carriage the buyer is not being charged for.
409
+ const shippingOptions = (resolvedDiscount == null ? void 0 : resolvedDiscount.freeShipping) === true ? shippingPlan.options.map((option)=>_extends({}, option, {
410
+ amountCents: 0
411
+ })) : shippingPlan.options;
412
+ // THE PLATFORM FEE (AGL-2152) — the advertised take PLUS Stripe's card
413
+ // cost, passed through at cost. A payment link is a destination charge, so
414
+ // Stripe debits 2.9% + 30¢ from the PLATFORM's balance; the old take-only
415
+ // figure meant every tier carrying a 0% rate invoiced a buyer at a loss to
416
+ // Aglyn, and Starter's 2% is below 2.9% so it lost money at every size too.
417
+ //
418
+ // `?? 'physical'` (AGL-2251), matching `checkout.ts` and the cart. Without
419
+ // it a product doc carrying no `type` fell to `resolveTransactionFeePct`'s
420
+ // digital branch, so a merchant's payment link took a different cut of the
421
+ // same product than their storefront did.
422
+ //
423
+ // The base is the whole card total: the goods, the manual tax line, and the DEAREST shipping
424
+ // option the link offers (the buyer picks after the link is minted and
425
+ // `application_fee_amount` is fixed at creation, so reaching for the
426
+ // cheapest would put the difference back on Aglyn). A store on Stripe Tax
427
+ // is the one residual — that tax is computed inside Stripe afterwards.
428
+ const shippingCeilingCents = shippingOptions.reduce((most, option)=>{
429
+ var _option_amountCents;
430
+ return Math.max(most, Math.max(0, Number((_option_amountCents = option.amountCents) != null ? _option_amountCents : 0)));
431
+ }, 0);
432
+ // Both bases are the DISCOUNTED goods (AGL-305). The platform take is a
433
+ // cut of what the merchant actually sells for, and Stripe's card cost is
434
+ // passed through on what the card actually runs for — reading `itemsCents`
435
+ // here would invoice the merchant a fee on money nobody paid.
436
+ const feeCents = Aglyn.resolveTransactionFeeCents(ownerOrg == null ? void 0 : ownerOrg.org, (_product_type1 = product.type) != null ? _product_type1 : 'physical', chargedItemsCents, chargedItemsCents + taxCents + shippingCeilingCents);
437
+ // Stripe Tax mode leaves the tax 0 at composition time and the webhook
438
+ // folds the computed figure in — the same additive shape AGL-1792 used for
439
+ // shipping, and for the same reason: only Stripe knows it.
440
+ const totals = CommerceModel.computeOrderTotals(lineItems, {
441
+ feeCents,
442
+ taxCents,
443
+ // The line item still carries the LIST price, so the discount has to be
444
+ // a named part of the totals or `itemsCents - discountCents + tax` would
445
+ // not be the number on the payment link.
446
+ discountCents: appliedDiscountCents
447
+ });
448
+ // THE LINK CHARGES `chargedItemsCents`, EXACTLY (the AGL-2159 construction,
449
+ // reused here because this path grew the same problem the moment it grew a
450
+ // discount).
451
+ //
452
+ // A Stripe line is `quantity` units at ONE integer `unit_amount`, so it can
453
+ // only express totals divisible by `quantity` — and a percentage discount
454
+ // does not respect that. Dividing and multiplying back misses the intended
455
+ // total by up to `quantity / 2` cents in either direction, which on this
456
+ // path is worse than on buy-now: the frozen `totals` above are written to
457
+ // the order document BEFORE the session is minted, so a link that charged
458
+ // a different number would leave the merchant's own books disagreeing with
459
+ // what their buyer paid, permanently and silently.
460
+ //
461
+ // So when the total does not divide evenly, the line becomes ONE unit at
462
+ // the exact total with the count moved into the display name. The real
463
+ // quantity is carried by the order document's line item, which is
464
+ // untouched, so nothing downstream can tell the difference.
465
+ //
466
+ // The even case — every undiscounted draft, and most discounted ones —
467
+ // keeps the per-unit shape byte for byte.
468
+ const evenUnitAmountCents = Math.floor(chargedItemsCents / quantity);
469
+ const remainderCents = chargedItemsCents - evenUnitAmountCents * quantity;
470
+ const chargedQuantity = remainderCents === 0 ? quantity : 1;
471
+ const chargedUnitAmountCents = remainderCents === 0 ? evenUnitAmountCents : chargedItemsCents;
472
+ const chargedLineName = `${product.name}${remainderCents === 0 ? '' : ` × ${quantity}`}`.slice(0, 120);
473
+ // Point of no return (AGL-1697): everything past here writes an order and
474
+ // mints a live payment link. Every deterministic refusal — unknown
475
+ // product, payments not set up, the shipping-destination ask — sits above
476
+ // this line, so none of them burns the key: the merchant fixes the input
477
+ // and presses the same button. Before the claim, a double-submit minted a
478
+ // SECOND order doc, burned a second sequential number, and returned two
479
+ // live payment links bound to different orders, both payable.
480
+ const claimed = await claimAttempt(firestore, {
481
+ kind: 'commerce-draft',
482
+ scopeId: hostId,
483
+ orgId: String((_ref1 = ownerOrg == null ? void 0 : (_ownerOrg_org2 = ownerOrg.org) == null ? void 0 : _ownerOrg_org2.id) != null ? _ref1 : ''),
484
+ key: idempotencyKey,
485
+ busyMessage: 'This draft order is already being created'
486
+ });
487
+ if ('replay' in claimed) {
488
+ return res.status(claimed.replay.status).json(claimed.replay.body);
489
+ }
490
+ claim = claimed.claim;
491
+ // THE REDEMPTION SLOT IS RESERVED HERE (AGL-305), on the same terms the
492
+ // storefront doors reserve it.
493
+ //
494
+ // A payment link lives until the buyer pays it, so between this handler and
495
+ // the `commerce-draft` webhook branch that settles the slot there is a
496
+ // window measured in days — far wider than a Checkout Session's. Reading
497
+ // `redemptions` and hoping would let a merchant mint ten links against a
498
+ // cap of one and have all ten pay.
499
+ //
500
+ // BELOW the claim because the hold is keyed by the attempt: a retry of one
501
+ // attempt must be able to re-claim the slot it already holds rather than be
502
+ // refused by it. An uncapped promotion writes nothing and returns an empty
503
+ // `holdKey`, which is what tells the webhook to fall back to the plain
504
+ // increment.
505
+ if (appliedDiscountId) {
506
+ const slot = await holdPromotionSlot({
507
+ firestore,
508
+ ref: hostRef.collection('discounts').doc(appliedDiscountId),
509
+ holdKey: promotionHoldKey(claimed.claim.stripeKey),
510
+ label: `draft discount ${appliedDiscountId}`
511
+ });
512
+ if (!slot.ok) {
513
+ // Refused rather than quietly repriced, and that is deliberate for the
514
+ // AUTOMATIC case too: the merchant composed this order at a price the
515
+ // promotion was part of, and minting the link at full price would
516
+ // invoice their buyer more than the store advertises without saying so.
517
+ // Nothing has been written yet, so the key goes back and the retry
518
+ // prices correctly — `resolveDiscount` counts live holds and simply
519
+ // stops offering an exhausted promotion.
520
+ await claim.release();
521
+ return res.status(409).json({
522
+ error: couponCode && (resolvedDiscount == null ? void 0 : resolvedDiscount.discount.code) ? CommerceModel.PROMOTION_EXHAUSTED_MESSAGE : CommerceModel.PROMOTION_UNAVAILABLE_MESSAGE
523
+ });
524
+ }
525
+ if (slot.holdKey) {
526
+ discountSlot = slot;
527
+ discountHoldKey = slot.holdKey;
528
+ }
529
+ }
530
+ // Order doc first (transactional number), then the payment link.
531
+ const orderRef = hostRef.collection('orders').doc();
532
+ const counterRef = hostRef.collection('counters').doc('orders');
533
+ await firestore.runTransaction(async (transaction)=>{
534
+ var _counter_get, _decoded_email;
535
+ const counter = await transaction.get(counterRef);
536
+ const number = Number((_counter_get = counter.get('next')) != null ? _counter_get : 1);
537
+ transaction.set(counterRef, {
538
+ next: number + 1
539
+ }, {
540
+ merge: true
541
+ });
542
+ transaction.set(orderRef, {
543
+ number,
544
+ status: 'pending',
545
+ channel: 'draft',
546
+ lineItems,
547
+ totals,
548
+ // WHICH TAX REGIME THIS ORDER IS COMPOSED UNDER (AGL-2451), from the
549
+ // decision taken above rather than from the frozen `taxCents` — a
550
+ // Stripe Tax draft freezes 0 there and only the paid session knows the
551
+ // figure, so a mode read back off the amount would call it `none`.
552
+ //
553
+ // Stamped at composition so a draft that is never paid still says what
554
+ // it was priced under, and RESTATED by the `commerce-draft` webhook
555
+ // branch from the session that actually charged it. The webhook's is
556
+ // authoritative — it has Stripe's computed tax in hand — and for a
557
+ // manual draft the two agree by construction.
558
+ taxMode: CommerceModel.storefrontTaxModeForDecision(taxDecision, taxCents),
559
+ customerEmail: email || null,
560
+ timeline: [
561
+ {
562
+ atMs: Date.now(),
563
+ event: 'draft',
564
+ detail: `Draft created by ${(_decoded_email = decoded.email) != null ? _decoded_email : decoded.uid}`
565
+ }
566
+ ],
567
+ createdAtMs: Date.now(),
568
+ createdAt: firebaseAdmin.firestore.FieldValue.serverTimestamp()
569
+ });
570
+ });
571
+ // The tax rate is minted here, BELOW the claim, because it creates a real
572
+ // Stripe object (AGL-1953). Cached per host, so it is usually a read.
573
+ let draftTaxRateId = '';
574
+ if (taxCents > 0 && manualRate) {
575
+ var _ref2;
576
+ draftTaxRateId = (_ref2 = await resolveManualTaxRateId(_extends({
577
+ hostRef,
578
+ taxPct: manualRate.pct,
579
+ taxLabel: manualRate.label || `Tax (${manualRate.pct}%)`
580
+ }, claim.stripeKey ? {
581
+ headers: {
582
+ 'Idempotency-Key': `${claim.stripeKey}-tax-rate`
583
+ }
584
+ } : {}))) != null ? _ref2 : '';
585
+ if (!draftTaxRateId) {
586
+ // A VISIBLE refusal rather than an untaxed payment link — the silent
587
+ // under-collection is the defect. The order doc is rolled back the
588
+ // same way the session failure below rolls it back.
589
+ await orderRef.delete().catch(()=>undefined);
590
+ await releaseDiscountSlot();
591
+ await claim.release();
592
+ return res.status(502).json({
593
+ error: 'Payment link creation failed'
594
+ });
595
+ }
596
+ }
597
+ const params = new URLSearchParams(_extends({
598
+ mode: 'payment'
599
+ }, useStripeTax ? {
600
+ 'automatic_tax[enabled]': 'true'
601
+ } : {}, draftTaxRateId ? {
602
+ 'line_items[0][tax_rates][0]': draftTaxRateId
603
+ } : {}, {
604
+ 'line_items[0][quantity]': String(chargedQuantity),
605
+ 'line_items[0][price_data][currency]': 'usd',
606
+ 'line_items[0][price_data][unit_amount]': String(chargedUnitAmountCents),
607
+ 'line_items[0][price_data][product_data][name]': chargedLineName
608
+ }, CommerceModel.destinationChargeParams({
609
+ accountId: String(accountId),
610
+ feeCents,
611
+ taxOwner: useStripeTax ? 'platform' : 'merchant',
612
+ // The DISCOUNTED goods (AGL-305): this is what the merchant is
613
+ // transferred, and paying out the list price on a discounted link
614
+ // would move money Stripe never collected.
615
+ merchantGoodsCents: chargedItemsCents,
616
+ shippingFloorCents: CommerceModel.shippingFloorCents(shippingOptions)
617
+ }), email ? {
618
+ customer_email: email
619
+ } : {}, {
620
+ success_url: `${consoleProductsUrl}?draft=paid`,
621
+ cancel_url: `${consoleProductsUrl}?draft=canceled`,
622
+ 'metadata[type]': 'commerce-draft',
623
+ 'metadata[hostId]': hostId,
624
+ 'metadata[orderId]': orderRef.id,
625
+ 'metadata[productId]': productId
626
+ }, variantId ? {
627
+ 'metadata[variantId]': variantId
628
+ } : {}, {
629
+ 'metadata[feeCents]': String(feeCents)
630
+ }, appliedDiscountId ? {
631
+ 'metadata[discountId]': appliedDiscountId
632
+ } : {}, discountHoldKey ? {
633
+ 'metadata[discountHoldKey]': discountHoldKey
634
+ } : {}, useStripeTax ? {
635
+ 'metadata[transferCents]': String(CommerceModel.platformLiableTransferCents({
636
+ feeCents,
637
+ merchantGoodsCents: chargedItemsCents,
638
+ shippingFloorCents: CommerceModel.shippingFloorCents(shippingOptions)
639
+ })),
640
+ 'metadata[transferShippingCents]': String(CommerceModel.shippingFloorCents(shippingOptions))
641
+ } : {}));
642
+ // Both keys or neither (AGL-1720's rule, inherited). Stripe will not apply
643
+ // a shipping rate without an address to ship to, and a merchant who
644
+ // configured nothing plans to no options and so gets neither — a payment
645
+ // link byte-identical to the one this handler built before shipping
646
+ // existed on it.
647
+ if (shippingOptions.length > 0) {
648
+ CommerceModel.appendShippingAddressCollectionParams(params, shippingPlan.countries);
649
+ CommerceModel.appendCheckoutShippingParams(params, shippingOptions);
650
+ }
651
+ const response = await fetch('https://api.stripe.com/v1/checkout/sessions', {
652
+ method: 'POST',
653
+ headers: _extends({
654
+ Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`,
655
+ 'Content-Type': 'application/x-www-form-urlencoded'
656
+ }, claim.stripeKey ? {
657
+ 'Idempotency-Key': claim.stripeKey
658
+ } : {}),
659
+ body: params.toString()
660
+ });
661
+ const session = await response.json();
662
+ if (!response.ok || !session.url) {
663
+ console.error('Stripe draft-order error', session.error);
664
+ await orderRef.delete().catch(()=>undefined);
665
+ // The draft did not happen — hand the key back rather than locking this
666
+ // dialog out over one flaky moment. The retry re-derives the SAME
667
+ // digest, so if Stripe did create the session it replays it.
668
+ await releaseDiscountSlot();
669
+ await claim.release();
670
+ return res.status(502).json({
671
+ error: 'Payment link creation failed'
672
+ });
673
+ }
674
+ await orderRef.set({
675
+ checkoutSessionId: session.id,
676
+ paymentLinkUrl: session.url
677
+ }, {
678
+ merge: true
679
+ });
680
+ // Spread on the same terms as the register's: present only when there is
681
+ // something to say, so a caller can test the key rather than a length.
682
+ const payload = _extends({
683
+ orderId: orderRef.id,
684
+ url: session.url
685
+ }, stockWarnings.length > 0 ? {
686
+ stockWarnings
687
+ } : {});
688
+ await claim.record(200, payload);
689
+ return res.status(200).json(payload);
690
+ } catch (error) {
691
+ console.error(error);
692
+ // Release on the way out so a transient failure does not strand the key
693
+ // (AGL-1691's rule). The order write may or may not have landed; the
694
+ // merchant reconciles from the orders list, the same position they were
695
+ // in before this endpoint had a claim at all. The redemption slot goes
696
+ // back for the same reason — a throw is the one path that would otherwise
697
+ // leave it standing against the cap until its TTL lapsed.
698
+ await releaseDiscountSlot();
699
+ await (claim == null ? void 0 : claim.release());
700
+ return res.status(500).json({
701
+ error: 'Draft order failed'
702
+ });
703
+ }
704
+ };
705
+
706
+ //# sourceMappingURL=draft-order.js.map