@aglyn/plugins-commerce 1.0.0-beta.284 → 1.0.0-beta.287

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 (420) hide show
  1. package/README.md +1 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/cart.js +25 -12
  4. package/src/lib/components/cart.js.map +1 -1
  5. package/src/lib/components/commerce-console-page.js +70 -13
  6. package/src/lib/components/commerce-console-page.js.map +1 -1
  7. package/src/lib/components/console/order-detail-dialog.component.js +2 -1
  8. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  9. package/src/lib/components/console/payment-methods-card.component.js +1 -1
  10. package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
  11. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
  12. package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
  13. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
  14. package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
  15. package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
  16. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
  17. package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
  18. package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
  19. package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
  20. package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
  21. package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
  22. package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
  23. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
  24. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
  25. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
  26. package/src/lib/components/console/pos/use-pos-display.js +50 -0
  27. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  28. package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
  29. package/src/lib/components/console/pos-cellular-control.component.js +211 -0
  30. package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
  31. package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
  32. package/src/lib/components/console/pos-devices-card.component.js +47 -15
  33. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  34. package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
  35. package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
  36. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  37. package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
  38. package/src/lib/components/console/pos-display-page.component.js +44 -2
  39. package/src/lib/components/console/pos-display-page.component.js.map +1 -1
  40. package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
  41. package/src/lib/components/console/pos-hardware-card.component.js +157 -36
  42. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
  43. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
  44. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
  45. package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
  46. package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
  47. package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
  48. package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
  49. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
  50. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
  51. package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
  52. package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
  53. package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
  54. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
  55. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
  56. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
  57. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
  58. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
  59. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
  60. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
  61. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  62. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
  63. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
  64. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
  65. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
  66. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
  67. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
  68. package/src/lib/components/console/pos-page.component.d.ts +1 -1
  69. package/src/lib/components/console/pos-page.component.js +63 -12
  70. package/src/lib/components/console/pos-page.component.js.map +1 -1
  71. package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
  72. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
  73. package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
  74. package/src/lib/components/console/product-check-in-fields.component.js +60 -14
  75. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
  76. package/src/lib/components/console/product-editor-dialog.component.js +44 -1
  77. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  78. package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
  79. package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
  80. package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
  81. package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
  82. package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
  83. package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
  84. package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
  85. package/src/lib/components/console/product-register-fields.component.js +31 -2
  86. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  87. package/src/lib/components/console/products-hub-card.component.js +11 -2
  88. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  89. package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
  90. package/src/lib/components/console/register-hardware-card.component.js +56 -27
  91. package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
  92. package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
  93. package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
  94. package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
  95. package/src/lib/components/console/reservations-card.component.d.ts +9 -0
  96. package/src/lib/components/console/reservations-card.component.js +158 -23
  97. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  98. package/src/lib/components/console/shippingeasy-card.component.js +1 -1
  99. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
  100. package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
  101. package/src/lib/components/console/shipstation-card.component.js +3 -3
  102. package/src/lib/components/console/shipstation-card.component.js.map +1 -1
  103. package/src/lib/components/product-detail.d.ts +4 -0
  104. package/src/lib/components/product-detail.js +40 -5
  105. package/src/lib/components/product-detail.js.map +1 -1
  106. package/src/lib/components/product-reviews.js +28 -11
  107. package/src/lib/components/product-reviews.js.map +1 -1
  108. package/src/lib/components/reservation-widget.js +28 -5
  109. package/src/lib/components/reservation-widget.js.map +1 -1
  110. package/src/lib/components/use-day-picker.d.ts +25 -0
  111. package/src/lib/components/use-day-picker.js +57 -0
  112. package/src/lib/components/use-day-picker.js.map +1 -0
  113. package/src/lib/constants/operator-alerts.d.ts +55 -0
  114. package/src/lib/constants/operator-alerts.js +156 -1
  115. package/src/lib/constants/operator-alerts.js.map +1 -1
  116. package/src/lib/declarations.console-server.js +54 -1
  117. package/src/lib/declarations.console-server.js.map +1 -1
  118. package/src/lib/declarations.d.ts +4 -2
  119. package/src/lib/declarations.js +11 -4
  120. package/src/lib/declarations.js.map +1 -1
  121. package/src/lib/declarations.server.js +9 -0
  122. package/src/lib/declarations.server.js.map +1 -1
  123. package/src/lib/model/commerce-cart.d.ts +9 -1
  124. package/src/lib/model/commerce-cart.js +4 -3
  125. package/src/lib/model/commerce-cart.js.map +1 -1
  126. package/src/lib/model/commerce-check-in-product.d.ts +26 -0
  127. package/src/lib/model/commerce-check-in-product.js +64 -2
  128. package/src/lib/model/commerce-check-in-product.js.map +1 -1
  129. package/src/lib/model/commerce-check-in-record.d.ts +127 -0
  130. package/src/lib/model/commerce-check-in-record.js +36 -0
  131. package/src/lib/model/commerce-check-in-record.js.map +1 -0
  132. package/src/lib/model/commerce-check-in.d.ts +91 -87
  133. package/src/lib/model/commerce-check-in.js +186 -62
  134. package/src/lib/model/commerce-check-in.js.map +1 -1
  135. package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
  136. package/src/lib/model/commerce-kiosk-offer.js +35 -0
  137. package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
  138. package/src/lib/model/commerce-orders.d.ts +76 -0
  139. package/src/lib/model/commerce-orders.js +6 -0
  140. package/src/lib/model/commerce-orders.js.map +1 -1
  141. package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
  142. package/src/lib/model/commerce-pos-day-report.js +39 -2
  143. package/src/lib/model/commerce-pos-day-report.js.map +1 -1
  144. package/src/lib/model/commerce-pos-offline.d.ts +1 -1
  145. package/src/lib/model/commerce-pos-offline.js +6 -1
  146. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  147. package/src/lib/model/commerce-pos-ops.js +3 -2
  148. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  149. package/src/lib/model/commerce-pos.d.ts +36 -3
  150. package/src/lib/model/commerce-pos.js +14 -6
  151. package/src/lib/model/commerce-pos.js.map +1 -1
  152. package/src/lib/model/commerce-receipt.js +3 -2
  153. package/src/lib/model/commerce-receipt.js.map +1 -1
  154. package/src/lib/model/commerce-reservations.d.ts +69 -4
  155. package/src/lib/model/commerce-reservations.js +57 -5
  156. package/src/lib/model/commerce-reservations.js.map +1 -1
  157. package/src/lib/model/commerce.d.ts +66 -0
  158. package/src/lib/model/commerce.js +15 -0
  159. package/src/lib/model/commerce.js.map +1 -1
  160. package/src/lib/model/order-list-fields.d.ts +11 -0
  161. package/src/lib/model/order-list-fields.js +17 -1
  162. package/src/lib/model/order-list-fields.js.map +1 -1
  163. package/src/lib/model/own-store-tax-summary.d.ts +152 -0
  164. package/src/lib/model/own-store-tax-summary.js +288 -0
  165. package/src/lib/model/own-store-tax-summary.js.map +1 -0
  166. package/src/lib/model/plugin-permissions.d.ts +67 -0
  167. package/src/lib/model/plugin-permissions.js +224 -7
  168. package/src/lib/model/plugin-permissions.js.map +1 -1
  169. package/src/lib/model/pos-cellular.d.ts +223 -0
  170. package/src/lib/model/pos-cellular.js +293 -0
  171. package/src/lib/model/pos-cellular.js.map +1 -0
  172. package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
  173. package/src/lib/model/pos-hardware-in-person.js +224 -0
  174. package/src/lib/model/pos-hardware-in-person.js.map +1 -0
  175. package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
  176. package/src/lib/model/pos-hardware-tax-summary.js +225 -0
  177. package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
  178. package/src/lib/model/pos-hardware-terms.d.ts +74 -0
  179. package/src/lib/model/pos-hardware-terms.js +115 -0
  180. package/src/lib/model/pos-hardware-terms.js.map +1 -0
  181. package/src/lib/model/pos-hardware.d.ts +349 -7
  182. package/src/lib/model/pos-hardware.js +291 -20
  183. package/src/lib/model/pos-hardware.js.map +1 -1
  184. package/src/lib/model/product-write.d.ts +10 -0
  185. package/src/lib/model/product-write.js +4 -2
  186. package/src/lib/model/product-write.js.map +1 -1
  187. package/src/lib/plugin.js +16 -0
  188. package/src/lib/plugin.js.map +1 -1
  189. package/src/lib/server/billing-webhook.js +25 -1
  190. package/src/lib/server/billing-webhook.js.map +1 -1
  191. package/src/lib/server/cancel-order.js +7 -5
  192. package/src/lib/server/cancel-order.js.map +1 -1
  193. package/src/lib/server/cart-checkout.js +20 -8
  194. package/src/lib/server/cart-checkout.js.map +1 -1
  195. package/src/lib/server/cart.js +29 -0
  196. package/src/lib/server/cart.js.map +1 -1
  197. package/src/lib/server/checkout.js +42 -13
  198. package/src/lib/server/checkout.js.map +1 -1
  199. package/src/lib/server/collection-membership.d.ts +4 -0
  200. package/src/lib/server/collection-membership.js +5 -10
  201. package/src/lib/server/collection-membership.js.map +1 -1
  202. package/src/lib/server/commerce-site-keys.d.ts +29 -0
  203. package/src/lib/server/commerce-site-keys.js +40 -0
  204. package/src/lib/server/commerce-site-keys.js.map +1 -0
  205. package/src/lib/server/draft-order.js +8 -5
  206. package/src/lib/server/draft-order.js.map +1 -1
  207. package/src/lib/server/fulfill-order.js +7 -5
  208. package/src/lib/server/fulfill-order.js.map +1 -1
  209. package/src/lib/server/gift-cards.js +8 -5
  210. package/src/lib/server/gift-cards.js.map +1 -1
  211. package/src/lib/server/local-fulfillment-status.js +9 -6
  212. package/src/lib/server/local-fulfillment-status.js.map +1 -1
  213. package/src/lib/server/member-post.js +6 -5
  214. package/src/lib/server/member-post.js.map +1 -1
  215. package/src/lib/server/membership-admin-password.d.ts +4 -2
  216. package/src/lib/server/membership-admin-password.js +10 -8
  217. package/src/lib/server/membership-admin-password.js.map +1 -1
  218. package/src/lib/server/membership-admin-remove.d.ts +7 -5
  219. package/src/lib/server/membership-admin-remove.js +9 -9
  220. package/src/lib/server/membership-admin-remove.js.map +1 -1
  221. package/src/lib/server/order-notifications.js +5 -2
  222. package/src/lib/server/order-notifications.js.map +1 -1
  223. package/src/lib/server/order-print.js +7 -5
  224. package/src/lib/server/order-print.js.map +1 -1
  225. package/src/lib/server/order-receipt-send.js +8 -5
  226. package/src/lib/server/order-receipt-send.js.map +1 -1
  227. package/src/lib/server/orders-shipping-prepare.js +9 -6
  228. package/src/lib/server/orders-shipping-prepare.js.map +1 -1
  229. package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
  230. package/src/lib/server/own-store-tax-return-source.js +312 -0
  231. package/src/lib/server/own-store-tax-return-source.js.map +1 -0
  232. package/src/lib/server/payment-methods.js +13 -9
  233. package/src/lib/server/payment-methods.js.map +1 -1
  234. package/src/lib/server/pos-auth.d.ts +37 -6
  235. package/src/lib/server/pos-auth.js +40 -15
  236. package/src/lib/server/pos-auth.js.map +1 -1
  237. package/src/lib/server/pos-cellular-billing.d.ts +81 -0
  238. package/src/lib/server/pos-cellular-billing.js +711 -0
  239. package/src/lib/server/pos-cellular-billing.js.map +1 -0
  240. package/src/lib/server/pos-cellular-notify.d.ts +47 -0
  241. package/src/lib/server/pos-cellular-notify.js +150 -0
  242. package/src/lib/server/pos-cellular-notify.js.map +1 -0
  243. package/src/lib/server/pos-cellular.d.ts +88 -0
  244. package/src/lib/server/pos-cellular.js +339 -0
  245. package/src/lib/server/pos-cellular.js.map +1 -0
  246. package/src/lib/server/pos-check-in.d.ts +5 -1
  247. package/src/lib/server/pos-check-in.js +296 -28
  248. package/src/lib/server/pos-check-in.js.map +1 -1
  249. package/src/lib/server/pos-day-report.js +29 -3
  250. package/src/lib/server/pos-day-report.js.map +1 -1
  251. package/src/lib/server/pos-display.d.ts +16 -0
  252. package/src/lib/server/pos-display.js +129 -2
  253. package/src/lib/server/pos-display.js.map +1 -1
  254. package/src/lib/server/pos-hardware-admin.d.ts +10 -1
  255. package/src/lib/server/pos-hardware-admin.js +250 -84
  256. package/src/lib/server/pos-hardware-admin.js.map +1 -1
  257. package/src/lib/server/pos-hardware-attach.d.ts +105 -0
  258. package/src/lib/server/pos-hardware-attach.js +443 -0
  259. package/src/lib/server/pos-hardware-attach.js.map +1 -0
  260. package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
  261. package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
  262. package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
  263. package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
  264. package/src/lib/server/pos-hardware-buyer-record.js +86 -0
  265. package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
  266. package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
  267. package/src/lib/server/pos-hardware-cancel.js +147 -0
  268. package/src/lib/server/pos-hardware-cancel.js.map +1 -0
  269. package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
  270. package/src/lib/server/pos-hardware-closure-notices.js +85 -0
  271. package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
  272. package/src/lib/server/pos-hardware-closure.d.ts +60 -0
  273. package/src/lib/server/pos-hardware-closure.js +153 -0
  274. package/src/lib/server/pos-hardware-closure.js.map +1 -0
  275. package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
  276. package/src/lib/server/pos-hardware-in-person.js +236 -0
  277. package/src/lib/server/pos-hardware-in-person.js.map +1 -0
  278. package/src/lib/server/pos-hardware-notify.d.ts +40 -2
  279. package/src/lib/server/pos-hardware-notify.js +195 -14
  280. package/src/lib/server/pos-hardware-notify.js.map +1 -1
  281. package/src/lib/server/pos-hardware-readers.d.ts +115 -0
  282. package/src/lib/server/pos-hardware-readers.js +430 -0
  283. package/src/lib/server/pos-hardware-readers.js.map +1 -0
  284. package/src/lib/server/pos-hardware-returns.d.ts +116 -0
  285. package/src/lib/server/pos-hardware-returns.js +502 -0
  286. package/src/lib/server/pos-hardware-returns.js.map +1 -0
  287. package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
  288. package/src/lib/server/pos-hardware-sale-fields.js +44 -0
  289. package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
  290. package/src/lib/server/pos-hardware-sale.d.ts +54 -0
  291. package/src/lib/server/pos-hardware-sale.js +369 -0
  292. package/src/lib/server/pos-hardware-sale.js.map +1 -0
  293. package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
  294. package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
  295. package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
  296. package/src/lib/server/pos-hardware-terms.d.ts +64 -0
  297. package/src/lib/server/pos-hardware-terms.js +154 -0
  298. package/src/lib/server/pos-hardware-terms.js.map +1 -0
  299. package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
  300. package/src/lib/server/pos-hardware-user-eraser.js +31 -7
  301. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
  302. package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
  303. package/src/lib/server/pos-hardware-webhook.js +51 -6
  304. package/src/lib/server/pos-hardware-webhook.js.map +1 -1
  305. package/src/lib/server/pos-hardware.d.ts +74 -1
  306. package/src/lib/server/pos-hardware.js +175 -10
  307. package/src/lib/server/pos-hardware.js.map +1 -1
  308. package/src/lib/server/pos-kiosk.d.ts +2 -0
  309. package/src/lib/server/pos-kiosk.js +17 -12
  310. package/src/lib/server/pos-kiosk.js.map +1 -1
  311. package/src/lib/server/pos-offline-card-order.d.ts +64 -0
  312. package/src/lib/server/pos-offline-card-order.js +102 -0
  313. package/src/lib/server/pos-offline-card-order.js.map +1 -0
  314. package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
  315. package/src/lib/server/pos-offline-card-reconcile.js +215 -18
  316. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
  317. package/src/lib/server/pos-offline-sync.d.ts +39 -0
  318. package/src/lib/server/pos-offline-sync.js +190 -55
  319. package/src/lib/server/pos-offline-sync.js.map +1 -1
  320. package/src/lib/server/pos-ops-gate.d.ts +15 -4
  321. package/src/lib/server/pos-ops-gate.js +42 -9
  322. package/src/lib/server/pos-ops-gate.js.map +1 -1
  323. package/src/lib/server/pos-ops-routes.js +24 -0
  324. package/src/lib/server/pos-ops-routes.js.map +1 -1
  325. package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
  326. package/src/lib/server/pos-order-refund-ids.js +31 -0
  327. package/src/lib/server/pos-order-refund-ids.js.map +1 -0
  328. package/src/lib/server/pos-order.js +52 -49
  329. package/src/lib/server/pos-order.js.map +1 -1
  330. package/src/lib/server/pos-payment.js +1 -1
  331. package/src/lib/server/pos-payment.js.map +1 -1
  332. package/src/lib/server/pos-reader-splash-admin.js +30 -32
  333. package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
  334. package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
  335. package/src/lib/server/pos-reader-splash-images-route.js +113 -0
  336. package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
  337. package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
  338. package/src/lib/server/pos-reader-splash-images.js +123 -0
  339. package/src/lib/server/pos-reader-splash-images.js.map +1 -0
  340. package/src/lib/server/pos-reader-splash.d.ts +68 -1
  341. package/src/lib/server/pos-reader-splash.js +182 -11
  342. package/src/lib/server/pos-reader-splash.js.map +1 -1
  343. package/src/lib/server/pos-readers.d.ts +29 -0
  344. package/src/lib/server/pos-readers.js +134 -35
  345. package/src/lib/server/pos-readers.js.map +1 -1
  346. package/src/lib/server/pos-return.d.ts +10 -0
  347. package/src/lib/server/pos-return.js +26 -1
  348. package/src/lib/server/pos-return.js.map +1 -1
  349. package/src/lib/server/pos-sale.js +6 -1
  350. package/src/lib/server/pos-sale.js.map +1 -1
  351. package/src/lib/server/pos-shift.js +11 -0
  352. package/src/lib/server/pos-shift.js.map +1 -1
  353. package/src/lib/server/pos-staff-pin.js +25 -20
  354. package/src/lib/server/pos-staff-pin.js.map +1 -1
  355. package/src/lib/server/pos-terminal.d.ts +14 -4
  356. package/src/lib/server/pos-terminal.js +34 -38
  357. package/src/lib/server/pos-terminal.js.map +1 -1
  358. package/src/lib/server/printers.d.ts +7 -3
  359. package/src/lib/server/printers.js +18 -12
  360. package/src/lib/server/printers.js.map +1 -1
  361. package/src/lib/server/product-drafts.d.ts +11 -1
  362. package/src/lib/server/product-drafts.js +12 -8
  363. package/src/lib/server/product-drafts.js.map +1 -1
  364. package/src/lib/server/product.d.ts +15 -1
  365. package/src/lib/server/product.js +16 -3
  366. package/src/lib/server/product.js.map +1 -1
  367. package/src/lib/server/products-write.d.ts +26 -2
  368. package/src/lib/server/products-write.js +19 -7
  369. package/src/lib/server/products-write.js.map +1 -1
  370. package/src/lib/server/refund.js +34 -11
  371. package/src/lib/server/refund.js.map +1 -1
  372. package/src/lib/server/reservation-availability-query.d.ts +8 -0
  373. package/src/lib/server/reservation-availability-query.js +11 -1
  374. package/src/lib/server/reservation-availability-query.js.map +1 -1
  375. package/src/lib/server/reservation-availability.d.ts +1 -1
  376. package/src/lib/server/reservation-availability.js +7 -2
  377. package/src/lib/server/reservation-availability.js.map +1 -1
  378. package/src/lib/server/reservation-guests.d.ts +32 -0
  379. package/src/lib/server/reservation-guests.js +285 -0
  380. package/src/lib/server/reservation-guests.js.map +1 -0
  381. package/src/lib/server/reservation-walk-in.d.ts +11 -1
  382. package/src/lib/server/reservation-walk-in.js +56 -12
  383. package/src/lib/server/reservation-walk-in.js.map +1 -1
  384. package/src/lib/server/reserve.js +18 -5
  385. package/src/lib/server/reserve.js.map +1 -1
  386. package/src/lib/server/returns.js +9 -6
  387. package/src/lib/server/returns.js.map +1 -1
  388. package/src/lib/server/reviews.d.ts +22 -2
  389. package/src/lib/server/reviews.js +88 -20
  390. package/src/lib/server/reviews.js.map +1 -1
  391. package/src/lib/server/shipping-connectors.js +10 -11
  392. package/src/lib/server/shipping-connectors.js.map +1 -1
  393. package/src/lib/server/site-page-resolver.js +20 -3
  394. package/src/lib/server/site-page-resolver.js.map +1 -1
  395. package/src/lib/server/store-day.d.ts +33 -0
  396. package/src/lib/server/store-day.js +46 -0
  397. package/src/lib/server/store-day.js.map +1 -0
  398. package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
  399. package/src/lib/server/store-setup-ai-writer.js +5 -6
  400. package/src/lib/server/store-setup-ai-writer.js.map +1 -1
  401. package/src/lib/server/storefront-tax.d.ts +13 -0
  402. package/src/lib/server/storefront-tax.js +8 -1
  403. package/src/lib/server/storefront-tax.js.map +1 -1
  404. package/src/lib/server/tax-return-source.d.ts +32 -3
  405. package/src/lib/server/tax-return-source.js +99 -20
  406. package/src/lib/server/tax-return-source.js.map +1 -1
  407. package/src/lib/server.js +100 -2
  408. package/src/lib/server.js.map +1 -1
  409. package/src/lib/testing/fake-firestore.js +58 -16
  410. package/src/lib/testing/fake-firestore.js.map +1 -1
  411. package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
  412. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
  413. package/src/lib/testing/site-register-permissions.d.ts +29 -0
  414. package/src/lib/testing/site-register-permissions.js +38 -0
  415. package/src/lib/testing/site-register-permissions.js.map +1 -0
  416. package/src/lib/transfer/tracking.server.js +8 -5
  417. package/src/lib/transfer/tracking.server.js.map +1 -1
  418. package/src/lib/utils/add-to-cart.d.ts +2 -0
  419. package/src/lib/utils/add-to-cart.js +6 -3
  420. package/src/lib/utils/add-to-cart.js.map +1 -1
@@ -0,0 +1,58 @@
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
+ export interface HardwareBuyerStore {
18
+ hostId: string;
19
+ name: string;
20
+ /** Whether card readers can be registered to it: its Stripe Terminal Location exists. */
21
+ hasLocation: boolean;
22
+ }
23
+ export interface HardwareBuyerWorkspace {
24
+ orgId: string;
25
+ name: string;
26
+ /** Whether the workspace's plan includes the point of sale. */
27
+ posPlan: boolean;
28
+ stores: HardwareBuyerStore[];
29
+ }
30
+ export interface HardwareBuyerPerson {
31
+ uid: string;
32
+ name: string;
33
+ /** Their email address, in full. */
34
+ email: string;
35
+ workspaces: HardwareBuyerWorkspace[];
36
+ }
37
+ export interface HardwareBuyerFindResult {
38
+ kind: 'email' | 'name';
39
+ people: HardwareBuyerPerson[];
40
+ /** Workspaces whose name matched, each with the person it would be attached to. */
41
+ workspaces: Array<HardwareBuyerWorkspace & {
42
+ owner: Omit<HardwareBuyerPerson, 'workspaces'> | null;
43
+ }>;
44
+ /** An exact address with no account: sell anyway, invite, attach later. */
45
+ noAccount: boolean;
46
+ }
47
+ /** How many people, workspaces and stores one answer carries at most. */
48
+ export declare const BUYER_LOOKUP_LIMITS: {
49
+ people: number;
50
+ workspaces: number;
51
+ workspacesPerPerson: number;
52
+ storesPerWorkspace: number;
53
+ };
54
+ /**
55
+ * Looks a buyer up. An exact address is looked up as one; anything else as
56
+ * a person's name and a workspace's. Every address is answered in full.
57
+ */
58
+ export declare function findHardwareBuyers(query: string): Promise<HardwareBuyerFindResult>;
@@ -0,0 +1,180 @@
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 { nameSearchKey, nameSearchTokens, NAME_TOKEN_MAX_PREFIX } from "@aglyn/aglyn/app-utils/name-search";
19
+ import { firebaseAdmin, hostDisplayName } from "@aglyn/tenant-data-admin";
20
+ import { findUserByEmailAcrossPools } from "@aglyn/tenant-data-admin/server/auth-pools";
21
+ /** How many people, workspaces and stores one answer carries at most. */ export const BUYER_LOOKUP_LIMITS = {
22
+ people: 8,
23
+ workspaces: 8,
24
+ workspacesPerPerson: 5,
25
+ storesPerWorkspace: 10
26
+ };
27
+ const EXACT_EMAIL = /^[^@\s]{1,64}@[^@\s]+\.[^@\s]{2,}$/;
28
+ function firestore() {
29
+ return firebaseAdmin.app().firestore();
30
+ }
31
+ /** The typed words, as the tokens are stored. */ function words(query) {
32
+ return nameSearchKey(query).split(' ').filter(Boolean).map((word)=>[
33
+ ...word
34
+ ].slice(0, NAME_TOKEN_MAX_PREFIX).join(''));
35
+ }
36
+ /** Whether every typed word begins a word of `name`. */ function nameMatches(name, typed) {
37
+ const own = new Set(nameSearchTokens(name));
38
+ return typed.length > 0 && typed.every((word)=>own.has(word));
39
+ }
40
+ /** The longest typed word: the narrowest single `array-contains`. */ function narrowest(typed) {
41
+ var _sort_;
42
+ return (_sort_ = [
43
+ ...typed
44
+ ].sort((a, b)=>b.length - a.length)[0]) != null ? _sort_ : '';
45
+ }
46
+ async function storesOf(orgId) {
47
+ const hosts = await firestore().collection('hosts').where('orgId', '==', orgId).limit(BUYER_LOOKUP_LIMITS.storesPerWorkspace).get();
48
+ return Promise.all(hosts.docs.map(async (doc)=>{
49
+ const config = await firestore().collection('hosts').doc(String(doc.id)).collection('terminal').doc('config').get();
50
+ return {
51
+ hostId: String(doc.id),
52
+ name: hostDisplayName(doc.data(), String(doc.id)),
53
+ hasLocation: Boolean(config.exists && config.get('stripeLocationId'))
54
+ };
55
+ }));
56
+ }
57
+ async function workspace(orgId, org) {
58
+ var _data_name;
59
+ const data = org != null ? org : (await firestore().collection('orgs').doc(orgId).get()).data();
60
+ if (!data) return null;
61
+ return {
62
+ orgId,
63
+ name: String((_data_name = data['name']) != null ? _data_name : '').trim() || 'Workspace',
64
+ posPlan: Aglyn.checkEntitlement(data, 'pos'),
65
+ stores: await storesOf(orgId)
66
+ };
67
+ }
68
+ /** A row of a workspace's own roster, `orgs/{orgId}/members/{uid}`, and no other `members`. */ function isRosterRow(doc) {
69
+ var _doc_ref_parent, _doc_ref, _parent_parent;
70
+ const parent = (_doc_ref = doc.ref) == null ? void 0 : (_doc_ref_parent = _doc_ref.parent) == null ? void 0 : _doc_ref_parent.parent;
71
+ return (parent == null ? void 0 : (_parent_parent = parent.parent) == null ? void 0 : _parent_parent.id) === 'orgs';
72
+ }
73
+ /** The workspaces a person is on, by their roster rows. */ async function workspacesOf(uid) {
74
+ const rows = await firestore().collectionGroup('members').where('uid', '==', uid).limit(BUYER_LOOKUP_LIMITS.workspacesPerPerson).get();
75
+ const orgIds = [
76
+ ...new Set(rows.docs.filter(isRosterRow).map((doc)=>String(doc.ref.parent.parent.id)))
77
+ ];
78
+ return (await Promise.all(orgIds.map((orgId)=>workspace(orgId)))).filter((found)=>Boolean(found));
79
+ }
80
+ /** The people whose name begins with every typed word, one per account. */ async function peopleNamed(typed) {
81
+ const rows = await firestore().collectionGroup('members').where('consoleUserType', 'in', [
82
+ 'manager',
83
+ 'collaborator'
84
+ ]).where('searchTokens', 'array-contains', narrowest(typed)).limit(30).get();
85
+ const people = new Map();
86
+ for (const doc of rows.docs){
87
+ var _data_uid, _data_displayName, _data_email;
88
+ if (!isRosterRow(doc)) continue;
89
+ const data = doc.data();
90
+ const uid = String((_data_uid = data['uid']) != null ? _data_uid : doc.id);
91
+ const name = String((_data_displayName = data['displayName']) != null ? _data_displayName : '').trim();
92
+ // A match on the address or the job title alone is not a match on a name.
93
+ if (!uid || people.has(uid) || !nameMatches(name, typed)) continue;
94
+ people.set(uid, {
95
+ uid,
96
+ name,
97
+ email: String((_data_email = data['email']) != null ? _data_email : '')
98
+ });
99
+ if (people.size >= BUYER_LOOKUP_LIMITS.people) break;
100
+ }
101
+ return [
102
+ ...people.values()
103
+ ];
104
+ }
105
+ /** The workspaces whose name begins with every typed word. */ async function workspacesNamed(typed) {
106
+ const orgs = await firestore().collection('orgs').where('nameTokens', 'array-contains', narrowest(typed)).limit(20).get();
107
+ const matched = orgs.docs.filter((doc)=>{
108
+ var _doc_data_name;
109
+ return nameMatches(String((_doc_data_name = doc.data()['name']) != null ? _doc_data_name : ''), typed);
110
+ }).slice(0, BUYER_LOOKUP_LIMITS.workspaces);
111
+ return Promise.all(matched.map(async (doc)=>{
112
+ var _data_ownerUid, _owner_get, _owner_get1;
113
+ const data = doc.data();
114
+ const found = await workspace(String(doc.id), data);
115
+ const ownerUid = String((_data_ownerUid = data['ownerUid']) != null ? _data_ownerUid : '');
116
+ const owner = ownerUid ? await firestore().collection('orgs').doc(String(doc.id)).collection('members').doc(ownerUid).get() : null;
117
+ return _extends({}, found, {
118
+ owner: (owner == null ? void 0 : owner.exists) ? {
119
+ uid: ownerUid,
120
+ name: String((_owner_get = owner.get('displayName')) != null ? _owner_get : '').trim(),
121
+ email: String((_owner_get1 = owner.get('email')) != null ? _owner_get1 : '')
122
+ } : null
123
+ });
124
+ }));
125
+ }
126
+ /**
127
+ * Looks a buyer up. An exact address is looked up as one; anything else as
128
+ * a person's name and a workspace's. Every address is answered in full.
129
+ */ export async function findHardwareBuyers(query) {
130
+ const text = query.trim();
131
+ if (EXACT_EMAIL.test(text)) {
132
+ var _user_record_displayName;
133
+ const user = await findUserByEmailAcrossPools(text);
134
+ if (!user) return {
135
+ kind: 'email',
136
+ people: [],
137
+ workspaces: [],
138
+ noAccount: true
139
+ };
140
+ const uid = user.record.uid;
141
+ return {
142
+ kind: 'email',
143
+ people: [
144
+ {
145
+ uid,
146
+ name: String((_user_record_displayName = user.record.displayName) != null ? _user_record_displayName : '').trim(),
147
+ email: text.toLowerCase(),
148
+ workspaces: await workspacesOf(uid)
149
+ }
150
+ ],
151
+ workspaces: [],
152
+ noAccount: false
153
+ };
154
+ }
155
+ const typed = words(text);
156
+ if (!typed.length) return {
157
+ kind: 'name',
158
+ people: [],
159
+ workspaces: [],
160
+ noAccount: false
161
+ };
162
+ const [named, workspaces] = await Promise.all([
163
+ peopleNamed(typed),
164
+ workspacesNamed(typed)
165
+ ]);
166
+ const people = await Promise.all(named.map(async (person)=>({
167
+ uid: person.uid,
168
+ name: person.name,
169
+ email: person.email,
170
+ workspaces: await workspacesOf(person.uid)
171
+ })));
172
+ return {
173
+ kind: 'name',
174
+ people,
175
+ workspaces,
176
+ noAccount: false
177
+ };
178
+ }
179
+
180
+ //# sourceMappingURL=pos-hardware-buyer-lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-hardware-buyer-lookup.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\nimport * as Aglyn from '@aglyn/aglyn/server'\nimport { nameSearchKey, nameSearchTokens, NAME_TOKEN_MAX_PREFIX } from '@aglyn/aglyn/app-utils/name-search'\nimport { firebaseAdmin, hostDisplayName } from '@aglyn/tenant-data-admin'\nimport { findUserByEmailAcrossPools } from '@aglyn/tenant-data-admin/server/auth-pools'\n\n/*==========================================\n * FINDING THE BUYER OF A CARD READER SOLD IN PERSON (AGL-4038).\n *\n * A register user on the platform's own store looks up who they are selling\n * a reader to, among every account on the platform, by:\n *\n * - an exact email address, through every sign-in pool;\n * - a person's name, through the word-prefix `searchTokens` every\n * workspace roster row carries (`orgs/{orgId}/members`). Other\n * collections are called `members` too — an email list's subscribers,\n * which are a store's own contacts — so the collection-group query asks\n * for `consoleUserType`, which only a roster row carries\n * (`orgMemberListFields`, backfilled by\n * `tools/scripts/backfill-org-member-list-fields.mjs`), with its own\n * index, and keeps only rows under `orgs/`. The typed words must each\n * begin a word of the person's NAME, so a match on an address alone is\n * never shown;\n * - a workspace's name, through the workspaces' own `nameTokens`.\n *\n * Every answer is an indexed query, never a scan of a loaded window, and is\n * capped. Each says the least that lets the right buyer be picked: a\n * person's display name and their email address in full, so the register\n * user can read it back to them, and each of their workspaces with its\n * stores, whether the workspace's plan includes the point of sale and\n * whether each store has a card reader Location. Never a phone number, a\n * street address, a role or a bill. The audit log keeps the typed address\n * masked (`pos-hardware-sale.ts`).\n *=========================================*/\n\nexport interface HardwareBuyerStore {\n hostId: string\n name: string\n /** Whether card readers can be registered to it: its Stripe Terminal Location exists. */\n hasLocation: boolean\n}\n\nexport interface HardwareBuyerWorkspace {\n orgId: string\n name: string\n /** Whether the workspace's plan includes the point of sale. */\n posPlan: boolean\n stores: HardwareBuyerStore[]\n}\n\nexport interface HardwareBuyerPerson {\n uid: string\n name: string\n /** Their email address, in full. */\n email: string\n workspaces: HardwareBuyerWorkspace[]\n}\n\nexport interface HardwareBuyerFindResult {\n kind: 'email' | 'name'\n people: HardwareBuyerPerson[]\n /** Workspaces whose name matched, each with the person it would be attached to. */\n workspaces: Array<HardwareBuyerWorkspace & { owner: Omit<HardwareBuyerPerson, 'workspaces'> | null }>\n /** An exact address with no account: sell anyway, invite, attach later. */\n noAccount: boolean\n}\n\n/** How many people, workspaces and stores one answer carries at most. */\nexport const BUYER_LOOKUP_LIMITS = { people: 8, workspaces: 8, workspacesPerPerson: 5, storesPerWorkspace: 10 }\n\nconst EXACT_EMAIL = /^[^@\\s]{1,64}@[^@\\s]+\\.[^@\\s]{2,}$/\n\nfunction firestore() {\n return firebaseAdmin.app().firestore()\n}\n\n/** The typed words, as the tokens are stored. */\nfunction words(query: string): string[] {\n return nameSearchKey(query)\n .split(' ')\n .filter(Boolean)\n .map((word) => [...word].slice(0, NAME_TOKEN_MAX_PREFIX).join(''))\n}\n\n/** Whether every typed word begins a word of `name`. */\nfunction nameMatches(name: string, typed: readonly string[]): boolean {\n const own = new Set(nameSearchTokens(name))\n return typed.length > 0 && typed.every((word) => own.has(word))\n}\n\n/** The longest typed word: the narrowest single `array-contains`. */\nfunction narrowest(typed: readonly string[]): string {\n return [...typed].sort((a, b) => b.length - a.length)[0] ?? ''\n}\n\nasync function storesOf(orgId: string): Promise<HardwareBuyerStore[]> {\n const hosts = await firestore()\n .collection('hosts')\n .where('orgId', '==', orgId)\n .limit(BUYER_LOOKUP_LIMITS.storesPerWorkspace)\n .get()\n return Promise.all(\n hosts.docs.map(async (doc: any) => {\n const config = await firestore()\n .collection('hosts')\n .doc(String(doc.id))\n .collection('terminal')\n .doc('config')\n .get()\n return {\n hostId: String(doc.id),\n name: hostDisplayName(doc.data() as Record<string, unknown>, String(doc.id)),\n hasLocation: Boolean(config.exists && config.get('stripeLocationId')),\n }\n }),\n )\n}\n\nasync function workspace(orgId: string, org?: Record<string, unknown>): Promise<HardwareBuyerWorkspace | null> {\n const data = org ?? ((await firestore().collection('orgs').doc(orgId).get()).data() as Record<string, unknown> | undefined)\n if (!data) return null\n return {\n orgId,\n name: String(data['name'] ?? '').trim() || 'Workspace',\n posPlan: Aglyn.checkEntitlement(data as never, 'pos'),\n stores: await storesOf(orgId),\n }\n}\n\n/** A row of a workspace's own roster, `orgs/{orgId}/members/{uid}`, and no other `members`. */\nfunction isRosterRow(doc: { ref?: any }): boolean {\n const parent = doc.ref?.parent?.parent\n return parent?.parent?.id === 'orgs'\n}\n\n/** The workspaces a person is on, by their roster rows. */\nasync function workspacesOf(uid: string): Promise<HardwareBuyerWorkspace[]> {\n const rows = await firestore()\n .collectionGroup('members')\n .where('uid', '==', uid)\n .limit(BUYER_LOOKUP_LIMITS.workspacesPerPerson)\n .get()\n const orgIds = [\n ...new Set(rows.docs.filter(isRosterRow).map((doc: any) => String(doc.ref.parent.parent.id))),\n ] as string[]\n return (await Promise.all(orgIds.map((orgId) => workspace(orgId)))).filter(\n (found): found is HardwareBuyerWorkspace => Boolean(found),\n )\n}\n\n/** The people whose name begins with every typed word, one per account. */\nasync function peopleNamed(typed: readonly string[]): Promise<Array<{ uid: string; name: string; email: string }>> {\n const rows = await firestore()\n .collectionGroup('members')\n .where('consoleUserType', 'in', ['manager', 'collaborator'])\n .where('searchTokens', 'array-contains', narrowest(typed))\n .limit(30)\n .get()\n const people = new Map<string, { uid: string; name: string; email: string }>()\n for (const doc of rows.docs as Array<{ id: string; ref?: any; data: () => Record<string, unknown> }>) {\n if (!isRosterRow(doc)) continue\n const data = doc.data()\n const uid = String(data['uid'] ?? doc.id)\n const name = String(data['displayName'] ?? '').trim()\n // A match on the address or the job title alone is not a match on a name.\n if (!uid || people.has(uid) || !nameMatches(name, typed)) continue\n people.set(uid, { uid, name, email: String(data['email'] ?? '') })\n if (people.size >= BUYER_LOOKUP_LIMITS.people) break\n }\n return [...people.values()]\n}\n\n/** The workspaces whose name begins with every typed word. */\nasync function workspacesNamed(typed: readonly string[]) {\n const orgs = await firestore()\n .collection('orgs')\n .where('nameTokens', 'array-contains', narrowest(typed))\n .limit(20)\n .get()\n const matched = (orgs.docs as Array<{ id: string; data: () => Record<string, unknown> }>)\n .filter((doc) => nameMatches(String(doc.data()['name'] ?? ''), typed))\n .slice(0, BUYER_LOOKUP_LIMITS.workspaces)\n return Promise.all(\n matched.map(async (doc) => {\n const data = doc.data()\n const found = (await workspace(String(doc.id), data)) as HardwareBuyerWorkspace\n const ownerUid = String(data['ownerUid'] ?? '')\n const owner = ownerUid\n ? await firestore().collection('orgs').doc(String(doc.id)).collection('members').doc(ownerUid).get()\n : null\n return {\n ...found,\n owner: owner?.exists\n ? {\n uid: ownerUid,\n name: String(owner.get('displayName') ?? '').trim(),\n email: String(owner.get('email') ?? ''),\n }\n : null,\n }\n }),\n )\n}\n\n/**\n * Looks a buyer up. An exact address is looked up as one; anything else as\n * a person's name and a workspace's. Every address is answered in full.\n */\nexport async function findHardwareBuyers(query: string): Promise<HardwareBuyerFindResult> {\n const text = query.trim()\n if (EXACT_EMAIL.test(text)) {\n const user = await findUserByEmailAcrossPools(text)\n if (!user) return { kind: 'email', people: [], workspaces: [], noAccount: true }\n const uid = user.record.uid\n return {\n kind: 'email',\n people: [\n {\n uid,\n name: String(user.record.displayName ?? '').trim(),\n email: text.toLowerCase(),\n workspaces: await workspacesOf(uid),\n },\n ],\n workspaces: [],\n noAccount: false,\n }\n }\n const typed = words(text)\n if (!typed.length) return { kind: 'name', people: [], workspaces: [], noAccount: false }\n const [named, workspaces] = await Promise.all([peopleNamed(typed), workspacesNamed(typed)])\n const people = await Promise.all(\n named.map(async (person) => ({\n uid: person.uid,\n name: person.name,\n email: person.email,\n workspaces: await workspacesOf(person.uid),\n })),\n )\n return { kind: 'name', people, workspaces, noAccount: false }\n}\n"],"names":["Aglyn","nameSearchKey","nameSearchTokens","NAME_TOKEN_MAX_PREFIX","firebaseAdmin","hostDisplayName","findUserByEmailAcrossPools","BUYER_LOOKUP_LIMITS","people","workspaces","workspacesPerPerson","storesPerWorkspace","EXACT_EMAIL","firestore","app","words","query","split","filter","Boolean","map","word","slice","join","nameMatches","name","typed","own","Set","length","every","has","narrowest","sort","a","b","storesOf","orgId","hosts","collection","where","limit","get","Promise","all","docs","doc","config","String","id","hostId","data","hasLocation","exists","workspace","org","trim","posPlan","checkEntitlement","stores","isRosterRow","parent","ref","workspacesOf","uid","rows","collectionGroup","orgIds","found","peopleNamed","Map","set","email","size","values","workspacesNamed","orgs","matched","owner","ownerUid","findHardwareBuyers","text","test","user","kind","noAccount","record","displayName","toLowerCase","named","person"],"mappings":"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"}
@@ -0,0 +1,29 @@
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
+ import { type PosHardwareAddress } from '../model/pos-hardware';
18
+ /** The address of a store's card reader Location, or null when it has none. */
19
+ export declare function posHardwareStoreAddress(hostId: string): Promise<PosHardwareAddress | null>;
20
+ /**
21
+ * Gives an attached in-person sale its buyer's address from their store's
22
+ * reader Location, with its sale record in the same transaction. Never
23
+ * throws: a sale left without an address keeps the buyer's name, and the
24
+ * next attach or reader set-up tries again. True when it wrote one.
25
+ */
26
+ export declare function fillPosHardwareBuyerAddress(input: {
27
+ orgId: string;
28
+ orderId: string;
29
+ }): Promise<boolean>;
@@ -0,0 +1,86 @@
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 { firebaseAdmin } from "@aglyn/tenant-data-admin";
18
+ import { posHardwareBuyerAddress, posHardwareOrderSource, posHardwareSaleRecord, posHardwareSaleSetOptions } from "../model/pos-hardware.js";
19
+ import { hardwareOrdersRef, posHardwareSaleRef } from "./pos-hardware.js";
20
+ import { posStripe } from "./pos-stripe.js";
21
+ /*==========================================
22
+ * THE BUYER'S ADDRESS ON AN IN-PERSON SALE (AGL-4038).
23
+ *
24
+ * The platform keeps each hardware buyer's name and address for its
25
+ * reseller records (`PosHardwareSaleBuyer`). An online order has the address
26
+ * it shipped to. A sale at the booth has none unless the register typed one,
27
+ * so the address of the store the buyer's readers are set up on stands in:
28
+ * the store's card reader Location, which Stripe holds. It is filled in once,
29
+ * the first time the sale is attached to a store that has one, and never
30
+ * replaces an address the register typed.
31
+ *=========================================*/ /** The address of a store's card reader Location, or null when it has none. */ export async function posHardwareStoreAddress(hostId) {
32
+ var _config_get, _ref;
33
+ var _location_body;
34
+ const config = await firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminal').doc('config').get();
35
+ const locationId = String((_config_get = config.get('stripeLocationId')) != null ? _config_get : '');
36
+ if (!/^tml_[A-Za-z0-9]+$/.test(locationId)) return null;
37
+ const location = await posStripe('GET', `terminal/locations/${locationId}`);
38
+ if (!location.ok) return null;
39
+ const address = (_ref = (_location_body = location.body) == null ? void 0 : _location_body.address) != null ? _ref : {};
40
+ return posHardwareBuyerAddress({
41
+ line1: address['line1'],
42
+ line2: address['line2'],
43
+ city: address['city'],
44
+ state: address['state'],
45
+ postalCode: address['postal_code'],
46
+ country: address['country']
47
+ });
48
+ }
49
+ /** An attached in-person sale on a store, with no address for its buyer yet. */ function wantsStoreAddress(order) {
50
+ var _order_attachment;
51
+ return Boolean(order && posHardwareOrderSource(order) === 'in_person' && ((_order_attachment = order.attachment) == null ? void 0 : _order_attachment.state) === 'attached' && order.attachment.hostId && !order.attachment.address);
52
+ }
53
+ /**
54
+ * Gives an attached in-person sale its buyer's address from their store's
55
+ * reader Location, with its sale record in the same transaction. Never
56
+ * throws: a sale left without an address keeps the buyer's name, and the
57
+ * next attach or reader set-up tries again. True when it wrote one.
58
+ */ export async function fillPosHardwareBuyerAddress(input) {
59
+ try {
60
+ var _before_attachment;
61
+ const ref = hardwareOrdersRef(input.orgId).doc(input.orderId);
62
+ const before = (await ref.get()).data();
63
+ if (!wantsStoreAddress(before)) return false;
64
+ const address = await posHardwareStoreAddress(String((_before_attachment = before.attachment) == null ? void 0 : _before_attachment.hostId));
65
+ if (!address) return false;
66
+ return await firebaseAdmin.app().firestore().runTransaction(async (transaction)=>{
67
+ var _now_attachment, _before_attachment;
68
+ const now = (await transaction.get(ref)).data();
69
+ if (!wantsStoreAddress(now) || ((_now_attachment = now.attachment) == null ? void 0 : _now_attachment.hostId) !== ((_before_attachment = before.attachment) == null ? void 0 : _before_attachment.hostId)) return false;
70
+ const after = _extends({}, now, {
71
+ attachment: _extends({}, now.attachment, {
72
+ address
73
+ }),
74
+ updatedAtMs: Date.now()
75
+ });
76
+ transaction.set(ref, after);
77
+ transaction.set(posHardwareSaleRef(input.orderId), posHardwareSaleRecord(input.orderId, after), posHardwareSaleSetOptions(after));
78
+ return true;
79
+ });
80
+ } catch (error) {
81
+ console.error('[pos-hardware] the buyer’s store address was not recorded', input.orderId, error);
82
+ return false;
83
+ }
84
+ }
85
+
86
+ //# sourceMappingURL=pos-hardware-buyer-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-hardware-buyer-record.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\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport {\n posHardwareBuyerAddress,\n posHardwareOrderSource,\n posHardwareSaleRecord,\n posHardwareSaleSetOptions,\n type PosHardwareAddress,\n type PosHardwareAttachment,\n type PosHardwareOrder,\n} from '../model/pos-hardware'\nimport { hardwareOrdersRef, posHardwareSaleRef } from './pos-hardware'\nimport { posStripe } from './pos-stripe'\n\n/*==========================================\n * THE BUYER'S ADDRESS ON AN IN-PERSON SALE (AGL-4038).\n *\n * The platform keeps each hardware buyer's name and address for its\n * reseller records (`PosHardwareSaleBuyer`). An online order has the address\n * it shipped to. A sale at the booth has none unless the register typed one,\n * so the address of the store the buyer's readers are set up on stands in:\n * the store's card reader Location, which Stripe holds. It is filled in once,\n * the first time the sale is attached to a store that has one, and never\n * replaces an address the register typed.\n *=========================================*/\n\n/** The address of a store's card reader Location, or null when it has none. */\nexport async function posHardwareStoreAddress(hostId: string): Promise<PosHardwareAddress | null> {\n const config = await firebaseAdmin\n .app()\n .firestore()\n .collection('hosts')\n .doc(hostId)\n .collection('terminal')\n .doc('config')\n .get()\n const locationId = String(config.get('stripeLocationId') ?? '')\n if (!/^tml_[A-Za-z0-9]+$/.test(locationId)) return null\n const location = await posStripe('GET', `terminal/locations/${locationId}`)\n if (!location.ok) return null\n const address = (location.body?.address ?? {}) as Record<string, unknown>\n return posHardwareBuyerAddress({\n line1: address['line1'],\n line2: address['line2'],\n city: address['city'],\n state: address['state'],\n postalCode: address['postal_code'],\n country: address['country'],\n })\n}\n\n/** An attached in-person sale on a store, with no address for its buyer yet. */\nfunction wantsStoreAddress(order: PosHardwareOrder | undefined): order is PosHardwareOrder {\n return Boolean(\n order &&\n posHardwareOrderSource(order) === 'in_person' &&\n order.attachment?.state === 'attached' &&\n order.attachment.hostId &&\n !order.attachment.address,\n )\n}\n\n/**\n * Gives an attached in-person sale its buyer's address from their store's\n * reader Location, with its sale record in the same transaction. Never\n * throws: a sale left without an address keeps the buyer's name, and the\n * next attach or reader set-up tries again. True when it wrote one.\n */\nexport async function fillPosHardwareBuyerAddress(input: { orgId: string; orderId: string }): Promise<boolean> {\n try {\n const ref = hardwareOrdersRef(input.orgId).doc(input.orderId)\n const before = (await ref.get()).data() as PosHardwareOrder | undefined\n if (!wantsStoreAddress(before)) return false\n const address = await posHardwareStoreAddress(String(before.attachment?.hostId))\n if (!address) return false\n return await firebaseAdmin\n .app()\n .firestore()\n .runTransaction(async (transaction: any) => {\n const now = (await transaction.get(ref)).data() as PosHardwareOrder | undefined\n if (!wantsStoreAddress(now) || now.attachment?.hostId !== before.attachment?.hostId) return false\n const after: PosHardwareOrder = {\n ...now,\n attachment: { ...(now.attachment as PosHardwareAttachment), address },\n updatedAtMs: Date.now(),\n }\n transaction.set(ref, after)\n transaction.set(\n posHardwareSaleRef(input.orderId),\n posHardwareSaleRecord(input.orderId, after),\n posHardwareSaleSetOptions(after),\n )\n return true\n })\n } catch (error) {\n console.error('[pos-hardware] the buyer’s store address was not recorded', input.orderId, error)\n return false\n }\n}\n"],"names":["firebaseAdmin","posHardwareBuyerAddress","posHardwareOrderSource","posHardwareSaleRecord","posHardwareSaleSetOptions","hardwareOrdersRef","posHardwareSaleRef","posStripe","posHardwareStoreAddress","hostId","config","location","app","firestore","collection","doc","get","locationId","String","test","ok","address","body","line1","line2","city","state","postalCode","country","wantsStoreAddress","order","Boolean","attachment","fillPosHardwareBuyerAddress","input","before","ref","orgId","orderId","data","runTransaction","transaction","now","after","updatedAtMs","Date","set","error","console"],"mappings":"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"}
@@ -0,0 +1,58 @@
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
+ import { type PosHardwareCancelReason, type PosHardwareOrder } from '../model/pos-hardware';
18
+ /** What became of one cancel. */
19
+ export type PosHardwareCancelResult =
20
+ /** Refunded now (or Stripe's earlier refund recovered) and settled. */
21
+ {
22
+ outcome: 'settled';
23
+ before: PosHardwareOrder;
24
+ order: PosHardwareOrder;
25
+ }
26
+ /** It already had the final status: nothing was asked of Stripe. */
27
+ | {
28
+ outcome: 'already';
29
+ order: PosHardwareOrder;
30
+ } | {
31
+ outcome: 'missing';
32
+ }
33
+ /** Shipped, delivered, registered, or canceled the other way. */
34
+ | {
35
+ outcome: 'not-refundable';
36
+ order: PosHardwareOrder;
37
+ } | {
38
+ outcome: 'no-payment';
39
+ order: PosHardwareOrder;
40
+ }
41
+ /** Stripe refused; the claim was released and the order is as it was. */
42
+ | {
43
+ outcome: 'refused';
44
+ order: PosHardwareOrder;
45
+ message: string;
46
+ code: string | null;
47
+ };
48
+ export interface PosHardwareCancelRequest {
49
+ orgId: string;
50
+ orderId: string;
51
+ /** `canceled` for a cancel (staff or closure), `refunded` for a staff refund. */
52
+ finalStatus: 'canceled' | 'refunded';
53
+ reason: PosHardwareCancelReason;
54
+ now?: () => number;
55
+ }
56
+ /** The idempotency key every caller refunds an order under. */
57
+ export declare function posHardwareRefundKey(orderId: string): string;
58
+ export declare function cancelAndRefundPosHardwareOrder(request: PosHardwareCancelRequest): Promise<PosHardwareCancelResult>;
@@ -0,0 +1,147 @@
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 { firebaseAdmin } from "@aglyn/tenant-data-admin";
18
+ import { POS_HARDWARE_STATUS_STAMP, posHardwareRefundable, posHardwareSaleRecord, posHardwareSaleSetOptions } from "../model/pos-hardware.js";
19
+ import { hardwareOrdersRef, posHardwareSaleRef } from "./pos-hardware.js";
20
+ import { posStripe } from "./pos-stripe.js";
21
+ /** The idempotency key every caller refunds an order under. */ export function posHardwareRefundKey(orderId) {
22
+ return `pos-hw-refund-${orderId}`;
23
+ }
24
+ /**
25
+ * The refund Stripe already made on this payment, for a charge it refuses as
26
+ * already refunded: the earlier ask settled at Stripe and never reached the
27
+ * order (a crash between the two, or an ask after Stripe's key window).
28
+ */ async function existingRefund(paymentIntentId) {
29
+ var _found_amount;
30
+ var _listed_body, _listed_body1;
31
+ const listed = await posStripe('GET', 'refunds', {
32
+ params: {
33
+ payment_intent: paymentIntentId,
34
+ limit: 10
35
+ }
36
+ }).catch(()=>null);
37
+ const refunds = Array.isArray(listed == null ? void 0 : (_listed_body = listed.body) == null ? void 0 : _listed_body.data) ? listed == null ? void 0 : (_listed_body1 = listed.body) == null ? void 0 : _listed_body1.data : [];
38
+ const found = refunds.find((refund)=>(refund == null ? void 0 : refund['id']) && ((refund == null ? void 0 : refund['status']) === 'succeeded' || (refund == null ? void 0 : refund['status']) === 'pending'));
39
+ return found ? {
40
+ id: String(found['id']),
41
+ amount: Number((_found_amount = found['amount']) != null ? _found_amount : 0)
42
+ } : null;
43
+ }
44
+ export async function cancelAndRefundPosHardwareOrder(request) {
45
+ var _request_now, _asked_body_amount, _ref, _before_totalCents;
46
+ var _asked_body, _asked_body_error, _asked_body1;
47
+ const { orgId, orderId, finalStatus, reason } = request;
48
+ const now = (_request_now = request.now) != null ? _request_now : Date.now;
49
+ const firestore = firebaseAdmin.app().firestore();
50
+ const ref = hardwareOrdersRef(orgId).doc(orderId);
51
+ const claim = await firestore.runTransaction(async (transaction)=>{
52
+ const snapshot = await transaction.get(ref);
53
+ if (!snapshot.exists) return {
54
+ outcome: 'missing'
55
+ };
56
+ const order = snapshot.data();
57
+ if (order.status === finalStatus) return {
58
+ outcome: 'already',
59
+ order
60
+ };
61
+ if (!posHardwareRefundable(order.status)) return {
62
+ outcome: 'not-refundable',
63
+ order
64
+ };
65
+ if (!order.stripePaymentIntentId) return {
66
+ outcome: 'no-payment',
67
+ order
68
+ };
69
+ transaction.update(ref, {
70
+ refundRequestedAtMs: now()
71
+ });
72
+ return {
73
+ outcome: 'claimed',
74
+ order
75
+ };
76
+ });
77
+ if (claim.outcome !== 'claimed') return claim;
78
+ const before = claim.order;
79
+ const asked = await posStripe('POST', 'refunds', {
80
+ // The same parameters for every caller: see the module note.
81
+ params: {
82
+ payment_intent: before.stripePaymentIntentId,
83
+ 'metadata[type]': 'pos-hardware-order',
84
+ 'metadata[orderId]': orderId,
85
+ 'metadata[orgId]': orgId
86
+ },
87
+ idempotencyKey: posHardwareRefundKey(orderId)
88
+ });
89
+ let refund = asked.ok && ((_asked_body = asked.body) == null ? void 0 : _asked_body.id) ? {
90
+ id: String(asked.body.id),
91
+ amount: Number((_asked_body_amount = asked.body.amount) != null ? _asked_body_amount : 0)
92
+ } : null;
93
+ const code = asked.ok ? null : String((_ref = (_asked_body1 = asked.body) == null ? void 0 : (_asked_body_error = _asked_body1.error) == null ? void 0 : _asked_body_error.code) != null ? _ref : '') || null;
94
+ if (!refund && code === 'charge_already_refunded') {
95
+ refund = await existingRefund(String(before.stripePaymentIntentId));
96
+ }
97
+ if (!refund) {
98
+ var _ref1;
99
+ var _asked_body_error1, _asked_body2;
100
+ await ref.update({
101
+ refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete()
102
+ }).catch(()=>undefined);
103
+ console.error('[pos-hardware] refund refused', orderId, asked.status, code);
104
+ const settledBefore = _extends({}, before);
105
+ delete settledBefore.refundRequestedAtMs;
106
+ return {
107
+ outcome: 'refused',
108
+ order: settledBefore,
109
+ message: String((_ref1 = (_asked_body2 = asked.body) == null ? void 0 : (_asked_body_error1 = _asked_body2.error) == null ? void 0 : _asked_body_error1.message) != null ? _ref1 : '') || 'Stripe refused the refund.',
110
+ code
111
+ };
112
+ }
113
+ const at = now();
114
+ const refundedCents = refund.amount > 0 ? refund.amount : Number((_before_totalCents = before.totalCents) != null ? _before_totalCents : 0);
115
+ const patch = {
116
+ status: finalStatus,
117
+ [POS_HARDWARE_STATUS_STAMP[finalStatus]]: at,
118
+ updatedAtMs: at,
119
+ refundId: refund.id,
120
+ refundedCents,
121
+ cancelReason: reason,
122
+ refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete()
123
+ };
124
+ const settled = _extends({}, before);
125
+ delete settled.refundRequestedAtMs;
126
+ const after = _extends({}, settled, {
127
+ status: finalStatus,
128
+ [POS_HARDWARE_STATUS_STAMP[finalStatus]]: at,
129
+ updatedAtMs: at,
130
+ refundId: refund.id,
131
+ refundedCents,
132
+ cancelReason: reason
133
+ });
134
+ // The order and its retained sale record move together: the record is
135
+ // what the refund is accounted from once the workspace is gone.
136
+ await firestore.runTransaction(async (transaction)=>{
137
+ transaction.update(ref, patch);
138
+ transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after), posHardwareSaleSetOptions(after));
139
+ });
140
+ return {
141
+ outcome: 'settled',
142
+ before: settled,
143
+ order: after
144
+ };
145
+ }
146
+
147
+ //# sourceMappingURL=pos-hardware-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-hardware-cancel.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\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport {\n POS_HARDWARE_STATUS_STAMP,\n posHardwareRefundable,\n posHardwareSaleRecord,\n posHardwareSaleSetOptions,\n type PosHardwareCancelReason,\n type PosHardwareOrder,\n} from '../model/pos-hardware'\nimport { hardwareOrdersRef, posHardwareSaleRef } from './pos-hardware'\nimport { posStripe } from './pos-stripe'\n\n/*==========================================\n * CANCELING AND REFUNDING A HARDWARE ORDER IN FULL (AGL-4038).\n *\n * One path for every caller: staff on the Hardware orders page, and the\n * closures (a workspace deleted, the buying account closed) that cancel every\n * order of theirs that has not shipped. Each refunds the whole payment on the\n * PLATFORM account, only before the order ships, and only once:\n *\n * 1. CLAIM under the lock: the order must still be paid or ordered, and\n * `refundRequestedAtMs` is set, so it cannot be marked shipped while the\n * money is on its way back.\n * 2. REFUND through Stripe under ONE idempotency key per order,\n * `pos-hw-refund-{orderId}`, with the same parameters whoever asks — a\n * key replayed with different parameters is refused by Stripe, so no\n * caller adds its own. A second ask inside Stripe's key window gets the\n * first refund back; after it, Stripe refuses the charge as already\n * refunded, and the refund it already made is read back instead of a\n * second one made.\n * 3. SETTLE: the order and its retained sale record move together, in one\n * transaction, with the refund id, the cents Stripe reported and why.\n *\n * Stripe refusing releases the claim, so the order can still ship. Telling\n * people (the buyer, staff) and the audit row are the caller's: staff and a\n * closure say different things.\n *=========================================*/\n\n/** What became of one cancel. */\nexport type PosHardwareCancelResult =\n /** Refunded now (or Stripe's earlier refund recovered) and settled. */\n | { outcome: 'settled'; before: PosHardwareOrder; order: PosHardwareOrder }\n /** It already had the final status: nothing was asked of Stripe. */\n | { outcome: 'already'; order: PosHardwareOrder }\n | { outcome: 'missing' }\n /** Shipped, delivered, registered, or canceled the other way. */\n | { outcome: 'not-refundable'; order: PosHardwareOrder }\n | { outcome: 'no-payment'; order: PosHardwareOrder }\n /** Stripe refused; the claim was released and the order is as it was. */\n | { outcome: 'refused'; order: PosHardwareOrder; message: string; code: string | null }\n\nexport interface PosHardwareCancelRequest {\n orgId: string\n orderId: string\n /** `canceled` for a cancel (staff or closure), `refunded` for a staff refund. */\n finalStatus: 'canceled' | 'refunded'\n reason: PosHardwareCancelReason\n now?: () => number\n}\n\ntype ClaimedOrder = PosHardwareOrder & { refundRequestedAtMs?: number }\n\n/** The idempotency key every caller refunds an order under. */\nexport function posHardwareRefundKey(orderId: string): string {\n return `pos-hw-refund-${orderId}`\n}\n\n/**\n * The refund Stripe already made on this payment, for a charge it refuses as\n * already refunded: the earlier ask settled at Stripe and never reached the\n * order (a crash between the two, or an ask after Stripe's key window).\n */\nasync function existingRefund(paymentIntentId: string): Promise<{ id: string; amount: number } | null> {\n const listed = await posStripe('GET', 'refunds', {\n params: { payment_intent: paymentIntentId, limit: 10 },\n }).catch(() => null)\n const refunds = Array.isArray(listed?.body?.data) ? (listed?.body?.data as Array<Record<string, unknown>>) : []\n const found = refunds.find(\n (refund) => refund?.['id'] && (refund?.['status'] === 'succeeded' || refund?.['status'] === 'pending'),\n )\n return found ? { id: String(found['id']), amount: Number(found['amount'] ?? 0) } : null\n}\n\nexport async function cancelAndRefundPosHardwareOrder(\n request: PosHardwareCancelRequest,\n): Promise<PosHardwareCancelResult> {\n const { orgId, orderId, finalStatus, reason } = request\n const now = request.now ?? Date.now\n const firestore = firebaseAdmin.app().firestore()\n const ref = hardwareOrdersRef(orgId).doc(orderId)\n\n const claim = await firestore.runTransaction(async (transaction: any): Promise<PosHardwareCancelResult | { outcome: 'claimed'; order: ClaimedOrder }> => {\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) return { outcome: 'missing' }\n const order = snapshot.data() as ClaimedOrder\n if (order.status === finalStatus) return { outcome: 'already', order }\n if (!posHardwareRefundable(order.status)) return { outcome: 'not-refundable', order }\n if (!order.stripePaymentIntentId) return { outcome: 'no-payment', order }\n transaction.update(ref, { refundRequestedAtMs: now() })\n return { outcome: 'claimed', order }\n })\n if (claim.outcome !== 'claimed') return claim\n const before = claim.order\n\n const asked = await posStripe('POST', 'refunds', {\n // The same parameters for every caller: see the module note.\n params: {\n payment_intent: before.stripePaymentIntentId,\n 'metadata[type]': 'pos-hardware-order',\n 'metadata[orderId]': orderId,\n 'metadata[orgId]': orgId,\n },\n idempotencyKey: posHardwareRefundKey(orderId),\n })\n let refund: { id: string; amount: number } | null =\n asked.ok && asked.body?.id ? { id: String(asked.body.id), amount: Number(asked.body.amount ?? 0) } : null\n const code = asked.ok ? null : String(asked.body?.error?.code ?? '') || null\n if (!refund && code === 'charge_already_refunded') {\n refund = await existingRefund(String(before.stripePaymentIntentId))\n }\n if (!refund) {\n await ref.update({ refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete() }).catch(() => undefined)\n console.error('[pos-hardware] refund refused', orderId, asked.status, code)\n const settledBefore = { ...before }\n delete settledBefore.refundRequestedAtMs\n return {\n outcome: 'refused',\n order: settledBefore,\n message: String(asked.body?.error?.message ?? '') || 'Stripe refused the refund.',\n code,\n }\n }\n\n const at = now()\n const refundedCents = refund.amount > 0 ? refund.amount : Number(before.totalCents ?? 0)\n const patch = {\n status: finalStatus,\n [POS_HARDWARE_STATUS_STAMP[finalStatus]]: at,\n updatedAtMs: at,\n refundId: refund.id,\n refundedCents,\n cancelReason: reason,\n refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete(),\n }\n const settled: ClaimedOrder = { ...before }\n delete settled.refundRequestedAtMs\n const after: PosHardwareOrder = {\n ...settled,\n status: finalStatus,\n [POS_HARDWARE_STATUS_STAMP[finalStatus]]: at,\n updatedAtMs: at,\n refundId: refund.id,\n refundedCents,\n cancelReason: reason,\n }\n // The order and its retained sale record move together: the record is\n // what the refund is accounted from once the workspace is gone.\n await firestore.runTransaction(async (transaction: any) => {\n transaction.update(ref, patch)\n transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after), posHardwareSaleSetOptions(after))\n })\n return { outcome: 'settled', before: settled, order: after }\n}\n"],"names":["firebaseAdmin","POS_HARDWARE_STATUS_STAMP","posHardwareRefundable","posHardwareSaleRecord","posHardwareSaleSetOptions","hardwareOrdersRef","posHardwareSaleRef","posStripe","posHardwareRefundKey","orderId","existingRefund","paymentIntentId","found","listed","params","payment_intent","limit","catch","refunds","Array","isArray","body","data","find","refund","id","String","amount","Number","cancelAndRefundPosHardwareOrder","request","asked","before","orgId","finalStatus","reason","now","Date","firestore","app","ref","doc","claim","runTransaction","transaction","snapshot","get","exists","outcome","order","status","stripePaymentIntentId","update","refundRequestedAtMs","idempotencyKey","ok","code","error","FieldValue","delete","undefined","console","settledBefore","message","at","refundedCents","totalCents","patch","updatedAtMs","refundId","cancelReason","settled","after","set"],"mappings":"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"}