@aglyn/plugins-commerce 1.0.0-beta.229 → 1.0.0-beta.231

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 (590) hide show
  1. package/package.json +13 -13
  2. package/src/index.d.ts +0 -1
  3. package/src/index.js +0 -1
  4. package/src/index.js.map +1 -1
  5. package/src/lib/barcode/barcode-decode.d.ts +71 -0
  6. package/src/lib/barcode/barcode-decode.js +498 -0
  7. package/src/lib/barcode/barcode-decode.js.map +1 -0
  8. package/src/lib/barcode/barcode-encode.d.ts +44 -0
  9. package/src/lib/barcode/barcode-encode.js +138 -0
  10. package/src/lib/barcode/barcode-encode.js.map +1 -0
  11. package/src/lib/barcode/barcode-scanner.component.d.ts +23 -0
  12. package/src/lib/barcode/barcode-scanner.component.js +260 -0
  13. package/src/lib/barcode/barcode-scanner.component.js.map +1 -0
  14. package/src/lib/barcode/scan-button.component.d.ts +10 -0
  15. package/src/lib/barcode/scan-button.component.js +62 -0
  16. package/src/lib/barcode/scan-button.component.js.map +1 -0
  17. package/src/lib/barcode/scanner-wedge.d.ts +35 -0
  18. package/src/lib/barcode/scanner-wedge.js +108 -0
  19. package/src/lib/barcode/scanner-wedge.js.map +1 -0
  20. package/src/lib/components/account.js +10 -1
  21. package/src/lib/components/account.js.map +1 -1
  22. package/src/lib/components/cart-extras.d.ts +45 -0
  23. package/src/lib/components/cart-extras.js +127 -0
  24. package/src/lib/components/cart-extras.js.map +1 -0
  25. package/src/lib/components/cart.js +82 -15
  26. package/src/lib/components/cart.js.map +1 -1
  27. package/src/lib/components/checkout-return-notice.d.ts +26 -0
  28. package/src/lib/components/checkout-return-notice.js +48 -0
  29. package/src/lib/components/checkout-return-notice.js.map +1 -0
  30. package/src/lib/components/commerce-console-page.js +124 -0
  31. package/src/lib/components/commerce-console-page.js.map +1 -1
  32. package/src/lib/components/commerce-console-sections.d.ts +1 -1
  33. package/src/lib/components/commerce-console-sections.js +4 -0
  34. package/src/lib/components/commerce-console-sections.js.map +1 -1
  35. package/src/lib/components/console/bulk-fulfill.d.ts +44 -0
  36. package/src/lib/components/console/bulk-fulfill.js +84 -0
  37. package/src/lib/components/console/bulk-fulfill.js.map +1 -0
  38. package/src/lib/components/console/customer-notifications-card.component.d.ts +19 -0
  39. package/src/lib/components/console/customer-notifications-card.component.js +149 -0
  40. package/src/lib/components/console/customer-notifications-card.component.js.map +1 -0
  41. package/src/lib/components/console/host-orders-card.component.js +84 -5
  42. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  43. package/src/lib/components/console/locations-card.component.js +164 -57
  44. package/src/lib/components/console/locations-card.component.js.map +1 -1
  45. package/src/lib/components/console/order-detail-dialog.component.js +209 -61
  46. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  47. package/src/lib/components/console/order-fulfillment-panel.component.d.ts +48 -0
  48. package/src/lib/components/console/order-fulfillment-panel.component.js +542 -0
  49. package/src/lib/components/console/order-fulfillment-panel.component.js.map +1 -0
  50. package/src/lib/components/console/order-invoice.component.d.ts +33 -0
  51. package/src/lib/components/console/order-invoice.component.js +81 -0
  52. package/src/lib/components/console/order-invoice.component.js.map +1 -0
  53. package/src/lib/components/console/order-receipt-resend.component.d.ts +21 -0
  54. package/src/lib/components/console/order-receipt-resend.component.js +203 -0
  55. package/src/lib/components/console/order-receipt-resend.component.js.map +1 -0
  56. package/src/lib/components/console/order-returns.component.d.ts +36 -0
  57. package/src/lib/components/console/order-returns.component.js +142 -0
  58. package/src/lib/components/console/order-returns.component.js.map +1 -0
  59. package/src/lib/components/console/order-shipping-actions.component.d.ts +54 -0
  60. package/src/lib/components/console/order-shipping-actions.component.js +149 -0
  61. package/src/lib/components/console/order-shipping-actions.component.js.map +1 -0
  62. package/src/lib/components/console/order-webhooks-card.component.d.ts +50 -0
  63. package/src/lib/components/console/order-webhooks-card.component.js +623 -0
  64. package/src/lib/components/console/order-webhooks-card.component.js.map +1 -0
  65. package/src/lib/components/console/order-zones.d.ts +155 -0
  66. package/src/lib/components/console/order-zones.js +40 -0
  67. package/src/lib/components/console/order-zones.js.map +1 -0
  68. package/src/lib/components/console/payment-methods-card.component.d.ts +67 -0
  69. package/src/lib/components/console/payment-methods-card.component.js +395 -0
  70. package/src/lib/components/console/payment-methods-card.component.js.map +1 -0
  71. package/src/lib/components/console/pos/pos-api.d.ts +124 -0
  72. package/src/lib/components/console/pos/pos-api.js +101 -0
  73. package/src/lib/components/console/pos/pos-api.js.map +1 -0
  74. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +36 -0
  75. package/src/lib/components/console/pos/pos-cart-panel.component.js +160 -0
  76. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -0
  77. package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +39 -0
  78. package/src/lib/components/console/pos/pos-item-dialog.component.js +352 -0
  79. package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -0
  80. package/src/lib/components/console/pos/pos-product-grid.component.d.ts +47 -0
  81. package/src/lib/components/console/pos/pos-product-grid.component.js +272 -0
  82. package/src/lib/components/console/pos/pos-product-grid.component.js.map +1 -0
  83. package/src/lib/components/console/pos/pos-receipt-panel.component.d.ts +27 -0
  84. package/src/lib/components/console/pos/pos-receipt-panel.component.js +282 -0
  85. package/src/lib/components/console/pos/pos-receipt-panel.component.js.map +1 -0
  86. package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +53 -0
  87. package/src/lib/components/console/pos/pos-tender-dialogs.component.js +445 -0
  88. package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -0
  89. package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +31 -0
  90. package/src/lib/components/console/pos/pos-tender-panel.component.js +640 -0
  91. package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -0
  92. package/src/lib/components/console/pos/use-pos-display.d.ts +43 -0
  93. package/src/lib/components/console/pos/use-pos-display.js +161 -0
  94. package/src/lib/components/console/pos/use-pos-display.js.map +1 -0
  95. package/src/lib/components/console/pos-devices-card.component.d.ts +14 -0
  96. package/src/lib/components/console/pos-devices-card.component.js +546 -0
  97. package/src/lib/components/console/pos-devices-card.component.js.map +1 -0
  98. package/src/lib/components/console/pos-display/brand-screen.d.ts +33 -0
  99. package/src/lib/components/console/pos-display/brand-screen.js +85 -0
  100. package/src/lib/components/console/pos-display/brand-screen.js.map +1 -0
  101. package/src/lib/components/console/pos-display/cart-screen.d.ts +29 -0
  102. package/src/lib/components/console/pos-display/cart-screen.js +166 -0
  103. package/src/lib/components/console/pos-display/cart-screen.js.map +1 -0
  104. package/src/lib/components/console/pos-display/pairing-screen.d.ts +24 -0
  105. package/src/lib/components/console/pos-display/pairing-screen.js +127 -0
  106. package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -0
  107. package/src/lib/components/console/pos-display/pos-display-api.d.ts +90 -0
  108. package/src/lib/components/console/pos-display/pos-display-api.js +140 -0
  109. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -0
  110. package/src/lib/components/console/pos-display/receipt-screen.d.ts +35 -0
  111. package/src/lib/components/console/pos-display/receipt-screen.js +200 -0
  112. package/src/lib/components/console/pos-display/receipt-screen.js.map +1 -0
  113. package/src/lib/components/console/pos-display/tip-screen.d.ts +36 -0
  114. package/src/lib/components/console/pos-display/tip-screen.js +211 -0
  115. package/src/lib/components/console/pos-display/tip-screen.js.map +1 -0
  116. package/src/lib/components/console/pos-display-page.component.d.ts +16 -0
  117. package/src/lib/components/console/pos-display-page.component.js +407 -0
  118. package/src/lib/components/console/pos-display-page.component.js.map +1 -0
  119. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +40 -0
  120. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +289 -0
  121. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -0
  122. package/src/lib/components/console/pos-ops/pos-last-receipt.component.d.ts +34 -0
  123. package/src/lib/components/console/pos-ops/pos-last-receipt.component.js +61 -0
  124. package/src/lib/components/console/pos-ops/pos-last-receipt.component.js.map +1 -0
  125. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +38 -0
  126. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +129 -0
  127. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -0
  128. package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +37 -0
  129. package/src/lib/components/console/pos-ops/pos-ops-api.js +60 -0
  130. package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -0
  131. package/src/lib/components/console/pos-ops/pos-pin-pad.component.d.ts +48 -0
  132. package/src/lib/components/console/pos-ops/pos-pin-pad.component.js +220 -0
  133. package/src/lib/components/console/pos-ops/pos-pin-pad.component.js.map +1 -0
  134. package/src/lib/components/console/pos-ops/pos-receipt-actions.component.d.ts +63 -0
  135. package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js +186 -0
  136. package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js.map +1 -0
  137. package/src/lib/components/console/pos-ops/pos-receipt.d.ts +39 -0
  138. package/src/lib/components/console/pos-ops/pos-receipt.js +182 -0
  139. package/src/lib/components/console/pos-ops/pos-receipt.js.map +1 -0
  140. package/src/lib/components/console/pos-ops/pos-return-dialog.component.d.ts +40 -0
  141. package/src/lib/components/console/pos-ops/pos-return-dialog.component.js +465 -0
  142. package/src/lib/components/console/pos-ops/pos-return-dialog.component.js.map +1 -0
  143. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.d.ts +29 -0
  144. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +253 -0
  145. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -0
  146. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +34 -0
  147. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +494 -0
  148. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -0
  149. package/src/lib/components/console/pos-ops/pos-shift-report.component.d.ts +37 -0
  150. package/src/lib/components/console/pos-ops/pos-shift-report.component.js +102 -0
  151. package/src/lib/components/console/pos-ops/pos-shift-report.component.js.map +1 -0
  152. package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.d.ts +30 -0
  153. package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js +277 -0
  154. package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js.map +1 -0
  155. package/src/lib/components/console/pos-ops/register-ops.d.ts +28 -0
  156. package/src/lib/components/console/pos-ops/register-ops.js +28 -0
  157. package/src/lib/components/console/pos-ops/register-ops.js.map +1 -0
  158. package/src/lib/components/console/pos-ops/use-pos-cashier.d.ts +46 -0
  159. package/src/lib/components/console/pos-ops/use-pos-cashier.js +128 -0
  160. package/src/lib/components/console/pos-ops/use-pos-cashier.js.map +1 -0
  161. package/src/lib/components/console/pos-ops/use-pos-sale-receipt.d.ts +36 -0
  162. package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js +64 -0
  163. package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js.map +1 -0
  164. package/src/lib/components/console/pos-page.component.d.ts +13 -5
  165. package/src/lib/components/console/pos-page.component.js +729 -657
  166. package/src/lib/components/console/pos-page.component.js.map +1 -1
  167. package/src/lib/components/console/product-editor-dialog.component.js +51 -7
  168. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  169. package/src/lib/components/console/product-labels-dialog.component.d.ts +13 -0
  170. package/src/lib/components/console/product-labels-dialog.component.js +197 -0
  171. package/src/lib/components/console/product-labels-dialog.component.js.map +1 -0
  172. package/src/lib/components/console/product-register-fields.component.d.ts +19 -0
  173. package/src/lib/components/console/product-register-fields.component.js +241 -0
  174. package/src/lib/components/console/product-register-fields.component.js.map +1 -0
  175. package/src/lib/components/console/product-zones.d.ts +58 -2
  176. package/src/lib/components/console/product-zones.js +10 -2
  177. package/src/lib/components/console/product-zones.js.map +1 -1
  178. package/src/lib/components/console/products-hub-card.component.js +51 -11
  179. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  180. package/src/lib/components/console/register-hardware-card.component.d.ts +33 -0
  181. package/src/lib/components/console/register-hardware-card.component.js +826 -0
  182. package/src/lib/components/console/register-hardware-card.component.js.map +1 -0
  183. package/src/lib/components/console/registers-card.component.js +24 -5
  184. package/src/lib/components/console/registers-card.component.js.map +1 -1
  185. package/src/lib/components/console/return-actions.d.ts +38 -0
  186. package/src/lib/components/console/return-actions.js +76 -0
  187. package/src/lib/components/console/return-actions.js.map +1 -0
  188. package/src/lib/components/console/return-detail-dialog.component.d.ts +34 -0
  189. package/src/lib/components/console/return-detail-dialog.component.js +718 -0
  190. package/src/lib/components/console/return-detail-dialog.component.js.map +1 -0
  191. package/src/lib/components/console/return-settings-card.component.d.ts +34 -0
  192. package/src/lib/components/console/return-settings-card.component.js +195 -0
  193. package/src/lib/components/console/return-settings-card.component.js.map +1 -0
  194. package/src/lib/components/console/return-zones.d.ts +87 -0
  195. package/src/lib/components/console/return-zones.js +31 -0
  196. package/src/lib/components/console/return-zones.js.map +1 -0
  197. package/src/lib/components/console/returns-card.component.d.ts +45 -0
  198. package/src/lib/components/console/returns-card.component.js +159 -0
  199. package/src/lib/components/console/returns-card.component.js.map +1 -0
  200. package/src/lib/components/console/shipping-settings-card.component.js +161 -5
  201. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
  202. package/src/lib/components/console/shippingeasy-card.component.d.ts +59 -0
  203. package/src/lib/components/console/shippingeasy-card.component.js +378 -0
  204. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -0
  205. package/src/lib/components/console/shipstation-card.component.d.ts +35 -0
  206. package/src/lib/components/console/shipstation-card.component.js +345 -0
  207. package/src/lib/components/console/shipstation-card.component.js.map +1 -0
  208. package/src/lib/components/console/start-return-dialog.component.d.ts +40 -0
  209. package/src/lib/components/console/start-return-dialog.component.js +243 -0
  210. package/src/lib/components/console/start-return-dialog.component.js.map +1 -0
  211. package/src/lib/components/console/stock-movements-card.component.js +2 -1
  212. package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
  213. package/src/lib/components/console/store-settings-card.component.js +2 -66
  214. package/src/lib/components/console/store-settings-card.component.js.map +1 -1
  215. package/src/lib/components/console/store-zones.d.ts +42 -0
  216. package/src/lib/components/console/store-zones.js +39 -0
  217. package/src/lib/components/console/store-zones.js.map +1 -0
  218. package/src/lib/components/order-status.d.ts +36 -0
  219. package/src/lib/components/order-status.js +502 -0
  220. package/src/lib/components/order-status.js.map +1 -0
  221. package/src/lib/components/product-detail.js +44 -2
  222. package/src/lib/components/product-detail.js.map +1 -1
  223. package/src/lib/components/return-request.d.ts +32 -0
  224. package/src/lib/components/return-request.js +576 -0
  225. package/src/lib/components/return-request.js.map +1 -0
  226. package/src/lib/components/storefront-payment-appearance.d.ts +32 -0
  227. package/src/lib/components/storefront-payment-appearance.js +114 -0
  228. package/src/lib/components/storefront-payment-appearance.js.map +1 -0
  229. package/src/lib/components/storefront-payment-element.d.ts +57 -1
  230. package/src/lib/components/storefront-payment-element.js +332 -33
  231. package/src/lib/components/storefront-payment-element.js.map +1 -1
  232. package/src/lib/constants/order-status.d.ts +22 -0
  233. package/src/lib/constants/order-status.js +22 -0
  234. package/src/lib/constants/order-status.js.map +1 -0
  235. package/src/lib/constants/return-request.d.ts +27 -0
  236. package/src/lib/constants/return-request.js +32 -0
  237. package/src/lib/constants/return-request.js.map +1 -0
  238. package/src/lib/constants/stock-movement-query.js +2 -1
  239. package/src/lib/constants/stock-movement-query.js.map +1 -1
  240. package/src/lib/declarations.console-server.js +9 -0
  241. package/src/lib/declarations.console-server.js.map +1 -1
  242. package/src/lib/declarations.server.d.ts +2 -1
  243. package/src/lib/declarations.server.js +47 -1
  244. package/src/lib/declarations.server.js.map +1 -1
  245. package/src/lib/model/buyer-notifications.d.ts +59 -0
  246. package/src/lib/model/buyer-notifications.js +97 -0
  247. package/src/lib/model/buyer-notifications.js.map +1 -0
  248. package/src/lib/model/commerce-orders.d.ts +127 -1
  249. package/src/lib/model/commerce-orders.js +24 -15
  250. package/src/lib/model/commerce-orders.js.map +1 -1
  251. package/src/lib/model/commerce-payment-methods.d.ts +146 -0
  252. package/src/lib/model/commerce-payment-methods.js +247 -0
  253. package/src/lib/model/commerce-payment-methods.js.map +1 -0
  254. package/src/lib/model/commerce-pos-ops.d.ts +437 -0
  255. package/src/lib/model/commerce-pos-ops.js +721 -0
  256. package/src/lib/model/commerce-pos-ops.js.map +1 -0
  257. package/src/lib/model/commerce-pos.d.ts +263 -0
  258. package/src/lib/model/commerce-pos.js +375 -0
  259. package/src/lib/model/commerce-pos.js.map +1 -0
  260. package/src/lib/model/commerce-printers.d.ts +211 -0
  261. package/src/lib/model/commerce-printers.js +181 -0
  262. package/src/lib/model/commerce-printers.js.map +1 -0
  263. package/src/lib/model/commerce-receipt.d.ts +97 -0
  264. package/src/lib/model/commerce-receipt.js +180 -0
  265. package/src/lib/model/commerce-receipt.js.map +1 -0
  266. package/src/lib/model/commerce-returns.d.ts +207 -0
  267. package/src/lib/model/commerce-returns.js +300 -0
  268. package/src/lib/model/commerce-returns.js.map +1 -0
  269. package/src/lib/model/commerce-shipping.d.ts +44 -1
  270. package/src/lib/model/commerce-shipping.js +53 -9
  271. package/src/lib/model/commerce-shipping.js.map +1 -1
  272. package/src/lib/model/commerce-tax-engine.d.ts +90 -0
  273. package/src/lib/model/commerce-tax-engine.js +129 -0
  274. package/src/lib/model/commerce-tax-engine.js.map +1 -0
  275. package/src/lib/model/commerce.d.ts +88 -2
  276. package/src/lib/model/commerce.js +89 -1
  277. package/src/lib/model/commerce.js.map +1 -1
  278. package/src/lib/model/index.d.ts +15 -0
  279. package/src/lib/model/index.js +15 -0
  280. package/src/lib/model/index.js.map +1 -1
  281. package/src/lib/model/order-events.d.ts +154 -0
  282. package/src/lib/model/order-events.js +153 -0
  283. package/src/lib/model/order-events.js.map +1 -0
  284. package/src/lib/model/order-fulfillment.d.ts +117 -0
  285. package/src/lib/model/order-fulfillment.js +217 -0
  286. package/src/lib/model/order-fulfillment.js.map +1 -0
  287. package/src/lib/model/order-history.d.ts +58 -0
  288. package/src/lib/model/order-history.js +22 -0
  289. package/src/lib/model/order-history.js.map +1 -0
  290. package/src/lib/model/order-list-fields.d.ts +9 -1
  291. package/src/lib/model/order-list-fields.js +7 -1
  292. package/src/lib/model/order-list-fields.js.map +1 -1
  293. package/src/lib/model/order-shipping-export.d.ts +91 -0
  294. package/src/lib/model/order-shipping-export.js +192 -0
  295. package/src/lib/model/order-shipping-export.js.map +1 -0
  296. package/src/lib/model/order-status-view.d.ts +103 -0
  297. package/src/lib/model/order-status-view.js +156 -0
  298. package/src/lib/model/order-status-view.js.map +1 -0
  299. package/src/lib/model/order-webhooks.d.ts +142 -0
  300. package/src/lib/model/order-webhooks.js +91 -0
  301. package/src/lib/model/order-webhooks.js.map +1 -0
  302. package/src/lib/model/product-channel.d.ts +56 -0
  303. package/src/lib/model/product-channel.js +86 -0
  304. package/src/lib/model/product-channel.js.map +1 -0
  305. package/src/lib/model/product-modifiers.d.ts +80 -0
  306. package/src/lib/model/product-modifiers.js +140 -0
  307. package/src/lib/model/product-modifiers.js.map +1 -0
  308. package/src/lib/model/shippingeasy.d.ts +94 -0
  309. package/src/lib/model/shippingeasy.js +267 -0
  310. package/src/lib/model/shippingeasy.js.map +1 -0
  311. package/src/lib/model/shipstation.d.ts +125 -0
  312. package/src/lib/model/shipstation.js +399 -0
  313. package/src/lib/model/shipstation.js.map +1 -0
  314. package/src/lib/model/smart-collection-reads.d.ts +32 -0
  315. package/src/lib/model/smart-collection-reads.js +63 -0
  316. package/src/lib/model/smart-collection-reads.js.map +1 -0
  317. package/src/lib/model/tracking-url.d.ts +74 -0
  318. package/src/lib/model/tracking-url.js +159 -0
  319. package/src/lib/model/tracking-url.js.map +1 -0
  320. package/src/lib/plugin-config.d.ts +13 -0
  321. package/src/lib/plugin-config.js +77 -5
  322. package/src/lib/plugin-config.js.map +1 -1
  323. package/src/lib/plugin.js +23 -0
  324. package/src/lib/plugin.js.map +1 -1
  325. package/src/lib/pos-ops-config.d.ts +39 -0
  326. package/src/lib/pos-ops-config.js +88 -0
  327. package/src/lib/pos-ops-config.js.map +1 -0
  328. package/src/lib/printing/print-document.d.ts +106 -0
  329. package/src/lib/printing/print-document.js +464 -0
  330. package/src/lib/printing/print-document.js.map +1 -0
  331. package/src/lib/printing/product-labels.d.ts +58 -0
  332. package/src/lib/printing/product-labels.js +116 -0
  333. package/src/lib/printing/product-labels.js.map +1 -0
  334. package/src/lib/printing/render-epson.d.ts +57 -0
  335. package/src/lib/printing/render-epson.js +135 -0
  336. package/src/lib/printing/render-epson.js.map +1 -0
  337. package/src/lib/printing/render-star.d.ts +45 -0
  338. package/src/lib/printing/render-star.js +100 -0
  339. package/src/lib/printing/render-star.js.map +1 -0
  340. package/src/lib/printing/render-text.d.ts +25 -0
  341. package/src/lib/printing/render-text.js +53 -0
  342. package/src/lib/printing/render-text.js.map +1 -0
  343. package/src/lib/server/api-v1/openapi.js +27 -4
  344. package/src/lib/server/api-v1/openapi.js.map +1 -1
  345. package/src/lib/server/api-v1/order-view.d.ts +67 -0
  346. package/src/lib/server/api-v1/order-view.js +120 -0
  347. package/src/lib/server/api-v1/order-view.js.map +1 -0
  348. package/src/lib/server/api-v1/orders-and-products.js +58 -65
  349. package/src/lib/server/api-v1/orders-and-products.js.map +1 -1
  350. package/src/lib/server/billing-webhook.js +135 -28
  351. package/src/lib/server/billing-webhook.js.map +1 -1
  352. package/src/lib/server/cancel-order.js +29 -0
  353. package/src/lib/server/cancel-order.js.map +1 -1
  354. package/src/lib/server/carrier-rates-availability.d.ts +26 -0
  355. package/src/lib/server/carrier-rates-availability.js +76 -0
  356. package/src/lib/server/carrier-rates-availability.js.map +1 -0
  357. package/src/lib/server/carrier-shipping.d.ts +84 -0
  358. package/src/lib/server/carrier-shipping.js +135 -0
  359. package/src/lib/server/carrier-shipping.js.map +1 -0
  360. package/src/lib/server/cart-checkout.d.ts +2 -0
  361. package/src/lib/server/cart-checkout.js +226 -22
  362. package/src/lib/server/cart-checkout.js.map +1 -1
  363. package/src/lib/server/checkout-extras.d.ts +64 -0
  364. package/src/lib/server/checkout-extras.js +157 -0
  365. package/src/lib/server/checkout-extras.js.map +1 -0
  366. package/src/lib/server/{feed.d.ts → checkout-status.d.ts} +2 -7
  367. package/src/lib/server/checkout-status.js +111 -0
  368. package/src/lib/server/checkout-status.js.map +1 -0
  369. package/src/lib/server/checkout.js +86 -9
  370. package/src/lib/server/checkout.js.map +1 -1
  371. package/src/lib/server/draft-order.js +34 -5
  372. package/src/lib/server/draft-order.js.map +1 -1
  373. package/src/lib/server/fulfill-order.d.ts +127 -10
  374. package/src/lib/server/fulfill-order.js +451 -49
  375. package/src/lib/server/fulfill-order.js.map +1 -1
  376. package/src/lib/server/legacy-feed.d.ts +28 -0
  377. package/src/lib/server/legacy-feed.js +52 -0
  378. package/src/lib/server/legacy-feed.js.map +1 -0
  379. package/src/lib/server/native-checkout.d.ts +34 -15
  380. package/src/lib/server/native-checkout.js +32 -17
  381. package/src/lib/server/native-checkout.js.map +1 -1
  382. package/src/lib/server/order-event-host-emit.d.ts +23 -0
  383. package/src/lib/server/order-event-host-emit.js +30 -0
  384. package/src/lib/server/order-event-host-emit.js.map +1 -0
  385. package/src/lib/server/order-event-triggers.d.ts +37 -0
  386. package/src/lib/server/order-event-triggers.js +119 -0
  387. package/src/lib/server/order-event-triggers.js.map +1 -0
  388. package/src/lib/server/order-events.d.ts +62 -0
  389. package/src/lib/server/order-events.js +109 -0
  390. package/src/lib/server/order-events.js.map +1 -0
  391. package/src/lib/server/order-history.d.ts +23 -0
  392. package/src/lib/server/order-history.js +65 -0
  393. package/src/lib/server/order-history.js.map +1 -0
  394. package/src/lib/server/order-notifications.d.ts +185 -0
  395. package/src/lib/server/order-notifications.js +567 -0
  396. package/src/lib/server/order-notifications.js.map +1 -0
  397. package/src/lib/server/order-receipt-send.d.ts +39 -0
  398. package/src/lib/server/order-receipt-send.js +151 -0
  399. package/src/lib/server/order-receipt-send.js.map +1 -0
  400. package/src/lib/server/order-status-token.d.ts +31 -0
  401. package/src/lib/server/order-status-token.js +75 -0
  402. package/src/lib/server/order-status-token.js.map +1 -0
  403. package/src/lib/server/order-status.d.ts +58 -0
  404. package/src/lib/server/order-status.js +141 -0
  405. package/src/lib/server/order-status.js.map +1 -0
  406. package/src/lib/server/order-webhooks.d.ts +108 -0
  407. package/src/lib/server/order-webhooks.js +622 -0
  408. package/src/lib/server/order-webhooks.js.map +1 -0
  409. package/src/lib/server/orders-shipping-prepare.d.ts +26 -0
  410. package/src/lib/server/orders-shipping-prepare.js +121 -0
  411. package/src/lib/server/orders-shipping-prepare.js.map +1 -0
  412. package/src/lib/server/payment-method-domains.d.ts +209 -0
  413. package/src/lib/server/payment-method-domains.js +444 -0
  414. package/src/lib/server/payment-method-domains.js.map +1 -0
  415. package/src/lib/server/payment-methods.d.ts +77 -0
  416. package/src/lib/server/payment-methods.js +284 -0
  417. package/src/lib/server/payment-methods.js.map +1 -0
  418. package/src/lib/server/pos-auth.d.ts +50 -0
  419. package/src/lib/server/pos-auth.js +121 -0
  420. package/src/lib/server/pos-auth.js.map +1 -0
  421. package/src/lib/server/pos-customer.d.ts +49 -0
  422. package/src/lib/server/pos-customer.js +257 -0
  423. package/src/lib/server/pos-customer.js.map +1 -0
  424. package/src/lib/server/pos-display.d.ts +57 -0
  425. package/src/lib/server/pos-display.js +419 -0
  426. package/src/lib/server/pos-display.js.map +1 -0
  427. package/src/lib/server/pos-fee-month.d.ts +34 -0
  428. package/src/lib/server/pos-fee-month.js +36 -0
  429. package/src/lib/server/pos-fee-month.js.map +1 -0
  430. package/src/lib/server/pos-ops-gate.d.ts +161 -0
  431. package/src/lib/server/pos-ops-gate.js +295 -0
  432. package/src/lib/server/pos-ops-gate.js.map +1 -0
  433. package/src/lib/server/pos-ops-routes.d.ts +22 -0
  434. package/src/lib/server/pos-ops-routes.js +36 -0
  435. package/src/lib/server/pos-ops-routes.js.map +1 -0
  436. package/src/lib/server/pos-order.d.ts +1 -18
  437. package/src/lib/server/pos-order.js +222 -42
  438. package/src/lib/server/pos-order.js.map +1 -1
  439. package/src/lib/server/pos-payment.d.ts +39 -0
  440. package/src/lib/server/pos-payment.js +922 -0
  441. package/src/lib/server/pos-payment.js.map +1 -0
  442. package/src/lib/server/pos-print.d.ts +82 -0
  443. package/src/lib/server/pos-print.js +193 -0
  444. package/src/lib/server/pos-print.js.map +1 -0
  445. package/src/lib/server/pos-readers.d.ts +27 -0
  446. package/src/lib/server/pos-readers.js +276 -0
  447. package/src/lib/server/pos-readers.js.map +1 -0
  448. package/src/lib/server/pos-refund-authority.d.ts +60 -0
  449. package/src/lib/server/pos-refund-authority.js +72 -0
  450. package/src/lib/server/pos-refund-authority.js.map +1 -0
  451. package/src/lib/server/pos-return.d.ts +58 -0
  452. package/src/lib/server/pos-return.js +891 -0
  453. package/src/lib/server/pos-return.js.map +1 -0
  454. package/src/lib/server/pos-sale-stamp.d.ts +66 -0
  455. package/src/lib/server/pos-sale-stamp.js +84 -0
  456. package/src/lib/server/pos-sale-stamp.js.map +1 -0
  457. package/src/lib/server/pos-sale.d.ts +170 -0
  458. package/src/lib/server/pos-sale.js +461 -0
  459. package/src/lib/server/pos-sale.js.map +1 -0
  460. package/src/lib/server/pos-shift.d.ts +45 -0
  461. package/src/lib/server/pos-shift.js +484 -0
  462. package/src/lib/server/pos-shift.js.map +1 -0
  463. package/src/lib/server/pos-staff-pin.d.ts +26 -0
  464. package/src/lib/server/pos-staff-pin.js +339 -0
  465. package/src/lib/server/pos-staff-pin.js.map +1 -0
  466. package/src/lib/server/pos-stripe.d.ts +91 -0
  467. package/src/lib/server/pos-stripe.js +129 -0
  468. package/src/lib/server/pos-stripe.js.map +1 -0
  469. package/src/lib/server/pos-terminal-connection-token.d.ts +48 -0
  470. package/src/lib/server/pos-terminal-connection-token.js +166 -0
  471. package/src/lib/server/pos-terminal-connection-token.js.map +1 -0
  472. package/src/lib/server/pos-terminal.d.ts +218 -0
  473. package/src/lib/server/pos-terminal.js +1014 -0
  474. package/src/lib/server/pos-terminal.js.map +1 -0
  475. package/src/lib/server/print-queue.d.ts +124 -0
  476. package/src/lib/server/print-queue.js +301 -0
  477. package/src/lib/server/print-queue.js.map +1 -0
  478. package/src/lib/server/printer-poll.d.ts +75 -0
  479. package/src/lib/server/printer-poll.js +325 -0
  480. package/src/lib/server/printer-poll.js.map +1 -0
  481. package/src/lib/server/printer-secret.d.ts +39 -0
  482. package/src/lib/server/printer-secret.js +56 -0
  483. package/src/lib/server/printer-secret.js.map +1 -0
  484. package/src/lib/server/printers.d.ts +114 -0
  485. package/src/lib/server/printers.js +546 -0
  486. package/src/lib/server/printers.js.map +1 -0
  487. package/src/lib/server/product-ai-capability.d.ts +42 -0
  488. package/src/lib/server/product-ai-capability.js +159 -0
  489. package/src/lib/server/product-ai-capability.js.map +1 -0
  490. package/src/lib/server/product-catalog.d.ts +42 -0
  491. package/src/lib/server/product-catalog.js +305 -0
  492. package/src/lib/server/product-catalog.js.map +1 -0
  493. package/src/lib/server/product-drafts.d.ts +119 -0
  494. package/src/lib/server/product-drafts.js +384 -0
  495. package/src/lib/server/product-drafts.js.map +1 -0
  496. package/src/lib/server/refund.js +110 -45
  497. package/src/lib/server/refund.js.map +1 -1
  498. package/src/lib/server/reserve.js +2 -0
  499. package/src/lib/server/reserve.js.map +1 -1
  500. package/src/lib/server/return-status-action.d.ts +37 -0
  501. package/src/lib/server/return-status-action.js +57 -0
  502. package/src/lib/server/return-status-action.js.map +1 -0
  503. package/src/lib/server/returns.d.ts +119 -0
  504. package/src/lib/server/returns.js +938 -0
  505. package/src/lib/server/returns.js.map +1 -0
  506. package/src/lib/server/shipment-records.d.ts +36 -0
  507. package/src/lib/server/shipment-records.js +289 -0
  508. package/src/lib/server/shipment-records.js.map +1 -0
  509. package/src/lib/server/shipping-connector-gates.d.ts +40 -0
  510. package/src/lib/server/shipping-connector-gates.js +97 -0
  511. package/src/lib/server/shipping-connector-gates.js.map +1 -0
  512. package/src/lib/server/shipping-connectors.d.ts +29 -0
  513. package/src/lib/server/shipping-connectors.js +236 -0
  514. package/src/lib/server/shipping-connectors.js.map +1 -0
  515. package/src/lib/server/shippingeasy.d.ts +238 -0
  516. package/src/lib/server/shippingeasy.js +787 -0
  517. package/src/lib/server/shippingeasy.js.map +1 -0
  518. package/src/lib/server/shipstation.d.ts +129 -0
  519. package/src/lib/server/shipstation.js +483 -0
  520. package/src/lib/server/shipstation.js.map +1 -0
  521. package/src/lib/server/site-page-resolver.d.ts +5 -0
  522. package/src/lib/server/site-page-resolver.js +156 -1
  523. package/src/lib/server/site-page-resolver.js.map +1 -1
  524. package/src/lib/server/stock-levels.d.ts +21 -0
  525. package/src/lib/server/stock-levels.js +263 -0
  526. package/src/lib/server/stock-levels.js.map +1 -0
  527. package/src/lib/server/stripe-refund.d.ts +47 -0
  528. package/src/lib/server/stripe-refund.js +87 -0
  529. package/src/lib/server/stripe-refund.js.map +1 -0
  530. package/src/lib/server/supplier-update.js +46 -5
  531. package/src/lib/server/supplier-update.js.map +1 -1
  532. package/src/lib/server/tax-engine-quote.d.ts +47 -0
  533. package/src/lib/server/tax-engine-quote.js +105 -0
  534. package/src/lib/server/tax-engine-quote.js.map +1 -0
  535. package/src/lib/server.js +146 -2
  536. package/src/lib/server.js.map +1 -1
  537. package/src/lib/site.js +12 -0
  538. package/src/lib/site.js.map +1 -1
  539. package/src/lib/subprocessors.d.ts +26 -0
  540. package/src/lib/subprocessors.js +50 -0
  541. package/src/lib/subprocessors.js.map +1 -0
  542. package/src/lib/tenant-emails.js +461 -3
  543. package/src/lib/tenant-emails.js.map +1 -1
  544. package/src/lib/testing/fake-firestore.d.ts +45 -0
  545. package/src/lib/testing/fake-firestore.js +189 -0
  546. package/src/lib/testing/fake-firestore.js.map +1 -0
  547. package/src/lib/testing/memory-firestore.d.ts +123 -0
  548. package/src/lib/testing/memory-firestore.js +274 -0
  549. package/src/lib/testing/memory-firestore.js.map +1 -0
  550. package/src/lib/testing/pos-ops-harness.d.ts +50 -0
  551. package/src/lib/testing/pos-ops-harness.js +184 -0
  552. package/src/lib/testing/pos-ops-harness.js.map +1 -0
  553. package/src/lib/testing/pos-ops-memory-firestore.d.ts +55 -0
  554. package/src/lib/testing/pos-ops-memory-firestore.js +376 -0
  555. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -0
  556. package/src/lib/transfer/records-transfer.d.ts +11 -1
  557. package/src/lib/transfer/records-transfer.js +127 -5
  558. package/src/lib/transfer/records-transfer.js.map +1 -1
  559. package/src/lib/transfer/records.server.d.ts +9 -2
  560. package/src/lib/transfer/records.server.js +58 -7
  561. package/src/lib/transfer/records.server.js.map +1 -1
  562. package/src/lib/transfer/register-transfer-resources.js +40 -1
  563. package/src/lib/transfer/register-transfer-resources.js.map +1 -1
  564. package/src/lib/transfer/register-transfer-ui.js +4 -1
  565. package/src/lib/transfer/register-transfer-ui.js.map +1 -1
  566. package/src/lib/transfer/shipping-presets.d.ts +23 -0
  567. package/src/lib/transfer/shipping-presets.js +156 -0
  568. package/src/lib/transfer/shipping-presets.js.map +1 -0
  569. package/src/lib/transfer/tracking-transfer.d.ts +101 -0
  570. package/src/lib/transfer/tracking-transfer.js +546 -0
  571. package/src/lib/transfer/tracking-transfer.js.map +1 -0
  572. package/src/lib/transfer/tracking.server.d.ts +37 -0
  573. package/src/lib/transfer/tracking.server.js +393 -0
  574. package/src/lib/transfer/tracking.server.js.map +1 -0
  575. package/src/lib/transfer/transfer-keys.d.ts +2 -1
  576. package/src/lib/transfer/transfer-keys.js +6 -2
  577. package/src/lib/transfer/transfer-keys.js.map +1 -1
  578. package/src/lib/utils/code128.d.ts +37 -0
  579. package/src/lib/utils/code128.js +199 -0
  580. package/src/lib/utils/code128.js.map +1 -0
  581. package/src/lib/utils/order-invoice.d.ts +55 -0
  582. package/src/lib/utils/order-invoice.js +127 -0
  583. package/src/lib/utils/order-invoice.js.map +1 -0
  584. package/src/lib/utils/use-checkout-return-notice.d.ts +34 -0
  585. package/src/lib/utils/use-checkout-return-notice.js +78 -0
  586. package/src/lib/utils/use-checkout-return-notice.js.map +1 -0
  587. package/src/lib/utils/use-storefront-purchase-event.js +4 -0
  588. package/src/lib/utils/use-storefront-purchase-event.js.map +1 -1
  589. package/src/lib/server/feed.js +0 -69
  590. package/src/lib/server/feed.js.map +0 -1
@@ -15,7 +15,12 @@
15
15
  * limitations under the License.
16
16
  */ import { _ as _extends } from "@swc/helpers/_/_extends";
17
17
  import { hostCollectionKind } from "@aglyn/aglyn/server";
18
- import composeScreenNodes from "@aglyn/tenant-runtime/compose-screen-nodes";
18
+ import composeScreenNodes, { composeNodesWithChrome } from "@aglyn/tenant-runtime/compose-screen-nodes";
19
+ import { resolveBuiltInPageLayoutId } from "@aglyn/tenant-runtime/built-in-page-layout";
20
+ import * as Aglyn from "@aglyn/aglyn/server";
21
+ import { ORDER_STATUS_PATH } from "./order-status-token.js";
22
+ import { ORDER_STATUS_COMPONENT_ID } from "../constants/order-status.js";
23
+ import { RETURN_REQUEST_COMPONENT_ID, RETURN_REQUEST_PATH } from "../constants/return-request.js";
19
24
  import getScreen from "@aglyn/tenant-runtime/get-screen";
20
25
  import { collectSocialImageFacts } from "@aglyn/tenant-runtime/social-image-facts";
21
26
  import { firebaseAdmin } from "@aglyn/tenant-data-admin";
@@ -39,6 +44,20 @@ import { readProductReviews } from "./reviews.js";
39
44
  // block hydrates variants client-side from the same slug. Same
40
45
  // mechanism as entry-template screens below.
41
46
  const pdpSegments = path.split('/').filter(Boolean);
47
+ // The guest order-status page (AGL-3610), at /order-status — reached only
48
+ // when the site has no page of its own there. The site's header and footer
49
+ // around the order-status block, which reads the signed `?o=&t=` link after
50
+ // hydration, so this page holds no order and is safe to cache. UNLISTED, so
51
+ // the head says noindex: it is a private page, not a landing page.
52
+ if (pdpSegments.length === 1 && pdpSegments[0] === ORDER_STATUS_PATH) {
53
+ return composeOrderStatusPage(hostId, host);
54
+ }
55
+ // The buyer's return form (AGL-3611), at /order-return, under the same
56
+ // terms: no page of the site's own there, the order read after hydration
57
+ // from the link's `?o=&t=` (or the member's session), UNLISTED.
58
+ if (pdpSegments.length === 1 && pdpSegments[0] === RETURN_REQUEST_PATH) {
59
+ return composeReturnRequestPage(hostId, host);
60
+ }
42
61
  if (pdpSegments.length === 2 && pdpSegments[0] === 'products') {
43
62
  var _productSnapshot_docs_;
44
63
  const adminFirestore = firebaseAdmin.app().firestore();
@@ -240,5 +259,141 @@ import { readProductReviews } from "./reviews.js";
240
259
  }
241
260
  return undefined;
242
261
  };
262
+ const ORDER_STATUS_NODE = 'order-status__block';
263
+ /** The order-status page's node tree, root first, for the layout's slot. */ export function buildOrderStatusNodes() {
264
+ return {
265
+ [Aglyn.NODE_ROOT_ID]: {
266
+ $id: Aglyn.NODE_ROOT_ID,
267
+ componentId: 'div',
268
+ nodes: [
269
+ 'order-status__container'
270
+ ]
271
+ },
272
+ 'order-status__container': {
273
+ $id: 'order-status__container',
274
+ parentId: Aglyn.NODE_ROOT_ID,
275
+ componentId: 'muiContainer',
276
+ pluginId: 'mui',
277
+ props: {
278
+ maxWidth: 'md',
279
+ sx: {
280
+ paddingTop: 6,
281
+ paddingBottom: 8
282
+ }
283
+ },
284
+ nodes: [
285
+ ORDER_STATUS_NODE
286
+ ]
287
+ },
288
+ [ORDER_STATUS_NODE]: {
289
+ $id: ORDER_STATUS_NODE,
290
+ parentId: 'order-status__container',
291
+ componentId: ORDER_STATUS_COMPONENT_ID,
292
+ pluginId: 'commerce',
293
+ props: {}
294
+ }
295
+ };
296
+ }
297
+ async function composeOrderStatusPage(hostId, host) {
298
+ try {
299
+ const layoutId = await resolveBuiltInPageLayoutId({
300
+ hostId,
301
+ host: host
302
+ });
303
+ const nodes = await composeNodesWithChrome({
304
+ hostId,
305
+ layoutId,
306
+ screenNodes: buildOrderStatusNodes(),
307
+ host: host
308
+ });
309
+ if (!nodes) return undefined;
310
+ return {
311
+ props: JSON.parse(JSON.stringify({
312
+ data: {
313
+ host,
314
+ screen: {
315
+ data: {
316
+ displayName: 'Order status',
317
+ visibility: Aglyn.HostScreenVisibility.UNLISTED
318
+ }
319
+ }
320
+ },
321
+ nodes
322
+ })),
323
+ revalidate: 3600
324
+ };
325
+ } catch (error) {
326
+ console.error('order status page composition failed', error);
327
+ return undefined;
328
+ }
329
+ }
330
+ const RETURN_REQUEST_NODE = 'ret__block';
331
+ /** The return form's node tree, root first, for the layout's slot. */ export function buildReturnRequestNodes() {
332
+ return {
333
+ [Aglyn.NODE_ROOT_ID]: {
334
+ $id: Aglyn.NODE_ROOT_ID,
335
+ componentId: 'div',
336
+ nodes: [
337
+ 'ret__container'
338
+ ]
339
+ },
340
+ ret__container: {
341
+ $id: 'ret__container',
342
+ parentId: Aglyn.NODE_ROOT_ID,
343
+ componentId: 'muiContainer',
344
+ pluginId: 'mui',
345
+ props: {
346
+ maxWidth: 'md',
347
+ sx: {
348
+ paddingTop: 6,
349
+ paddingBottom: 8
350
+ }
351
+ },
352
+ nodes: [
353
+ RETURN_REQUEST_NODE
354
+ ]
355
+ },
356
+ [RETURN_REQUEST_NODE]: {
357
+ $id: RETURN_REQUEST_NODE,
358
+ parentId: 'ret__container',
359
+ componentId: RETURN_REQUEST_COMPONENT_ID,
360
+ pluginId: 'commerce',
361
+ props: {}
362
+ }
363
+ };
364
+ }
365
+ async function composeReturnRequestPage(hostId, host) {
366
+ try {
367
+ const layoutId = await resolveBuiltInPageLayoutId({
368
+ hostId,
369
+ host: host
370
+ });
371
+ const nodes = await composeNodesWithChrome({
372
+ hostId,
373
+ layoutId,
374
+ screenNodes: buildReturnRequestNodes(),
375
+ host: host
376
+ });
377
+ if (!nodes) return undefined;
378
+ return {
379
+ props: JSON.parse(JSON.stringify({
380
+ data: {
381
+ host,
382
+ screen: {
383
+ data: {
384
+ displayName: 'Request a return',
385
+ visibility: Aglyn.HostScreenVisibility.UNLISTED
386
+ }
387
+ }
388
+ },
389
+ nodes
390
+ })),
391
+ revalidate: 3600
392
+ };
393
+ } catch (error) {
394
+ console.error('return request page composition failed', error);
395
+ return undefined;
396
+ }
397
+ }
243
398
 
244
399
  //# sourceMappingURL=site-page-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/site-page-resolver.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 type { SitePageResolver } from '@aglyn/aglyn/server'\nimport { hostCollectionKind } from '@aglyn/aglyn/server'\nimport composeScreenNodes from '@aglyn/tenant-runtime/compose-screen-nodes'\nimport getScreen from '@aglyn/tenant-runtime/get-screen'\nimport { collectSocialImageFacts } from '@aglyn/tenant-runtime/social-image-facts'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport * as CommerceModel from '../model'\nimport { toPublicProductDetail } from './product'\nimport { readProductReviews } from './reviews'\n\n/**\n * Commerce page resolver (AGL-292/298/418), relocated verbatim from the\n * tenant loader: /products/{slug} renders the host's designated PDP\n * template with product tokens, /collections/{slug} the collection\n * template — both compose server-side and return complete page props.\n * Runs only for paths that didn't match a published screen; returns\n * undefined for everything else so the loader falls through.\n */\nexport const commerceSitePageResolver: SitePageResolver = async ({\n hostId,\n host,\n path,\n}) => {\n const hostRes = { host }\n // Product detail routes (AGL-292): /products/{slug} renders the\n // host's designated PDP template screen (settings/store\n // `pdpScreenId`, AGL-295) with product tokens; the product-detail\n // block hydrates variants client-side from the same slug. Same\n // mechanism as entry-template screens below.\n const pdpSegments = path.split('/').filter(Boolean)\n if (pdpSegments.length === 2 && pdpSegments[0] === 'products') {\n const adminFirestore = firebaseAdmin.app().firestore()\n const hostDocRef = adminFirestore.collection('hosts').doc(hostId)\n const [storeSettings, productSnapshot] = await Promise.all([\n hostDocRef.collection('settings').doc('store').get(),\n hostDocRef\n .collection('products')\n .where('slug', '==', pdpSegments[1])\n .limit(1)\n .get(),\n ])\n const pdpScreenId = storeSettings.get('pdpScreenId')\n const productRaw = productSnapshot.docs[0]?.data() as any\n if (\n pdpScreenId &&\n productRaw &&\n !productRaw.deletedAt &&\n productRaw.status === 'active'\n ) {\n const product = CommerceModel.liftLegacyProduct(productRaw)\n const templateRes = await getScreen({\n hostId,\n screenId: pdpScreenId,\n // A PDP template renders against a routed PRODUCT, never at an address\n // of its own, so it is served here and 404s everywhere else (AGL-1400).\n allowTemplate: true,\n })\n if (templateRes.screen) {\n const [minPrice, maxPrice] = CommerceModel.productPriceRange(product)\n // Best-effort: a reviews read that fails costs the page its rating\n // snippet, not the page.\n const productReviews = await readProductReviews(\n hostId,\n productSnapshot.docs[0].id,\n ).catch((error) => {\n console.error('product review aggregate failed', error)\n return { reviews: [], aggregate: { count: 0, average: 0 } }\n })\n // The head shares this page as the template's image, then the site\n // default, so their documents are read in the template's own batch\n // (AGL-2850).\n const card = collectSocialImageFacts([\n (templateRes.screen as any).seo?.image,\n hostRes.host?.seo?.image,\n ])\n const templateNodes = await composeScreenNodes({\n hostId,\n screenId: pdpScreenId,\n screen: templateRes.screen,\n socialImages: card.socialImages,\n // The template's host variables, and its layout's, fill in from\n // this site as they do on every other page (AGL-2883).\n host: hostRes.host,\n tokens: {\n 'product.name': product.name,\n 'product.description': product.description ?? '',\n 'product.price':\n minPrice === maxPrice\n ? `$${minPrice}`\n : `From $${minPrice}`,\n 'product.image':\n product.mediaUrls?.[0] ?? product.imageUrl ?? '',\n 'product.slug': product.slug,\n },\n // Named as the product template it is if the page review holds it\n // (AGL-3374); without it the route has no page.\n page: {\n template: {\n role: 'entry',\n route: '/products/:slug',\n collectionName: 'Products',\n entryPath: `/products/${product.slug}`,\n fallback: 'not-found',\n },\n },\n })\n if (templateNodes) {\n return {\n props: JSON.parse(\n JSON.stringify({\n // The PDP block used to fetch this in an effect, so the\n // server rendered a skeleton and crawlers saw a product page\n // with no product in it (AGL-659). The product is already\n // loaded here — hand it down so it renders server-side.\n pageData: {\n commerce: {\n product: toPublicProductDetail(\n productSnapshot.docs[0].id,\n product,\n ),\n // Rating aggregate (AGL-686): needed HERE because\n // `aggregateRating` belongs nested inside the Product\n // structured data, and that is emitted server-side.\n // The reviews block used to publish a free-standing\n // AggregateRating node, which schema.org ignores.\n ...(productReviews.aggregate.count\n ? { reviews: productReviews }\n : {}),\n },\n },\n data: {\n host: hostRes.host,\n screen: {\n data: {\n ...templateRes.screen,\n // The product NAMES this page; the template's own name\n // (\"Product detail\") describes none of the products it\n // renders. Kept distinct from the SEO title because the\n // head treats an authored title as verbatim and a name\n // as the side the site title joins (AGL-1341) — so a\n // product with its own SEO title gets exactly that, and\n // one without gets \"Blue Widget – Acme Store\".\n displayName: product.name,\n seo: {\n ...((templateRes.screen as any).seo ?? {}),\n // Only when the PRODUCT authored one: inheriting the\n // template screen's title would give every product\n // page in the store the same `<title>`.\n title: product.seo?.title ?? undefined,\n description:\n product.seo?.description ??\n product.description ??\n undefined,\n },\n },\n },\n },\n nodes: templateNodes,\n ...card.collected(),\n }),\n ),\n revalidate: 60,\n }\n }\n }\n }\n }\n // Commerce collection routes (AGL-298): /collections/{slug} renders\n // the designated collection template with collection tokens; the\n // product-grid block derives the same slug from the URL.\n if (pdpSegments.length === 2 && pdpSegments[0] === 'collections') {\n const adminFirestore = firebaseAdmin.app().firestore()\n const hostDocRef = adminFirestore.collection('hosts').doc(hostId)\n const [storeSettings, collectionSnapshot] = await Promise.all([\n hostDocRef.collection('settings').doc('store').get(),\n hostDocRef\n .collection('collections')\n .where('slug', '==', pdpSegments[1])\n .limit(5)\n .get(),\n ])\n const collectionScreenId = storeSettings.get('collectionScreenId')\n // Content collections share this path and a slug is only unique within a\n // kind (AGL-954), so take the first CATALOG match rather than the first\n // doc — otherwise a blog with the same slug renders as a product page.\n const shopCollection = collectionSnapshot.docs\n .find((docSnapshot) => hostCollectionKind(docSnapshot.data()) === 'catalog')\n ?.data() as CommerceModel.HostCollection | undefined\n if (collectionScreenId && shopCollection) {\n const templateRes = await getScreen({\n hostId,\n screenId: collectionScreenId,\n allowTemplate: true,\n })\n if (templateRes.screen) {\n // As on the PDP above: the template's image, then the site default\n // (AGL-2850).\n const card = collectSocialImageFacts([\n (templateRes.screen as any).seo?.image,\n hostRes.host?.seo?.image,\n ])\n const templateNodes = await composeScreenNodes({\n hostId,\n screenId: collectionScreenId,\n screen: templateRes.screen,\n socialImages: card.socialImages,\n // As on the PDP above (AGL-2883).\n host: hostRes.host,\n tokens: {\n 'collection.name': shopCollection.name,\n 'collection.description': shopCollection.description ?? '',\n 'collection.image': shopCollection.imageUrl ?? '',\n 'collection.slug': shopCollection.slug,\n },\n // As on the PDP above (AGL-3374).\n page: {\n template: {\n role: 'entry',\n route: '/collections/:slug',\n collectionName: 'Store collections',\n entryPath: `/collections/${shopCollection.slug}`,\n fallback: 'not-found',\n },\n },\n })\n if (templateNodes) {\n return {\n props: JSON.parse(\n JSON.stringify({\n data: {\n host: hostRes.host,\n screen: {\n data: {\n ...templateRes.screen,\n // As on the PDP above: the catalog collection names the\n // page, and a name takes the site title after it while\n // an authored SEO title would not (AGL-1341). A shop\n // collection has no SEO title field of its own, so the\n // template's must not stand in for one.\n displayName: shopCollection.name,\n seo: {\n ...((templateRes.screen as any).seo ?? {}),\n title: undefined,\n description:\n shopCollection.description ?? undefined,\n },\n },\n },\n },\n nodes: templateNodes,\n ...card.collected(),\n }),\n ),\n revalidate: 60,\n }\n }\n }\n }\n }\n return undefined\n}\n"],"names":["hostCollectionKind","composeScreenNodes","getScreen","collectSocialImageFacts","firebaseAdmin","CommerceModel","toPublicProductDetail","readProductReviews","commerceSitePageResolver","hostId","host","path","hostRes","pdpSegments","split","filter","Boolean","length","productSnapshot","adminFirestore","app","firestore","hostDocRef","collection","doc","storeSettings","Promise","all","get","where","limit","pdpScreenId","productRaw","docs","data","deletedAt","status","product","liftLegacyProduct","templateRes","screenId","allowTemplate","screen","minPrice","maxPrice","productPriceRange","productReviews","id","catch","error","console","reviews","aggregate","count","average","card","seo","image","templateNodes","socialImages","tokens","name","description","mediaUrls","imageUrl","slug","page","template","role","route","collectionName","entryPath","fallback","props","JSON","parse","stringify","pageData","commerce","displayName","title","undefined","nodes","collected","revalidate","collectionSnapshot","collectionScreenId","shopCollection","find","docSnapshot"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/site-page-resolver.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 type { SitePageResolver } from '@aglyn/aglyn/server'\nimport { hostCollectionKind } from '@aglyn/aglyn/server'\nimport composeScreenNodes, {\n composeNodesWithChrome,\n} from '@aglyn/tenant-runtime/compose-screen-nodes'\nimport { resolveBuiltInPageLayoutId } from '@aglyn/tenant-runtime/built-in-page-layout'\nimport * as Aglyn from '@aglyn/aglyn/server'\nimport { ORDER_STATUS_PATH } from './order-status-token'\nimport { ORDER_STATUS_COMPONENT_ID } from '../constants/order-status'\nimport { RETURN_REQUEST_COMPONENT_ID, RETURN_REQUEST_PATH } from '../constants/return-request'\nimport getScreen from '@aglyn/tenant-runtime/get-screen'\nimport { collectSocialImageFacts } from '@aglyn/tenant-runtime/social-image-facts'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport * as CommerceModel from '../model'\nimport { toPublicProductDetail } from './product'\nimport { readProductReviews } from './reviews'\n\n/**\n * Commerce page resolver (AGL-292/298/418), relocated verbatim from the\n * tenant loader: /products/{slug} renders the host's designated PDP\n * template with product tokens, /collections/{slug} the collection\n * template — both compose server-side and return complete page props.\n * Runs only for paths that didn't match a published screen; returns\n * undefined for everything else so the loader falls through.\n */\nexport const commerceSitePageResolver: SitePageResolver = async ({\n hostId,\n host,\n path,\n}) => {\n const hostRes = { host }\n // Product detail routes (AGL-292): /products/{slug} renders the\n // host's designated PDP template screen (settings/store\n // `pdpScreenId`, AGL-295) with product tokens; the product-detail\n // block hydrates variants client-side from the same slug. Same\n // mechanism as entry-template screens below.\n const pdpSegments = path.split('/').filter(Boolean)\n // The guest order-status page (AGL-3610), at /order-status — reached only\n // when the site has no page of its own there. The site's header and footer\n // around the order-status block, which reads the signed `?o=&t=` link after\n // hydration, so this page holds no order and is safe to cache. UNLISTED, so\n // the head says noindex: it is a private page, not a landing page.\n if (pdpSegments.length === 1 && pdpSegments[0] === ORDER_STATUS_PATH) {\n return composeOrderStatusPage(hostId, host)\n }\n // The buyer's return form (AGL-3611), at /order-return, under the same\n // terms: no page of the site's own there, the order read after hydration\n // from the link's `?o=&t=` (or the member's session), UNLISTED.\n if (pdpSegments.length === 1 && pdpSegments[0] === RETURN_REQUEST_PATH) {\n return composeReturnRequestPage(hostId, host)\n }\n if (pdpSegments.length === 2 && pdpSegments[0] === 'products') {\n const adminFirestore = firebaseAdmin.app().firestore()\n const hostDocRef = adminFirestore.collection('hosts').doc(hostId)\n const [storeSettings, productSnapshot] = await Promise.all([\n hostDocRef.collection('settings').doc('store').get(),\n hostDocRef\n .collection('products')\n .where('slug', '==', pdpSegments[1])\n .limit(1)\n .get(),\n ])\n const pdpScreenId = storeSettings.get('pdpScreenId')\n const productRaw = productSnapshot.docs[0]?.data() as any\n if (\n pdpScreenId &&\n productRaw &&\n !productRaw.deletedAt &&\n productRaw.status === 'active'\n ) {\n const product = CommerceModel.liftLegacyProduct(productRaw)\n const templateRes = await getScreen({\n hostId,\n screenId: pdpScreenId,\n // A PDP template renders against a routed PRODUCT, never at an address\n // of its own, so it is served here and 404s everywhere else (AGL-1400).\n allowTemplate: true,\n })\n if (templateRes.screen) {\n const [minPrice, maxPrice] = CommerceModel.productPriceRange(product)\n // Best-effort: a reviews read that fails costs the page its rating\n // snippet, not the page.\n const productReviews = await readProductReviews(\n hostId,\n productSnapshot.docs[0].id,\n ).catch((error) => {\n console.error('product review aggregate failed', error)\n return { reviews: [], aggregate: { count: 0, average: 0 } }\n })\n // The head shares this page as the template's image, then the site\n // default, so their documents are read in the template's own batch\n // (AGL-2850).\n const card = collectSocialImageFacts([\n (templateRes.screen as any).seo?.image,\n hostRes.host?.seo?.image,\n ])\n const templateNodes = await composeScreenNodes({\n hostId,\n screenId: pdpScreenId,\n screen: templateRes.screen,\n socialImages: card.socialImages,\n // The template's host variables, and its layout's, fill in from\n // this site as they do on every other page (AGL-2883).\n host: hostRes.host,\n tokens: {\n 'product.name': product.name,\n 'product.description': product.description ?? '',\n 'product.price':\n minPrice === maxPrice\n ? `$${minPrice}`\n : `From $${minPrice}`,\n 'product.image':\n product.mediaUrls?.[0] ?? product.imageUrl ?? '',\n 'product.slug': product.slug,\n },\n // Named as the product template it is if the page review holds it\n // (AGL-3374); without it the route has no page.\n page: {\n template: {\n role: 'entry',\n route: '/products/:slug',\n collectionName: 'Products',\n entryPath: `/products/${product.slug}`,\n fallback: 'not-found',\n },\n },\n })\n if (templateNodes) {\n return {\n props: JSON.parse(\n JSON.stringify({\n // The PDP block used to fetch this in an effect, so the\n // server rendered a skeleton and crawlers saw a product page\n // with no product in it (AGL-659). The product is already\n // loaded here — hand it down so it renders server-side.\n pageData: {\n commerce: {\n product: toPublicProductDetail(\n productSnapshot.docs[0].id,\n product,\n ),\n // Rating aggregate (AGL-686): needed HERE because\n // `aggregateRating` belongs nested inside the Product\n // structured data, and that is emitted server-side.\n // The reviews block used to publish a free-standing\n // AggregateRating node, which schema.org ignores.\n ...(productReviews.aggregate.count\n ? { reviews: productReviews }\n : {}),\n },\n },\n data: {\n host: hostRes.host,\n screen: {\n data: {\n ...templateRes.screen,\n // The product NAMES this page; the template's own name\n // (\"Product detail\") describes none of the products it\n // renders. Kept distinct from the SEO title because the\n // head treats an authored title as verbatim and a name\n // as the side the site title joins (AGL-1341) — so a\n // product with its own SEO title gets exactly that, and\n // one without gets \"Blue Widget – Acme Store\".\n displayName: product.name,\n seo: {\n ...((templateRes.screen as any).seo ?? {}),\n // Only when the PRODUCT authored one: inheriting the\n // template screen's title would give every product\n // page in the store the same `<title>`.\n title: product.seo?.title ?? undefined,\n description:\n product.seo?.description ??\n product.description ??\n undefined,\n },\n },\n },\n },\n nodes: templateNodes,\n ...card.collected(),\n }),\n ),\n revalidate: 60,\n }\n }\n }\n }\n }\n // Commerce collection routes (AGL-298): /collections/{slug} renders\n // the designated collection template with collection tokens; the\n // product-grid block derives the same slug from the URL.\n if (pdpSegments.length === 2 && pdpSegments[0] === 'collections') {\n const adminFirestore = firebaseAdmin.app().firestore()\n const hostDocRef = adminFirestore.collection('hosts').doc(hostId)\n const [storeSettings, collectionSnapshot] = await Promise.all([\n hostDocRef.collection('settings').doc('store').get(),\n hostDocRef\n .collection('collections')\n .where('slug', '==', pdpSegments[1])\n .limit(5)\n .get(),\n ])\n const collectionScreenId = storeSettings.get('collectionScreenId')\n // Content collections share this path and a slug is only unique within a\n // kind (AGL-954), so take the first CATALOG match rather than the first\n // doc — otherwise a blog with the same slug renders as a product page.\n const shopCollection = collectionSnapshot.docs\n .find((docSnapshot) => hostCollectionKind(docSnapshot.data()) === 'catalog')\n ?.data() as CommerceModel.HostCollection | undefined\n if (collectionScreenId && shopCollection) {\n const templateRes = await getScreen({\n hostId,\n screenId: collectionScreenId,\n allowTemplate: true,\n })\n if (templateRes.screen) {\n // As on the PDP above: the template's image, then the site default\n // (AGL-2850).\n const card = collectSocialImageFacts([\n (templateRes.screen as any).seo?.image,\n hostRes.host?.seo?.image,\n ])\n const templateNodes = await composeScreenNodes({\n hostId,\n screenId: collectionScreenId,\n screen: templateRes.screen,\n socialImages: card.socialImages,\n // As on the PDP above (AGL-2883).\n host: hostRes.host,\n tokens: {\n 'collection.name': shopCollection.name,\n 'collection.description': shopCollection.description ?? '',\n 'collection.image': shopCollection.imageUrl ?? '',\n 'collection.slug': shopCollection.slug,\n },\n // As on the PDP above (AGL-3374).\n page: {\n template: {\n role: 'entry',\n route: '/collections/:slug',\n collectionName: 'Store collections',\n entryPath: `/collections/${shopCollection.slug}`,\n fallback: 'not-found',\n },\n },\n })\n if (templateNodes) {\n return {\n props: JSON.parse(\n JSON.stringify({\n data: {\n host: hostRes.host,\n screen: {\n data: {\n ...templateRes.screen,\n // As on the PDP above: the catalog collection names the\n // page, and a name takes the site title after it while\n // an authored SEO title would not (AGL-1341). A shop\n // collection has no SEO title field of its own, so the\n // template's must not stand in for one.\n displayName: shopCollection.name,\n seo: {\n ...((templateRes.screen as any).seo ?? {}),\n title: undefined,\n description:\n shopCollection.description ?? undefined,\n },\n },\n },\n },\n nodes: templateNodes,\n ...card.collected(),\n }),\n ),\n revalidate: 60,\n }\n }\n }\n }\n }\n return undefined\n}\n\nconst ORDER_STATUS_NODE = 'order-status__block'\n\n/** The order-status page's node tree, root first, for the layout's slot. */\nexport function buildOrderStatusNodes(): Record<string, Aglyn.AglynNodeSchema> {\n return {\n [Aglyn.NODE_ROOT_ID]: {\n $id: Aglyn.NODE_ROOT_ID,\n componentId: 'div',\n nodes: ['order-status__container'],\n } as Aglyn.AglynNodeSchema,\n 'order-status__container': {\n $id: 'order-status__container',\n parentId: Aglyn.NODE_ROOT_ID,\n componentId: 'muiContainer',\n pluginId: 'mui',\n props: { maxWidth: 'md', sx: { paddingTop: 6, paddingBottom: 8 } },\n nodes: [ORDER_STATUS_NODE],\n } as Aglyn.AglynNodeSchema,\n [ORDER_STATUS_NODE]: {\n $id: ORDER_STATUS_NODE,\n parentId: 'order-status__container',\n componentId: ORDER_STATUS_COMPONENT_ID,\n pluginId: 'commerce',\n props: {},\n } as Aglyn.AglynNodeSchema,\n }\n}\n\nasync function composeOrderStatusPage(hostId: string, host: unknown) {\n try {\n const layoutId = await resolveBuiltInPageLayoutId({ hostId, host: host as never })\n const nodes = await composeNodesWithChrome({\n hostId,\n layoutId,\n screenNodes: buildOrderStatusNodes(),\n host: host as Aglyn.HostTokenSource,\n })\n if (!nodes) return undefined\n return {\n props: JSON.parse(\n JSON.stringify({\n data: {\n host,\n screen: {\n data: {\n displayName: 'Order status',\n visibility: Aglyn.HostScreenVisibility.UNLISTED,\n },\n },\n },\n nodes,\n }),\n ),\n revalidate: 3600,\n }\n } catch (error) {\n console.error('order status page composition failed', error)\n return undefined\n }\n}\n\nconst RETURN_REQUEST_NODE = 'ret__block'\n\n/** The return form's node tree, root first, for the layout's slot. */\nexport function buildReturnRequestNodes(): Record<string, Aglyn.AglynNodeSchema> {\n return {\n [Aglyn.NODE_ROOT_ID]: {\n $id: Aglyn.NODE_ROOT_ID,\n componentId: 'div',\n nodes: ['ret__container'],\n } as Aglyn.AglynNodeSchema,\n ret__container: {\n $id: 'ret__container',\n parentId: Aglyn.NODE_ROOT_ID,\n componentId: 'muiContainer',\n pluginId: 'mui',\n props: { maxWidth: 'md', sx: { paddingTop: 6, paddingBottom: 8 } },\n nodes: [RETURN_REQUEST_NODE],\n } as Aglyn.AglynNodeSchema,\n [RETURN_REQUEST_NODE]: {\n $id: RETURN_REQUEST_NODE,\n parentId: 'ret__container',\n componentId: RETURN_REQUEST_COMPONENT_ID,\n pluginId: 'commerce',\n props: {},\n } as Aglyn.AglynNodeSchema,\n }\n}\n\nasync function composeReturnRequestPage(hostId: string, host: unknown) {\n try {\n const layoutId = await resolveBuiltInPageLayoutId({ hostId, host: host as never })\n const nodes = await composeNodesWithChrome({\n hostId,\n layoutId,\n screenNodes: buildReturnRequestNodes(),\n host: host as Aglyn.HostTokenSource,\n })\n if (!nodes) return undefined\n return {\n props: JSON.parse(\n JSON.stringify({\n data: {\n host,\n screen: {\n data: {\n displayName: 'Request a return',\n visibility: Aglyn.HostScreenVisibility.UNLISTED,\n },\n },\n },\n nodes,\n }),\n ),\n revalidate: 3600,\n }\n } catch (error) {\n console.error('return request page composition failed', error)\n return undefined\n }\n}\n"],"names":["hostCollectionKind","composeScreenNodes","composeNodesWithChrome","resolveBuiltInPageLayoutId","Aglyn","ORDER_STATUS_PATH","ORDER_STATUS_COMPONENT_ID","RETURN_REQUEST_COMPONENT_ID","RETURN_REQUEST_PATH","getScreen","collectSocialImageFacts","firebaseAdmin","CommerceModel","toPublicProductDetail","readProductReviews","commerceSitePageResolver","hostId","host","path","hostRes","pdpSegments","split","filter","Boolean","length","composeOrderStatusPage","composeReturnRequestPage","productSnapshot","adminFirestore","app","firestore","hostDocRef","collection","doc","storeSettings","Promise","all","get","where","limit","pdpScreenId","productRaw","docs","data","deletedAt","status","product","liftLegacyProduct","templateRes","screenId","allowTemplate","screen","minPrice","maxPrice","productPriceRange","productReviews","id","catch","error","console","reviews","aggregate","count","average","card","seo","image","templateNodes","socialImages","tokens","name","description","mediaUrls","imageUrl","slug","page","template","role","route","collectionName","entryPath","fallback","props","JSON","parse","stringify","pageData","commerce","displayName","title","undefined","nodes","collected","revalidate","collectionSnapshot","collectionScreenId","shopCollection","find","docSnapshot","ORDER_STATUS_NODE","buildOrderStatusNodes","NODE_ROOT_ID","$id","componentId","parentId","pluginId","maxWidth","sx","paddingTop","paddingBottom","layoutId","screenNodes","visibility","HostScreenVisibility","UNLISTED","RETURN_REQUEST_NODE","buildReturnRequestNodes","ret__container"],"mappings":"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"}
@@ -0,0 +1,21 @@
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 { PluginStockLevelResult, PluginStockLevels } from '@aglyn/aglyn/plugin-manager/plugin-stock-levels';
18
+ type Firestore = FirebaseFirestore.Firestore;
19
+ export declare function setAvailableStock(request: Parameters<PluginStockLevels['setAvailable']>[0], firestore?: Firestore): Promise<PluginStockLevelResult[]>;
20
+ export declare const commerceStockLevels: PluginStockLevels;
21
+ export {};
@@ -0,0 +1,263 @@
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
+ */ import { _ as _extends } from "@swc/helpers/_/_extends";
17
+ import { createResourceUid } from "@aglyn/aglyn/server";
18
+ import { firebaseAdmin } from "@aglyn/tenant-data-admin/server/firebase-admin";
19
+ import * as CommerceModel from "../model/index.js";
20
+ import { alertLowStockCrossing } from "./low-stock.js";
21
+ /**
22
+ * COUNTS FROM SOMEWHERE ELSE, APPLIED AS THIS PLUGIN APPLIES ANY COUNT
23
+ * (AGL-3634): commerce's implementation of core's `core.stock-levels`.
24
+ *
25
+ * A fulfillment network's warehouse holds the goods, so its count is the
26
+ * true one. Each count is applied the way a merchant's own stock-take is:
27
+ *
28
+ * - inside a transaction on the product, so a sale landing at the same
29
+ * moment is decremented from the count this write set, never lost under
30
+ * it (the AGL-2320 reasoning);
31
+ * - with an `inventoryAdjustments` row in the same transaction, reason
32
+ * `sync` and the counter named as `source`, so the stock history says who
33
+ * moved the number and by how much;
34
+ * - with the product's roll-up and sold-out flag rewritten, its
35
+ * `updatedAtMs` moved so shopping-channel feeds pick the change up, and
36
+ * the low-stock alert raised on a crossing. Back-in-stock email needs
37
+ * nothing here: its cron reads the count.
38
+ *
39
+ * Matched by SKU across the store's products that are not deleted. A
40
+ * variant that does not track stock is left alone (`untracked`), and so is
41
+ * one that counts stock per location (`per_location`): one number written
42
+ * over its buckets would erase the counts the merchant keeps by hand.
43
+ */ const PRODUCTS_PER_PAGE = 300;
44
+ /** The most products one call walks to find its SKUs. */ const MAX_PRODUCTS_SCANNED = 20000;
45
+ const SKU_MAX = 120;
46
+ const normalizeSku = (value)=>String(value != null ? value : '').trim().slice(0, SKU_MAX);
47
+ /** Every live variant of the store whose SKU is one of `wanted`, by SKU. */ async function locateSkus(firestore, hostId, wanted) {
48
+ const found = new Map();
49
+ const products = firestore.collection('hosts').doc(hostId).collection('products');
50
+ let cursor = null;
51
+ let scanned = 0;
52
+ while(scanned < MAX_PRODUCTS_SCANNED){
53
+ var _ref;
54
+ var _page_docs_;
55
+ let query = products.orderBy(firebaseAdmin.firestore.FieldPath.documentId()).limit(PRODUCTS_PER_PAGE);
56
+ if (cursor) query = query.startAfter(cursor);
57
+ const page = await query.get();
58
+ for (const doc of page.docs){
59
+ var _doc_data;
60
+ const data = (_doc_data = doc.data()) != null ? _doc_data : {};
61
+ if (data['deletedAt']) continue;
62
+ const variants = Array.isArray(data['variants']) ? data['variants'] : [];
63
+ for (const variant of variants){
64
+ var _found_get;
65
+ const sku = normalizeSku(variant['sku']);
66
+ if (!sku || !wanted.has(sku) || !variant['id']) continue;
67
+ const list = (_found_get = found.get(sku)) != null ? _found_get : [];
68
+ list.push({
69
+ productId: doc.id,
70
+ variantId: String(variant['id'])
71
+ });
72
+ found.set(sku, list);
73
+ }
74
+ }
75
+ scanned += page.size;
76
+ if (page.size < PRODUCTS_PER_PAGE) break;
77
+ cursor = (_ref = (_page_docs_ = page.docs[page.docs.length - 1]) == null ? void 0 : _page_docs_.id) != null ? _ref : null;
78
+ }
79
+ return found;
80
+ }
81
+ /** Applies one product's counts in one transaction; answers each variant's outcome. */ async function applyToProduct(input) {
82
+ const { firestore, hostId, productId, counts, source, nowMs } = input;
83
+ const productRef = firestore.collection('hosts').doc(hostId).collection('products').doc(productId);
84
+ const host = firestore.collection('hosts').doc(hostId);
85
+ const outcome = await firestore.runTransaction(async (transaction)=>{
86
+ const results = new Map();
87
+ const snapshot = await transaction.get(productRef);
88
+ if (!snapshot.exists || snapshot.get('deletedAt')) {
89
+ for (const [variantId, count] of counts)results.set(variantId, {
90
+ sku: count.sku,
91
+ outcome: 'unknown_sku'
92
+ });
93
+ return {
94
+ results,
95
+ before: null,
96
+ after: null
97
+ };
98
+ }
99
+ const before = CommerceModel.liftLegacyProduct(snapshot.data());
100
+ const rows = [];
101
+ const variants = before.variants.map((variant)=>{
102
+ const count = counts.get(variant.id);
103
+ if (!count) return variant;
104
+ if (variant.inventory == null) {
105
+ results.set(variant.id, {
106
+ sku: count.sku,
107
+ outcome: 'untracked'
108
+ });
109
+ return variant;
110
+ }
111
+ const current = Number(variant.inventory);
112
+ if (variant.inventoryByLocation && Object.keys(variant.inventoryByLocation).length > 0) {
113
+ results.set(variant.id, {
114
+ sku: count.sku,
115
+ outcome: 'per_location',
116
+ before: current
117
+ });
118
+ return variant;
119
+ }
120
+ if (current === count.quantity) {
121
+ results.set(variant.id, {
122
+ sku: count.sku,
123
+ outcome: 'unchanged',
124
+ before: current,
125
+ after: current
126
+ });
127
+ return variant;
128
+ }
129
+ rows.push({
130
+ productId,
131
+ variantId: variant.id,
132
+ delta: count.quantity - current,
133
+ reason: 'sync',
134
+ source,
135
+ atMs: nowMs
136
+ });
137
+ results.set(variant.id, {
138
+ sku: count.sku,
139
+ outcome: 'updated',
140
+ before: current,
141
+ after: count.quantity
142
+ });
143
+ return _extends({}, variant, {
144
+ inventory: count.quantity
145
+ });
146
+ });
147
+ for (const [variantId, count] of counts){
148
+ if (!results.has(variantId)) results.set(variantId, {
149
+ sku: count.sku,
150
+ outcome: 'unknown_sku'
151
+ });
152
+ }
153
+ if (!rows.length) return {
154
+ results,
155
+ before: null,
156
+ after: null
157
+ };
158
+ const after = _extends({}, before, {
159
+ variants
160
+ });
161
+ transaction.set(productRef, _extends({
162
+ variants
163
+ }, CommerceModel.productStockFields(after), {
164
+ updatedAtMs: nowMs
165
+ }), {
166
+ merge: true
167
+ });
168
+ for (const row of rows)transaction.set(host.collection('inventoryAdjustments').doc(createResourceUid()), row);
169
+ return {
170
+ results,
171
+ before,
172
+ after
173
+ };
174
+ });
175
+ if (outcome.before && outcome.after) alertLowStockCrossing(hostId, outcome.before, outcome.after);
176
+ return outcome.results;
177
+ }
178
+ /** The strongest outcome across the variants one SKU names: a change beats no change. */ const RANK = {
179
+ updated: 7,
180
+ unchanged: 6,
181
+ per_location: 5,
182
+ untracked: 4,
183
+ failed: 3,
184
+ invalid: 2,
185
+ unknown_sku: 1
186
+ };
187
+ export async function setAvailableStock(request, firestore = firebaseAdmin.app().firestore()) {
188
+ var _request_source;
189
+ const source = String((_request_source = request.source) != null ? _request_source : '').trim().slice(0, 60) || 'Sync';
190
+ const asked = request.levels.map((level)=>{
191
+ const sku = normalizeSku(level == null ? void 0 : level.sku);
192
+ const quantity = Number(level == null ? void 0 : level.quantity);
193
+ const valid = Boolean(sku) && Number.isInteger(quantity) && quantity >= 0 && quantity <= 10000000;
194
+ return {
195
+ sku,
196
+ quantity,
197
+ valid
198
+ };
199
+ });
200
+ const latest = new Map();
201
+ for (const entry of asked)if (entry.valid) latest.set(entry.sku, entry.quantity);
202
+ const bySku = new Map();
203
+ if (latest.size) {
204
+ const located = await locateSkus(firestore, request.hostId, new Set(latest.keys()));
205
+ const byProduct = new Map();
206
+ for (const [sku, places] of located){
207
+ for (const place of places){
208
+ var _byProduct_get, _latest_get;
209
+ const counts = (_byProduct_get = byProduct.get(place.productId)) != null ? _byProduct_get : new Map();
210
+ counts.set(place.variantId, {
211
+ sku,
212
+ quantity: (_latest_get = latest.get(sku)) != null ? _latest_get : 0
213
+ });
214
+ byProduct.set(place.productId, counts);
215
+ }
216
+ }
217
+ const nowMs = Date.now();
218
+ for (const [productId, counts] of byProduct){
219
+ let results;
220
+ try {
221
+ results = await applyToProduct({
222
+ firestore,
223
+ hostId: request.hostId,
224
+ productId,
225
+ counts,
226
+ source,
227
+ nowMs
228
+ });
229
+ } catch (error) {
230
+ console.error('[stock-levels] count not applied', request.hostId, productId, error);
231
+ results = new Map([
232
+ ...counts
233
+ ].map(([variantId, count])=>[
234
+ variantId,
235
+ {
236
+ sku: count.sku,
237
+ outcome: 'failed'
238
+ }
239
+ ]));
240
+ }
241
+ for (const result of results.values()){
242
+ const held = bySku.get(result.sku);
243
+ if (!held || RANK[result.outcome] > RANK[held.outcome]) bySku.set(result.sku, result);
244
+ }
245
+ }
246
+ }
247
+ return asked.map((entry)=>{
248
+ var _bySku_get;
249
+ if (!entry.valid) return {
250
+ sku: entry.sku,
251
+ outcome: 'invalid'
252
+ };
253
+ return (_bySku_get = bySku.get(entry.sku)) != null ? _bySku_get : {
254
+ sku: entry.sku,
255
+ outcome: 'unknown_sku'
256
+ };
257
+ });
258
+ }
259
+ export const commerceStockLevels = {
260
+ setAvailable: (request)=>setAvailableStock(request)
261
+ };
262
+
263
+ //# sourceMappingURL=stock-levels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/stock-levels.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 type {\n PluginStockLevelOutcome,\n PluginStockLevelResult,\n PluginStockLevels,\n} from '@aglyn/aglyn/plugin-manager/plugin-stock-levels'\nimport { createResourceUid } from '@aglyn/aglyn/server'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin/server/firebase-admin'\nimport * as CommerceModel from '../model'\nimport { alertLowStockCrossing } from './low-stock'\n\n/**\n * COUNTS FROM SOMEWHERE ELSE, APPLIED AS THIS PLUGIN APPLIES ANY COUNT\n * (AGL-3634): commerce's implementation of core's `core.stock-levels`.\n *\n * A fulfillment network's warehouse holds the goods, so its count is the\n * true one. Each count is applied the way a merchant's own stock-take is:\n *\n * - inside a transaction on the product, so a sale landing at the same\n * moment is decremented from the count this write set, never lost under\n * it (the AGL-2320 reasoning);\n * - with an `inventoryAdjustments` row in the same transaction, reason\n * `sync` and the counter named as `source`, so the stock history says who\n * moved the number and by how much;\n * - with the product's roll-up and sold-out flag rewritten, its\n * `updatedAtMs` moved so shopping-channel feeds pick the change up, and\n * the low-stock alert raised on a crossing. Back-in-stock email needs\n * nothing here: its cron reads the count.\n *\n * Matched by SKU across the store's products that are not deleted. A\n * variant that does not track stock is left alone (`untracked`), and so is\n * one that counts stock per location (`per_location`): one number written\n * over its buckets would erase the counts the merchant keeps by hand.\n */\n\nconst PRODUCTS_PER_PAGE = 300\n/** The most products one call walks to find its SKUs. */\nconst MAX_PRODUCTS_SCANNED = 20_000\nconst SKU_MAX = 120\n\ntype Firestore = FirebaseFirestore.Firestore\n\ninterface Located {\n productId: string\n variantId: string\n}\n\nconst normalizeSku = (value: unknown): string => String(value ?? '').trim().slice(0, SKU_MAX)\n\n/** Every live variant of the store whose SKU is one of `wanted`, by SKU. */\nasync function locateSkus(firestore: Firestore, hostId: string, wanted: ReadonlySet<string>) {\n const found = new Map<string, Located[]>()\n const products = firestore.collection('hosts').doc(hostId).collection('products')\n let cursor: string | null = null\n let scanned = 0\n while (scanned < MAX_PRODUCTS_SCANNED) {\n let query = products.orderBy(firebaseAdmin.firestore.FieldPath.documentId()).limit(PRODUCTS_PER_PAGE)\n if (cursor) query = query.startAfter(cursor)\n const page = await query.get()\n for (const doc of page.docs) {\n const data = doc.data() ?? {}\n if (data['deletedAt']) continue\n const variants = Array.isArray(data['variants']) ? (data['variants'] as Array<Record<string, unknown>>) : []\n for (const variant of variants) {\n const sku = normalizeSku(variant['sku'])\n if (!sku || !wanted.has(sku) || !variant['id']) continue\n const list = found.get(sku) ?? []\n list.push({ productId: doc.id, variantId: String(variant['id']) })\n found.set(sku, list)\n }\n }\n scanned += page.size\n if (page.size < PRODUCTS_PER_PAGE) break\n cursor = page.docs[page.docs.length - 1]?.id ?? null\n }\n return found\n}\n\n/** Applies one product's counts in one transaction; answers each variant's outcome. */\nasync function applyToProduct(input: {\n firestore: Firestore\n hostId: string\n productId: string\n counts: ReadonlyMap<string, { sku: string; quantity: number }>\n source: string\n nowMs: number\n}): Promise<Map<string, PluginStockLevelResult>> {\n const { firestore, hostId, productId, counts, source, nowMs } = input\n const productRef = firestore.collection('hosts').doc(hostId).collection('products').doc(productId)\n const host = firestore.collection('hosts').doc(hostId)\n const outcome = await firestore.runTransaction(async (transaction) => {\n const results = new Map<string, PluginStockLevelResult>()\n const snapshot = await transaction.get(productRef)\n if (!snapshot.exists || snapshot.get('deletedAt')) {\n for (const [variantId, count] of counts) results.set(variantId, { sku: count.sku, outcome: 'unknown_sku' })\n return { results, before: null, after: null }\n }\n const before = CommerceModel.liftLegacyProduct(snapshot.data() as never)\n const rows: CommerceModel.InventoryAdjustment[] = []\n const variants = before.variants.map((variant) => {\n const count = counts.get(variant.id)\n if (!count) return variant\n if (variant.inventory == null) {\n results.set(variant.id, { sku: count.sku, outcome: 'untracked' })\n return variant\n }\n const current = Number(variant.inventory)\n if (variant.inventoryByLocation && Object.keys(variant.inventoryByLocation).length > 0) {\n results.set(variant.id, { sku: count.sku, outcome: 'per_location', before: current })\n return variant\n }\n if (current === count.quantity) {\n results.set(variant.id, { sku: count.sku, outcome: 'unchanged', before: current, after: current })\n return variant\n }\n rows.push({\n productId,\n variantId: variant.id,\n delta: count.quantity - current,\n reason: 'sync',\n source,\n atMs: nowMs,\n })\n results.set(variant.id, { sku: count.sku, outcome: 'updated', before: current, after: count.quantity })\n return { ...variant, inventory: count.quantity }\n })\n for (const [variantId, count] of counts) {\n if (!results.has(variantId)) results.set(variantId, { sku: count.sku, outcome: 'unknown_sku' })\n }\n if (!rows.length) return { results, before: null, after: null }\n const after = { ...before, variants }\n transaction.set(\n productRef,\n { variants, ...CommerceModel.productStockFields(after), updatedAtMs: nowMs },\n { merge: true },\n )\n for (const row of rows) transaction.set(host.collection('inventoryAdjustments').doc(createResourceUid()), row)\n return { results, before, after }\n })\n if (outcome.before && outcome.after) alertLowStockCrossing(hostId, outcome.before, outcome.after)\n return outcome.results\n}\n\n/** The strongest outcome across the variants one SKU names: a change beats no change. */\nconst RANK: Record<PluginStockLevelOutcome, number> = {\n updated: 7,\n unchanged: 6,\n per_location: 5,\n untracked: 4,\n failed: 3,\n invalid: 2,\n unknown_sku: 1,\n}\n\nexport async function setAvailableStock(\n request: Parameters<PluginStockLevels['setAvailable']>[0],\n firestore: Firestore = firebaseAdmin.app().firestore(),\n): Promise<PluginStockLevelResult[]> {\n const source = String(request.source ?? '').trim().slice(0, 60) || 'Sync'\n const asked = request.levels.map((level) => {\n const sku = normalizeSku(level?.sku)\n const quantity = Number(level?.quantity)\n const valid = Boolean(sku) && Number.isInteger(quantity) && quantity >= 0 && quantity <= 10_000_000\n return { sku, quantity, valid }\n })\n const latest = new Map<string, number>()\n for (const entry of asked) if (entry.valid) latest.set(entry.sku, entry.quantity)\n const bySku = new Map<string, PluginStockLevelResult>()\n if (latest.size) {\n const located = await locateSkus(firestore, request.hostId, new Set(latest.keys()))\n const byProduct = new Map<string, Map<string, { sku: string; quantity: number }>>()\n for (const [sku, places] of located) {\n for (const place of places) {\n const counts = byProduct.get(place.productId) ?? new Map()\n counts.set(place.variantId, { sku, quantity: latest.get(sku) ?? 0 })\n byProduct.set(place.productId, counts)\n }\n }\n const nowMs = Date.now()\n for (const [productId, counts] of byProduct) {\n let results: Map<string, PluginStockLevelResult>\n try {\n results = await applyToProduct({ firestore, hostId: request.hostId, productId, counts, source, nowMs })\n } catch (error) {\n console.error('[stock-levels] count not applied', request.hostId, productId, error)\n results = new Map([...counts].map(([variantId, count]) => [variantId, { sku: count.sku, outcome: 'failed' }]))\n }\n for (const result of results.values()) {\n const held = bySku.get(result.sku)\n if (!held || RANK[result.outcome] > RANK[held.outcome]) bySku.set(result.sku, result)\n }\n }\n }\n return asked.map((entry) => {\n if (!entry.valid) return { sku: entry.sku, outcome: 'invalid' as const }\n return bySku.get(entry.sku) ?? { sku: entry.sku, outcome: 'unknown_sku' as const }\n })\n}\n\nexport const commerceStockLevels: PluginStockLevels = {\n setAvailable: (request) => setAvailableStock(request),\n}\n"],"names":["createResourceUid","firebaseAdmin","CommerceModel","alertLowStockCrossing","PRODUCTS_PER_PAGE","MAX_PRODUCTS_SCANNED","SKU_MAX","normalizeSku","value","String","trim","slice","locateSkus","firestore","hostId","wanted","found","Map","products","collection","doc","cursor","scanned","page","query","orderBy","FieldPath","documentId","limit","startAfter","get","docs","data","variants","Array","isArray","variant","sku","has","list","push","productId","id","variantId","set","size","length","applyToProduct","input","counts","source","nowMs","productRef","host","outcome","runTransaction","transaction","results","snapshot","exists","count","before","after","liftLegacyProduct","rows","map","inventory","current","Number","inventoryByLocation","Object","keys","quantity","delta","reason","atMs","productStockFields","updatedAtMs","merge","row","RANK","updated","unchanged","per_location","untracked","failed","invalid","unknown_sku","setAvailableStock","request","app","asked","levels","level","valid","Boolean","isInteger","latest","entry","bySku","located","Set","byProduct","places","place","Date","now","error","console","result","values","held","commerceStockLevels","setAvailable"],"mappings":"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"}