@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.
- package/README.md +1 -1
- package/package.json +13 -13
- package/src/lib/components/cart.js +25 -12
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +70 -13
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +2 -1
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/payment-methods-card.component.js +1 -1
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
- package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
- package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.js +50 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
- package/src/lib/components/console/pos-cellular-control.component.js +211 -0
- package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
- package/src/lib/components/console/pos-devices-card.component.js +47 -15
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
- package/src/lib/components/console/pos-display-page.component.js +44 -2
- package/src/lib/components/console/pos-display-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
- package/src/lib/components/console/pos-hardware-card.component.js +157 -36
- package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.d.ts +1 -1
- package/src/lib/components/console/pos-page.component.js +63 -12
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
- package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
- package/src/lib/components/console/product-check-in-fields.component.js +60 -14
- package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +44 -1
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
- package/src/lib/components/console/product-register-fields.component.js +31 -2
- package/src/lib/components/console/product-register-fields.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +11 -2
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
- package/src/lib/components/console/register-hardware-card.component.js +56 -27
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
- package/src/lib/components/console/reservations-card.component.d.ts +9 -0
- package/src/lib/components/console/reservations-card.component.js +158 -23
- package/src/lib/components/console/reservations-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
- package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
- package/src/lib/components/console/shipstation-card.component.js +3 -3
- package/src/lib/components/console/shipstation-card.component.js.map +1 -1
- package/src/lib/components/product-detail.d.ts +4 -0
- package/src/lib/components/product-detail.js +40 -5
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/product-reviews.js +28 -11
- package/src/lib/components/product-reviews.js.map +1 -1
- package/src/lib/components/reservation-widget.js +28 -5
- package/src/lib/components/reservation-widget.js.map +1 -1
- package/src/lib/components/use-day-picker.d.ts +25 -0
- package/src/lib/components/use-day-picker.js +57 -0
- package/src/lib/components/use-day-picker.js.map +1 -0
- package/src/lib/constants/operator-alerts.d.ts +55 -0
- package/src/lib/constants/operator-alerts.js +156 -1
- package/src/lib/constants/operator-alerts.js.map +1 -1
- package/src/lib/declarations.console-server.js +54 -1
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +4 -2
- package/src/lib/declarations.js +11 -4
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/declarations.server.js +9 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/commerce-cart.d.ts +9 -1
- package/src/lib/model/commerce-cart.js +4 -3
- package/src/lib/model/commerce-cart.js.map +1 -1
- package/src/lib/model/commerce-check-in-product.d.ts +26 -0
- package/src/lib/model/commerce-check-in-product.js +64 -2
- package/src/lib/model/commerce-check-in-product.js.map +1 -1
- package/src/lib/model/commerce-check-in-record.d.ts +127 -0
- package/src/lib/model/commerce-check-in-record.js +36 -0
- package/src/lib/model/commerce-check-in-record.js.map +1 -0
- package/src/lib/model/commerce-check-in.d.ts +91 -87
- package/src/lib/model/commerce-check-in.js +186 -62
- package/src/lib/model/commerce-check-in.js.map +1 -1
- package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
- package/src/lib/model/commerce-kiosk-offer.js +35 -0
- package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +76 -0
- package/src/lib/model/commerce-orders.js +6 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
- package/src/lib/model/commerce-pos-day-report.js +39 -2
- package/src/lib/model/commerce-pos-day-report.js.map +1 -1
- package/src/lib/model/commerce-pos-offline.d.ts +1 -1
- package/src/lib/model/commerce-pos-offline.js +6 -1
- package/src/lib/model/commerce-pos-offline.js.map +1 -1
- package/src/lib/model/commerce-pos-ops.js +3 -2
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +36 -3
- package/src/lib/model/commerce-pos.js +14 -6
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-receipt.js +3 -2
- package/src/lib/model/commerce-receipt.js.map +1 -1
- package/src/lib/model/commerce-reservations.d.ts +69 -4
- package/src/lib/model/commerce-reservations.js +57 -5
- package/src/lib/model/commerce-reservations.js.map +1 -1
- package/src/lib/model/commerce.d.ts +66 -0
- package/src/lib/model/commerce.js +15 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/order-list-fields.d.ts +11 -0
- package/src/lib/model/order-list-fields.js +17 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/own-store-tax-summary.d.ts +152 -0
- package/src/lib/model/own-store-tax-summary.js +288 -0
- package/src/lib/model/own-store-tax-summary.js.map +1 -0
- package/src/lib/model/plugin-permissions.d.ts +67 -0
- package/src/lib/model/plugin-permissions.js +224 -7
- package/src/lib/model/plugin-permissions.js.map +1 -1
- package/src/lib/model/pos-cellular.d.ts +223 -0
- package/src/lib/model/pos-cellular.js +293 -0
- package/src/lib/model/pos-cellular.js.map +1 -0
- package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
- package/src/lib/model/pos-hardware-in-person.js +224 -0
- package/src/lib/model/pos-hardware-in-person.js.map +1 -0
- package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
- package/src/lib/model/pos-hardware-tax-summary.js +225 -0
- package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
- package/src/lib/model/pos-hardware-terms.d.ts +74 -0
- package/src/lib/model/pos-hardware-terms.js +115 -0
- package/src/lib/model/pos-hardware-terms.js.map +1 -0
- package/src/lib/model/pos-hardware.d.ts +349 -7
- package/src/lib/model/pos-hardware.js +291 -20
- package/src/lib/model/pos-hardware.js.map +1 -1
- package/src/lib/model/product-write.d.ts +10 -0
- package/src/lib/model/product-write.js +4 -2
- package/src/lib/model/product-write.js.map +1 -1
- package/src/lib/plugin.js +16 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/billing-webhook.js +25 -1
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +7 -5
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/cart-checkout.js +20 -8
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/cart.js +29 -0
- package/src/lib/server/cart.js.map +1 -1
- package/src/lib/server/checkout.js +42 -13
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/collection-membership.d.ts +4 -0
- package/src/lib/server/collection-membership.js +5 -10
- package/src/lib/server/collection-membership.js.map +1 -1
- package/src/lib/server/commerce-site-keys.d.ts +29 -0
- package/src/lib/server/commerce-site-keys.js +40 -0
- package/src/lib/server/commerce-site-keys.js.map +1 -0
- package/src/lib/server/draft-order.js +8 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.js +7 -5
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/gift-cards.js +8 -5
- package/src/lib/server/gift-cards.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.js +9 -6
- package/src/lib/server/local-fulfillment-status.js.map +1 -1
- package/src/lib/server/member-post.js +6 -5
- package/src/lib/server/member-post.js.map +1 -1
- package/src/lib/server/membership-admin-password.d.ts +4 -2
- package/src/lib/server/membership-admin-password.js +10 -8
- package/src/lib/server/membership-admin-password.js.map +1 -1
- package/src/lib/server/membership-admin-remove.d.ts +7 -5
- package/src/lib/server/membership-admin-remove.js +9 -9
- package/src/lib/server/membership-admin-remove.js.map +1 -1
- package/src/lib/server/order-notifications.js +5 -2
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/order-print.js +7 -5
- package/src/lib/server/order-print.js.map +1 -1
- package/src/lib/server/order-receipt-send.js +8 -5
- package/src/lib/server/order-receipt-send.js.map +1 -1
- package/src/lib/server/orders-shipping-prepare.js +9 -6
- package/src/lib/server/orders-shipping-prepare.js.map +1 -1
- package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
- package/src/lib/server/own-store-tax-return-source.js +312 -0
- package/src/lib/server/own-store-tax-return-source.js.map +1 -0
- package/src/lib/server/payment-methods.js +13 -9
- package/src/lib/server/payment-methods.js.map +1 -1
- package/src/lib/server/pos-auth.d.ts +37 -6
- package/src/lib/server/pos-auth.js +40 -15
- package/src/lib/server/pos-auth.js.map +1 -1
- package/src/lib/server/pos-cellular-billing.d.ts +81 -0
- package/src/lib/server/pos-cellular-billing.js +711 -0
- package/src/lib/server/pos-cellular-billing.js.map +1 -0
- package/src/lib/server/pos-cellular-notify.d.ts +47 -0
- package/src/lib/server/pos-cellular-notify.js +150 -0
- package/src/lib/server/pos-cellular-notify.js.map +1 -0
- package/src/lib/server/pos-cellular.d.ts +88 -0
- package/src/lib/server/pos-cellular.js +339 -0
- package/src/lib/server/pos-cellular.js.map +1 -0
- package/src/lib/server/pos-check-in.d.ts +5 -1
- package/src/lib/server/pos-check-in.js +296 -28
- package/src/lib/server/pos-check-in.js.map +1 -1
- package/src/lib/server/pos-day-report.js +29 -3
- package/src/lib/server/pos-day-report.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +16 -0
- package/src/lib/server/pos-display.js +129 -2
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-hardware-admin.d.ts +10 -1
- package/src/lib/server/pos-hardware-admin.js +250 -84
- package/src/lib/server/pos-hardware-admin.js.map +1 -1
- package/src/lib/server/pos-hardware-attach.d.ts +105 -0
- package/src/lib/server/pos-hardware-attach.js +443 -0
- package/src/lib/server/pos-hardware-attach.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
- package/src/lib/server/pos-hardware-buyer-record.js +86 -0
- package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
- package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
- package/src/lib/server/pos-hardware-cancel.js +147 -0
- package/src/lib/server/pos-hardware-cancel.js.map +1 -0
- package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
- package/src/lib/server/pos-hardware-closure-notices.js +85 -0
- package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
- package/src/lib/server/pos-hardware-closure.d.ts +60 -0
- package/src/lib/server/pos-hardware-closure.js +153 -0
- package/src/lib/server/pos-hardware-closure.js.map +1 -0
- package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
- package/src/lib/server/pos-hardware-in-person.js +236 -0
- package/src/lib/server/pos-hardware-in-person.js.map +1 -0
- package/src/lib/server/pos-hardware-notify.d.ts +40 -2
- package/src/lib/server/pos-hardware-notify.js +195 -14
- package/src/lib/server/pos-hardware-notify.js.map +1 -1
- package/src/lib/server/pos-hardware-readers.d.ts +115 -0
- package/src/lib/server/pos-hardware-readers.js +430 -0
- package/src/lib/server/pos-hardware-readers.js.map +1 -0
- package/src/lib/server/pos-hardware-returns.d.ts +116 -0
- package/src/lib/server/pos-hardware-returns.js +502 -0
- package/src/lib/server/pos-hardware-returns.js.map +1 -0
- package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
- package/src/lib/server/pos-hardware-sale-fields.js +44 -0
- package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
- package/src/lib/server/pos-hardware-sale.d.ts +54 -0
- package/src/lib/server/pos-hardware-sale.js +369 -0
- package/src/lib/server/pos-hardware-sale.js.map +1 -0
- package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
- package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
- package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
- package/src/lib/server/pos-hardware-terms.d.ts +64 -0
- package/src/lib/server/pos-hardware-terms.js +154 -0
- package/src/lib/server/pos-hardware-terms.js.map +1 -0
- package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
- package/src/lib/server/pos-hardware-user-eraser.js +31 -7
- package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
- package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
- package/src/lib/server/pos-hardware-webhook.js +51 -6
- package/src/lib/server/pos-hardware-webhook.js.map +1 -1
- package/src/lib/server/pos-hardware.d.ts +74 -1
- package/src/lib/server/pos-hardware.js +175 -10
- package/src/lib/server/pos-hardware.js.map +1 -1
- package/src/lib/server/pos-kiosk.d.ts +2 -0
- package/src/lib/server/pos-kiosk.js +17 -12
- package/src/lib/server/pos-kiosk.js.map +1 -1
- package/src/lib/server/pos-offline-card-order.d.ts +64 -0
- package/src/lib/server/pos-offline-card-order.js +102 -0
- package/src/lib/server/pos-offline-card-order.js.map +1 -0
- package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
- package/src/lib/server/pos-offline-card-reconcile.js +215 -18
- package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
- package/src/lib/server/pos-offline-sync.d.ts +39 -0
- package/src/lib/server/pos-offline-sync.js +190 -55
- package/src/lib/server/pos-offline-sync.js.map +1 -1
- package/src/lib/server/pos-ops-gate.d.ts +15 -4
- package/src/lib/server/pos-ops-gate.js +42 -9
- package/src/lib/server/pos-ops-gate.js.map +1 -1
- package/src/lib/server/pos-ops-routes.js +24 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -1
- package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
- package/src/lib/server/pos-order-refund-ids.js +31 -0
- package/src/lib/server/pos-order-refund-ids.js.map +1 -0
- package/src/lib/server/pos-order.js +52 -49
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.js +1 -1
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-reader-splash-admin.js +30 -32
- package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
- package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
- package/src/lib/server/pos-reader-splash-images-route.js +113 -0
- package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
- package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
- package/src/lib/server/pos-reader-splash-images.js +123 -0
- package/src/lib/server/pos-reader-splash-images.js.map +1 -0
- package/src/lib/server/pos-reader-splash.d.ts +68 -1
- package/src/lib/server/pos-reader-splash.js +182 -11
- package/src/lib/server/pos-reader-splash.js.map +1 -1
- package/src/lib/server/pos-readers.d.ts +29 -0
- package/src/lib/server/pos-readers.js +134 -35
- package/src/lib/server/pos-readers.js.map +1 -1
- package/src/lib/server/pos-return.d.ts +10 -0
- package/src/lib/server/pos-return.js +26 -1
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.js +6 -1
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +11 -0
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/pos-staff-pin.js +25 -20
- package/src/lib/server/pos-staff-pin.js.map +1 -1
- package/src/lib/server/pos-terminal.d.ts +14 -4
- package/src/lib/server/pos-terminal.js +34 -38
- package/src/lib/server/pos-terminal.js.map +1 -1
- package/src/lib/server/printers.d.ts +7 -3
- package/src/lib/server/printers.js +18 -12
- package/src/lib/server/printers.js.map +1 -1
- package/src/lib/server/product-drafts.d.ts +11 -1
- package/src/lib/server/product-drafts.js +12 -8
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product.d.ts +15 -1
- package/src/lib/server/product.js +16 -3
- package/src/lib/server/product.js.map +1 -1
- package/src/lib/server/products-write.d.ts +26 -2
- package/src/lib/server/products-write.js +19 -7
- package/src/lib/server/products-write.js.map +1 -1
- package/src/lib/server/refund.js +34 -11
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reservation-availability-query.d.ts +8 -0
- package/src/lib/server/reservation-availability-query.js +11 -1
- package/src/lib/server/reservation-availability-query.js.map +1 -1
- package/src/lib/server/reservation-availability.d.ts +1 -1
- package/src/lib/server/reservation-availability.js +7 -2
- package/src/lib/server/reservation-availability.js.map +1 -1
- package/src/lib/server/reservation-guests.d.ts +32 -0
- package/src/lib/server/reservation-guests.js +285 -0
- package/src/lib/server/reservation-guests.js.map +1 -0
- package/src/lib/server/reservation-walk-in.d.ts +11 -1
- package/src/lib/server/reservation-walk-in.js +56 -12
- package/src/lib/server/reservation-walk-in.js.map +1 -1
- package/src/lib/server/reserve.js +18 -5
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/returns.js +9 -6
- package/src/lib/server/returns.js.map +1 -1
- package/src/lib/server/reviews.d.ts +22 -2
- package/src/lib/server/reviews.js +88 -20
- package/src/lib/server/reviews.js.map +1 -1
- package/src/lib/server/shipping-connectors.js +10 -11
- package/src/lib/server/shipping-connectors.js.map +1 -1
- package/src/lib/server/site-page-resolver.js +20 -3
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/store-day.d.ts +33 -0
- package/src/lib/server/store-day.js +46 -0
- package/src/lib/server/store-day.js.map +1 -0
- package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
- package/src/lib/server/store-setup-ai-writer.js +5 -6
- package/src/lib/server/store-setup-ai-writer.js.map +1 -1
- package/src/lib/server/storefront-tax.d.ts +13 -0
- package/src/lib/server/storefront-tax.js +8 -1
- package/src/lib/server/storefront-tax.js.map +1 -1
- package/src/lib/server/tax-return-source.d.ts +32 -3
- package/src/lib/server/tax-return-source.js +99 -20
- package/src/lib/server/tax-return-source.js.map +1 -1
- package/src/lib/server.js +100 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/fake-firestore.js +58 -16
- package/src/lib/testing/fake-firestore.js.map +1 -1
- package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
- package/src/lib/testing/site-register-permissions.d.ts +29 -0
- package/src/lib/testing/site-register-permissions.js +38 -0
- package/src/lib/testing/site-register-permissions.js.map +1 -0
- package/src/lib/transfer/tracking.server.js +8 -5
- package/src/lib/transfer/tracking.server.js.map +1 -1
- package/src/lib/utils/add-to-cart.d.ts +2 -0
- package/src/lib/utils/add-to-cart.js +6 -3
- package/src/lib/utils/add-to-cart.js.map +1 -1
package/src/lib/server/cart.js
CHANGED
|
@@ -18,6 +18,7 @@ import * as CommerceModel from "../model/index.js";
|
|
|
18
18
|
import { firebaseAdmin } from "@aglyn/tenant-data-admin";
|
|
19
19
|
import { isDocumentId } from "@aglyn/tenant-data-admin/server/document-id";
|
|
20
20
|
import { cartCookieName, mintCartId, readCartId } from "./cart-cookie.js";
|
|
21
|
+
import { readStoreDay } from "./store-day.js";
|
|
21
22
|
/**
|
|
22
23
|
* Server-backed cart (AGL-293): cookie-keyed doc under
|
|
23
24
|
* `hosts/{hostId}/carts`. GET returns the resolved cart; POST mutates
|
|
@@ -78,16 +79,26 @@ import { cartCookieName, mintCartId, readCartId } from "./cart-cookie.js";
|
|
|
78
79
|
if (isPost) {
|
|
79
80
|
var _body_action, _body_productId, _body_quantity, _body_quantity1;
|
|
80
81
|
const action = String((_body_action = body.action) != null ? _body_action : 'add');
|
|
82
|
+
// The day the shopper chose to use a check-in item (AGL-4043): part of
|
|
83
|
+
// the line's identity, so two days of one pass are two lines.
|
|
84
|
+
const useDayKey = typeof body.useDayKey === 'string' ? body.useDayKey.trim() : '';
|
|
81
85
|
const line = _extends({
|
|
82
86
|
productId: String((_body_productId = body.productId) != null ? _body_productId : '')
|
|
83
87
|
}, body.variantId ? {
|
|
84
88
|
variantId: String(body.variantId)
|
|
89
|
+
} : {}, useDayKey ? {
|
|
90
|
+
useDayKey
|
|
85
91
|
} : {}, {
|
|
86
92
|
// Clamped at the door as well as in the model (AGL-2285): the route
|
|
87
93
|
// used `Math.round(Number(...))` alone, which yields `NaN` for
|
|
88
94
|
// `{"quantity":"x"}` and slipped past `upsertCartLine`'s `<= 0` guard.
|
|
89
95
|
quantity: Math.min(CommerceModel.CART_MAX_QUANTITY, Math.max(-CommerceModel.CART_MAX_QUANTITY, Number.isFinite(Number((_body_quantity = body.quantity) != null ? _body_quantity : 1)) ? Math.round(Number((_body_quantity1 = body.quantity) != null ? _body_quantity1 : 1)) : 0))
|
|
90
96
|
});
|
|
97
|
+
if (useDayKey && !CommerceModel.isCheckInDayKey(useDayKey)) {
|
|
98
|
+
return res.status(400).json({
|
|
99
|
+
error: 'Choose the day as a date.'
|
|
100
|
+
});
|
|
101
|
+
}
|
|
91
102
|
if (action === 'clear') {
|
|
92
103
|
cart.lines = [];
|
|
93
104
|
} else if (!line.productId) {
|
|
@@ -107,6 +118,24 @@ import { cartCookieName, mintCartId, readCartId } from "./cart-cookie.js";
|
|
|
107
118
|
error: 'Unknown product'
|
|
108
119
|
});
|
|
109
120
|
}
|
|
121
|
+
// A use day is asked only by an item that asks for one, and is a
|
|
122
|
+
// day that has not passed on the store's calendar (AGL-4043).
|
|
123
|
+
const isNewLine = !cart.lines.some((held)=>CommerceModel.cartLineKey(held) === CommerceModel.cartLineKey(line));
|
|
124
|
+
if (useDayKey && (action === 'add' || isNewLine)) {
|
|
125
|
+
var _line_variantId;
|
|
126
|
+
var _product_variants_;
|
|
127
|
+
const product = productSnapshot.exists ? CommerceModel.liftLegacyProduct(productSnapshot.data()) : null;
|
|
128
|
+
const variantId = (_line_variantId = line.variantId) != null ? _line_variantId : product == null ? void 0 : (_product_variants_ = product.variants[0]) == null ? void 0 : _product_variants_.id;
|
|
129
|
+
if (!product || !CommerceModel.productAsksUseDate(product, variantId)) {
|
|
130
|
+
return res.status(400).json({
|
|
131
|
+
error: 'This item has no day to choose.'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const problem = CommerceModel.checkInUseDayProblem(useDayKey, (await readStoreDay(hostRef)).todayKey);
|
|
135
|
+
if (problem) return res.status(400).json({
|
|
136
|
+
error: problem
|
|
137
|
+
});
|
|
138
|
+
}
|
|
110
139
|
}
|
|
111
140
|
cart.lines = CommerceModel.upsertCartLine(cart, line, action === 'set' ? 'set' : 'add');
|
|
112
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/cart.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 { PluginApiHandler } from '@aglyn/aglyn/server'\nimport * as Aglyn from '@aglyn/aglyn/server'\nimport * as CommerceModel from '../model'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { isDocumentId } from '@aglyn/tenant-data-admin/server/document-id'\nimport { cartCookieName, mintCartId, readCartId } from './cart-cookie'\n\nexport interface ResolvedCartLine extends CommerceModel.CartLine {\n name: string\n variantLabel?: string\n unitAmountCents: number\n imageUrl?: string\n /** Line no longer purchasable (deleted/draft/sold out). */\n unavailable?: boolean\n}\n\n/**\n * Server-backed cart (AGL-293): cookie-keyed doc under\n * `hosts/{hostId}/carts`. GET returns the resolved cart; POST mutates\n * with {action: add|set|remove|clear}. Lines resolve against product\n * docs on every read so prices/names never go stale, and unavailable\n * lines surface instead of silently charging.\n */\nexport const cartHandler: PluginApiHandler = async (req, res) => {\n const isPost = req.method === 'POST'\n if (!isPost && req.method !== 'GET') {\n return res.status(405).json({ error: 'Method not allowed' })\n }\n const body = isPost\n ? typeof req.body === 'string'\n ? JSON.parse(req.body || '{}')\n : (req.body ?? {})\n : {}\n // AGL-1769: BOTH components of the path this handler writes come from the\n // caller — `hostId` off the body, `cartId` off a cookie whose name embeds\n // `hostId` — and `.doc()` appends a slash-separated PATH rather than taking\n // one opaque id. So an unvalidated pair named the nesting as well as the\n // document: a `hostId` of `a/b/c` wrote under `hosts/a/b/c`, invisible to\n // every console list because they resolve the host doc first.\n //\n // This handler is the one visitor-facing write in the AGL-1763 sweep that\n // needs NO credentials — no session, no member gate, no signature — so it is\n // the one place the id rule has to hold on its own.\n const hostId = String((isPost ? body.hostId : req.query.hostId) ?? '')\n // The message names BOTH causes it now covers (`762621581`): the guard reads\n // as \"absent\" but also refuses a hostId that is a path rather than an id, and\n // a caller told only \"missing\" would go looking for the wrong mistake.\n // AGL-1771: `isDocumentId`, not the cart module's old `isCartId` alias — this\n // value is a HOST id, and the rule it has to satisfy was never about carts.\n if (!isDocumentId(hostId))\n return res.status(400).json({ error: 'Missing or invalid hostId' })\n\n const cookieName = cartCookieName(hostId)\n // A cookie that is not a single document id reads as NO cart: a GET returns\n // an empty one and a POST mints a fresh id below, exactly as for a first-time\n // visitor. Nothing is stranded — a path that was never a cart id was never a\n // basket anyone filled.\n let cartId = readCartId(req.cookies, hostId)\n const firestore = firebaseAdmin.app().firestore()\n const hostRef = firestore.collection('hosts').doc(hostId)\n\n try {\n if (!cartId) {\n if (!isPost) return res.status(200).json({ lines: [], count: 0 })\n cartId = mintCartId()\n res.setHeader(\n 'Set-Cookie',\n `${cookieName}=${cartId}; Path=/; Max-Age=${60 * 60 * 24 * 90}; ` +\n 'HttpOnly; SameSite=Lax; Secure',\n )\n }\n const cartRef = hostRef.collection('carts').doc(cartId)\n const cartSnapshot = await cartRef.get()\n const cart: CommerceModel.HostCart = (cartSnapshot.data() as any) ?? { lines: [] }\n\n if (isPost) {\n const action = String(body.action ?? 'add')\n const line: CommerceModel.CartLine = {\n productId: String(body.productId ?? ''),\n ...(body.variantId ? { variantId: String(body.variantId) } : {}),\n // Clamped at the door as well as in the model (AGL-2285): the route\n // used `Math.round(Number(...))` alone, which yields `NaN` for\n // `{\"quantity\":\"x\"}` and slipped past `upsertCartLine`'s `<= 0` guard.\n quantity: Math.min(\n CommerceModel.CART_MAX_QUANTITY,\n Math.max(\n -CommerceModel.CART_MAX_QUANTITY,\n Number.isFinite(Number(body.quantity ?? 1))\n ? Math.round(Number(body.quantity ?? 1))\n : 0,\n ),\n ),\n }\n if (action === 'clear') {\n cart.lines = []\n } else if (!line.productId) {\n return res.status(400).json({ error: 'Missing productId' })\n } else if (action === 'remove') {\n cart.lines = CommerceModel.removeCartLine(cart, line)\n } else {\n // A product sold in person only (AGL-4060) never enters a basket: it\n // answers as no product at all, as its page does. A line already in\n // the cart stays removable and resolves as unavailable below.\n if (line.quantity > 0 && isDocumentId(line.productId)) {\n const productSnapshot = await hostRef.collection('products').doc(line.productId).get()\n if (productSnapshot.exists && !CommerceModel.productSellsOnline(productSnapshot.data())) {\n return res.status(404).json({ error: 'Unknown product' })\n }\n }\n cart.lines = CommerceModel.upsertCartLine(\n cart,\n line,\n action === 'set' ? 'set' : 'add',\n )\n }\n // AGL-1769: never mint an EMPTY cart. `clear` returns above before the\n // `!line.productId` check, so `{ hostId, action: 'clear' }` — no\n // product, valid or otherwise, and no credentials — used to create a\n // document per request holding `lines: []` and two timestamps. A `remove`\n // or a `set 0` that empties an absent basket is the same request wearing\n // a productId. A cart that would store no lines is not a cart.\n //\n // AGL-1760's test — does refusing discard money or work that already\n // occurred — is passed trivially here: there is no basket to strand. The\n // caller still gets its cookie and its empty-cart response, so the next\n // add lands on this id and creates the document properly.\n if (cartSnapshot.exists || cart.lines.length > 0) {\n await cartRef.set(\n {\n lines: cart.lines,\n updatedAtMs: Date.now(),\n ...(cartSnapshot.exists ? {} : { createdAtMs: Date.now() }),\n },\n { merge: true },\n )\n }\n }\n\n // Resolve display lines from product docs — never trust stored data.\n const uniqueProductIds = [...new Set(cart.lines.map((l) => l.productId))]\n const productSnapshots = await Promise.all(\n uniqueProductIds.map((id) =>\n hostRef.collection('products').doc(id).get(),\n ),\n )\n const productsById = new Map(\n productSnapshots.map((snapshot) => [\n snapshot.id,\n snapshot.exists ? CommerceModel.liftLegacyProduct(snapshot.data() as any) : null,\n ]),\n )\n const lines: ResolvedCartLine[] = cart.lines.map((line) => {\n const product = productsById.get(line.productId)\n if (!product || !CommerceModel.productListedOnline(product)) {\n return {\n ...line,\n name: product?.name ?? 'Unavailable product',\n unitAmountCents: 0,\n unavailable: true,\n }\n }\n const variant = line.variantId\n ? product.variants.find((item) => item.id === line.variantId)\n : product.variants[0]\n // A variant with no price yet (AGL-2916) is not for sale, and never a\n // line worth nothing.\n if (!variant || !CommerceModel.variantHasPrice(variant)) {\n return {\n ...line,\n name: product.name,\n unitAmountCents: 0,\n unavailable: true,\n }\n }\n return {\n ...line,\n name: product.name,\n ...(Object.keys(variant.options ?? {}).length\n ? { variantLabel: Object.values(variant.options ?? {}).join(' / ') }\n : {}),\n unitAmountCents: Math.round(Number(variant.priceUsd) * 100),\n ...(variant.imageUrl || product.mediaUrls?.[0] || product.imageUrl\n ? {\n imageUrl:\n variant.imageUrl ??\n product.mediaUrls?.[0] ??\n product.imageUrl,\n }\n : {}),\n ...(CommerceModel.canPurchase(product, variant.id, line.quantity)\n ? {}\n : { unavailable: true }),\n }\n })\n const subtotalCents = lines\n .filter((line) => !line.unavailable)\n .reduce((sum, line) => sum + line.unitAmountCents * line.quantity, 0)\n return res.status(200).json({\n lines,\n count: CommerceModel.cartCount(cart),\n subtotalCents,\n })\n } catch (error) {\n console.error(error)\n return res.status(500).json({ error: 'Cart unavailable' })\n }\n}\n"],"names":["CommerceModel","firebaseAdmin","isDocumentId","cartCookieName","mintCartId","readCartId","cartHandler","req","res","isPost","method","status","json","error","body","JSON","parse","hostId","String","query","cookieName","cartId","cookies","firestore","app","hostRef","collection","doc","cartSnapshot","lines","count","setHeader","cartRef","get","cart","data","action","line","productId","variantId","quantity","Math","min","CART_MAX_QUANTITY","max","Number","isFinite","round","removeCartLine","productSnapshot","exists","productSellsOnline","upsertCartLine","length","set","updatedAtMs","Date","now","createdAtMs","merge","uniqueProductIds","Set","map","l","productSnapshots","Promise","all","id","productsById","Map","snapshot","liftLegacyProduct","variant","product","productListedOnline","name","unitAmountCents","unavailable","variants","find","item","variantHasPrice","Object","keys","options","variantLabel","values","join","priceUsd","imageUrl","mediaUrls","canPurchase","subtotalCents","filter","reduce","sum","cartCount","console"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/cart.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 { PluginApiHandler } from '@aglyn/aglyn/server'\nimport * as Aglyn from '@aglyn/aglyn/server'\nimport * as CommerceModel from '../model'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { isDocumentId } from '@aglyn/tenant-data-admin/server/document-id'\nimport { cartCookieName, mintCartId, readCartId } from './cart-cookie'\nimport { readStoreDay } from './store-day'\n\nexport interface ResolvedCartLine extends CommerceModel.CartLine {\n name: string\n variantLabel?: string\n unitAmountCents: number\n imageUrl?: string\n /** Line no longer purchasable (deleted/draft/sold out). */\n unavailable?: boolean\n}\n\n/**\n * Server-backed cart (AGL-293): cookie-keyed doc under\n * `hosts/{hostId}/carts`. GET returns the resolved cart; POST mutates\n * with {action: add|set|remove|clear}. Lines resolve against product\n * docs on every read so prices/names never go stale, and unavailable\n * lines surface instead of silently charging.\n */\nexport const cartHandler: PluginApiHandler = async (req, res) => {\n const isPost = req.method === 'POST'\n if (!isPost && req.method !== 'GET') {\n return res.status(405).json({ error: 'Method not allowed' })\n }\n const body = isPost\n ? typeof req.body === 'string'\n ? JSON.parse(req.body || '{}')\n : (req.body ?? {})\n : {}\n // AGL-1769: BOTH components of the path this handler writes come from the\n // caller — `hostId` off the body, `cartId` off a cookie whose name embeds\n // `hostId` — and `.doc()` appends a slash-separated PATH rather than taking\n // one opaque id. So an unvalidated pair named the nesting as well as the\n // document: a `hostId` of `a/b/c` wrote under `hosts/a/b/c`, invisible to\n // every console list because they resolve the host doc first.\n //\n // This handler is the one visitor-facing write in the AGL-1763 sweep that\n // needs NO credentials — no session, no member gate, no signature — so it is\n // the one place the id rule has to hold on its own.\n const hostId = String((isPost ? body.hostId : req.query.hostId) ?? '')\n // The message names BOTH causes it now covers (`762621581`): the guard reads\n // as \"absent\" but also refuses a hostId that is a path rather than an id, and\n // a caller told only \"missing\" would go looking for the wrong mistake.\n // AGL-1771: `isDocumentId`, not the cart module's old `isCartId` alias — this\n // value is a HOST id, and the rule it has to satisfy was never about carts.\n if (!isDocumentId(hostId))\n return res.status(400).json({ error: 'Missing or invalid hostId' })\n\n const cookieName = cartCookieName(hostId)\n // A cookie that is not a single document id reads as NO cart: a GET returns\n // an empty one and a POST mints a fresh id below, exactly as for a first-time\n // visitor. Nothing is stranded — a path that was never a cart id was never a\n // basket anyone filled.\n let cartId = readCartId(req.cookies, hostId)\n const firestore = firebaseAdmin.app().firestore()\n const hostRef = firestore.collection('hosts').doc(hostId)\n\n try {\n if (!cartId) {\n if (!isPost) return res.status(200).json({ lines: [], count: 0 })\n cartId = mintCartId()\n res.setHeader(\n 'Set-Cookie',\n `${cookieName}=${cartId}; Path=/; Max-Age=${60 * 60 * 24 * 90}; ` +\n 'HttpOnly; SameSite=Lax; Secure',\n )\n }\n const cartRef = hostRef.collection('carts').doc(cartId)\n const cartSnapshot = await cartRef.get()\n const cart: CommerceModel.HostCart = (cartSnapshot.data() as any) ?? { lines: [] }\n\n if (isPost) {\n const action = String(body.action ?? 'add')\n // The day the shopper chose to use a check-in item (AGL-4043): part of\n // the line's identity, so two days of one pass are two lines.\n const useDayKey = typeof body.useDayKey === 'string' ? body.useDayKey.trim() : ''\n const line: CommerceModel.CartLine = {\n productId: String(body.productId ?? ''),\n ...(body.variantId ? { variantId: String(body.variantId) } : {}),\n ...(useDayKey ? { useDayKey } : {}),\n // Clamped at the door as well as in the model (AGL-2285): the route\n // used `Math.round(Number(...))` alone, which yields `NaN` for\n // `{\"quantity\":\"x\"}` and slipped past `upsertCartLine`'s `<= 0` guard.\n quantity: Math.min(\n CommerceModel.CART_MAX_QUANTITY,\n Math.max(\n -CommerceModel.CART_MAX_QUANTITY,\n Number.isFinite(Number(body.quantity ?? 1))\n ? Math.round(Number(body.quantity ?? 1))\n : 0,\n ),\n ),\n }\n if (useDayKey && !CommerceModel.isCheckInDayKey(useDayKey)) {\n return res.status(400).json({ error: 'Choose the day as a date.' })\n }\n if (action === 'clear') {\n cart.lines = []\n } else if (!line.productId) {\n return res.status(400).json({ error: 'Missing productId' })\n } else if (action === 'remove') {\n cart.lines = CommerceModel.removeCartLine(cart, line)\n } else {\n // A product sold in person only (AGL-4060) never enters a basket: it\n // answers as no product at all, as its page does. A line already in\n // the cart stays removable and resolves as unavailable below.\n if (line.quantity > 0 && isDocumentId(line.productId)) {\n const productSnapshot = await hostRef.collection('products').doc(line.productId).get()\n if (productSnapshot.exists && !CommerceModel.productSellsOnline(productSnapshot.data())) {\n return res.status(404).json({ error: 'Unknown product' })\n }\n // A use day is asked only by an item that asks for one, and is a\n // day that has not passed on the store's calendar (AGL-4043).\n const isNewLine = !cart.lines.some(\n (held) => CommerceModel.cartLineKey(held) === CommerceModel.cartLineKey(line),\n )\n if (useDayKey && (action === 'add' || isNewLine)) {\n const product = productSnapshot.exists ? CommerceModel.liftLegacyProduct(productSnapshot.data() as any) : null\n const variantId = line.variantId ?? product?.variants[0]?.id\n if (!product || !CommerceModel.productAsksUseDate(product, variantId)) {\n return res.status(400).json({ error: 'This item has no day to choose.' })\n }\n const problem = CommerceModel.checkInUseDayProblem(useDayKey, (await readStoreDay(hostRef)).todayKey)\n if (problem) return res.status(400).json({ error: problem })\n }\n }\n cart.lines = CommerceModel.upsertCartLine(\n cart,\n line,\n action === 'set' ? 'set' : 'add',\n )\n }\n // AGL-1769: never mint an EMPTY cart. `clear` returns above before the\n // `!line.productId` check, so `{ hostId, action: 'clear' }` — no\n // product, valid or otherwise, and no credentials — used to create a\n // document per request holding `lines: []` and two timestamps. A `remove`\n // or a `set 0` that empties an absent basket is the same request wearing\n // a productId. A cart that would store no lines is not a cart.\n //\n // AGL-1760's test — does refusing discard money or work that already\n // occurred — is passed trivially here: there is no basket to strand. The\n // caller still gets its cookie and its empty-cart response, so the next\n // add lands on this id and creates the document properly.\n if (cartSnapshot.exists || cart.lines.length > 0) {\n await cartRef.set(\n {\n lines: cart.lines,\n updatedAtMs: Date.now(),\n ...(cartSnapshot.exists ? {} : { createdAtMs: Date.now() }),\n },\n { merge: true },\n )\n }\n }\n\n // Resolve display lines from product docs — never trust stored data.\n const uniqueProductIds = [...new Set(cart.lines.map((l) => l.productId))]\n const productSnapshots = await Promise.all(\n uniqueProductIds.map((id) =>\n hostRef.collection('products').doc(id).get(),\n ),\n )\n const productsById = new Map(\n productSnapshots.map((snapshot) => [\n snapshot.id,\n snapshot.exists ? CommerceModel.liftLegacyProduct(snapshot.data() as any) : null,\n ]),\n )\n const lines: ResolvedCartLine[] = cart.lines.map((line) => {\n const product = productsById.get(line.productId)\n if (!product || !CommerceModel.productListedOnline(product)) {\n return {\n ...line,\n name: product?.name ?? 'Unavailable product',\n unitAmountCents: 0,\n unavailable: true,\n }\n }\n const variant = line.variantId\n ? product.variants.find((item) => item.id === line.variantId)\n : product.variants[0]\n // A variant with no price yet (AGL-2916) is not for sale, and never a\n // line worth nothing.\n if (!variant || !CommerceModel.variantHasPrice(variant)) {\n return {\n ...line,\n name: product.name,\n unitAmountCents: 0,\n unavailable: true,\n }\n }\n return {\n ...line,\n name: product.name,\n ...(Object.keys(variant.options ?? {}).length\n ? { variantLabel: Object.values(variant.options ?? {}).join(' / ') }\n : {}),\n unitAmountCents: Math.round(Number(variant.priceUsd) * 100),\n ...(variant.imageUrl || product.mediaUrls?.[0] || product.imageUrl\n ? {\n imageUrl:\n variant.imageUrl ??\n product.mediaUrls?.[0] ??\n product.imageUrl,\n }\n : {}),\n ...(CommerceModel.canPurchase(product, variant.id, line.quantity)\n ? {}\n : { unavailable: true }),\n }\n })\n const subtotalCents = lines\n .filter((line) => !line.unavailable)\n .reduce((sum, line) => sum + line.unitAmountCents * line.quantity, 0)\n return res.status(200).json({\n lines,\n count: CommerceModel.cartCount(cart),\n subtotalCents,\n })\n } catch (error) {\n console.error(error)\n return res.status(500).json({ error: 'Cart unavailable' })\n }\n}\n"],"names":["CommerceModel","firebaseAdmin","isDocumentId","cartCookieName","mintCartId","readCartId","readStoreDay","cartHandler","req","res","isPost","method","status","json","error","body","JSON","parse","hostId","String","query","cookieName","cartId","cookies","firestore","app","hostRef","collection","doc","cartSnapshot","lines","count","setHeader","cartRef","get","cart","data","action","useDayKey","trim","line","productId","variantId","quantity","Math","min","CART_MAX_QUANTITY","max","Number","isFinite","round","isCheckInDayKey","removeCartLine","productSnapshot","exists","productSellsOnline","isNewLine","some","held","cartLineKey","product","liftLegacyProduct","variants","id","productAsksUseDate","problem","checkInUseDayProblem","todayKey","upsertCartLine","length","set","updatedAtMs","Date","now","createdAtMs","merge","uniqueProductIds","Set","map","l","productSnapshots","Promise","all","productsById","Map","snapshot","variant","productListedOnline","name","unitAmountCents","unavailable","find","item","variantHasPrice","Object","keys","options","variantLabel","values","join","priceUsd","imageUrl","mediaUrls","canPurchase","subtotalCents","filter","reduce","sum","cartCount","console"],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@ import { merchantAccountIsReady } from "@aglyn/tenant-data-admin/server/payment-
|
|
|
24
24
|
import { checkoutSessionCardAuthenticationParams } from "@aglyn/tenant-data-admin/server/stripe-card-authentication";
|
|
25
25
|
import { CARRIER_POSTAL_CODE_MESSAGE, planCheckoutShippingWithCarriers } from "./carrier-shipping.js";
|
|
26
26
|
import { readActiveMemberSession } from "./membership.js";
|
|
27
|
+
import { readStoreDay } from "./store-day.js";
|
|
27
28
|
import { resolveManualTaxRateId } from "./manual-tax-rate.js";
|
|
28
29
|
import { taxEngineSessionMetadata } from "../model/commerce-tax-engine.js";
|
|
29
30
|
import { quoteSaleTaxWithEngine } from "./tax-engine-quote.js";
|
|
@@ -66,6 +67,9 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
66
67
|
const productId = String((_body_productId = body.productId) != null ? _body_productId : '');
|
|
67
68
|
const variantId = String((_body_variantId = body.variantId) != null ? _body_variantId : '');
|
|
68
69
|
const quantity = Math.max(1, Math.min(99, Math.round(Number((_body_quantity = body.quantity) != null ? _body_quantity : 1))));
|
|
70
|
+
// The day the buyer chose to use a check-in item (AGL-4043); checked below
|
|
71
|
+
// against the product and the store's calendar.
|
|
72
|
+
const useDayKey = typeof body.useDayKey === 'string' ? body.useDayKey.trim() : '';
|
|
69
73
|
const couponCode = String((_body_couponCode = body.couponCode) != null ? _body_couponCode : '').trim().toUpperCase().slice(0, 40);
|
|
70
74
|
// Buyer-chosen billing (AGL-545): a request, never an instruction —
|
|
71
75
|
// the session mode re-resolves from the product doc below.
|
|
@@ -127,16 +131,20 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
127
131
|
error: 'Unknown product'
|
|
128
132
|
});
|
|
129
133
|
}
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
|
|
134
|
+
// Variant pricing (AGL-292): the buyer's selection maps to a variant;
|
|
135
|
+
// absent variantId keeps the legacy default-variant behavior.
|
|
136
|
+
const lifted = CommerceModel.liftLegacyProduct(product);
|
|
137
|
+
// For sale online at all (AGL-4060): live, ACTIVE and sold online, the
|
|
138
|
+
// one check the cart's checkout makes of every line. A draft or archived
|
|
139
|
+
// product has no page, so Buy now answers it the 404 the product page
|
|
140
|
+
// does; a product sold in person only is bought at the register, the
|
|
141
|
+
// kiosk or the POS apps, never here. Asked of the LIFTED product, as the
|
|
142
|
+
// cart asks it, so a legacy document with no status still sells.
|
|
143
|
+
if (!CommerceModel.productListedOnline(lifted)) {
|
|
133
144
|
return res.status(404).json({
|
|
134
145
|
error: 'Unknown product'
|
|
135
146
|
});
|
|
136
147
|
}
|
|
137
|
-
// Variant pricing (AGL-292): the buyer's selection maps to a variant;
|
|
138
|
-
// absent variantId keeps the legacy default-variant behavior.
|
|
139
|
-
const lifted = CommerceModel.liftLegacyProduct(product);
|
|
140
148
|
const variant = variantId ? lifted.variants.find((item)=>item.id === variantId) : lifted.variants[0];
|
|
141
149
|
if (!variant) return res.status(404).json({
|
|
142
150
|
error: 'Unknown variant'
|
|
@@ -168,6 +176,25 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
168
176
|
// Seller resolution rides the owning org (AGL-238): plan gate from
|
|
169
177
|
// the org doc, Stripe account from the owner's marketplace profile.
|
|
170
178
|
const ownerOrg = await getOrgForHost(hostId);
|
|
179
|
+
// A use day (AGL-4043): only on an item that asks for one, and a day
|
|
180
|
+
// that has not passed on the store's calendar. Refused before anything
|
|
181
|
+
// is held, so a wrong day costs the buyer nothing.
|
|
182
|
+
if (useDayKey) {
|
|
183
|
+
var _ref5, _hostSnapshot_data;
|
|
184
|
+
if (!CommerceModel.productAsksUseDate(lifted, variant.id)) {
|
|
185
|
+
return res.status(400).json({
|
|
186
|
+
error: 'This item has no day to choose.'
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
const storeDay = await readStoreDay(hostRef, {
|
|
190
|
+
org: (_ref5 = ownerOrg == null ? void 0 : ownerOrg.org) != null ? _ref5 : null,
|
|
191
|
+
host: (_hostSnapshot_data = hostSnapshot.data()) != null ? _hostSnapshot_data : null
|
|
192
|
+
});
|
|
193
|
+
const problem = CommerceModel.checkInUseDayProblem(useDayKey, storeDay.todayKey);
|
|
194
|
+
if (problem) return res.status(400).json({
|
|
195
|
+
error: problem
|
|
196
|
+
});
|
|
197
|
+
}
|
|
171
198
|
const ownerId = ownerOrg == null ? void 0 : (_ownerOrg_org = ownerOrg.org) == null ? void 0 : _ownerOrg_org.ownerUid;
|
|
172
199
|
if (!ownerId) {
|
|
173
200
|
return res.status(409).json({
|
|
@@ -333,10 +360,10 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
333
360
|
// hub did not already answer for this code.
|
|
334
361
|
let appliedCoupon = '';
|
|
335
362
|
if (couponCode && !resolvedDiscount) {
|
|
336
|
-
var
|
|
363
|
+
var _ref6;
|
|
337
364
|
const couponSnapshot = await hostRef.collection('coupons').doc(couponCode).get();
|
|
338
365
|
const coupon = couponSnapshot.data();
|
|
339
|
-
const percentOff = Number((
|
|
366
|
+
const percentOff = Number((_ref6 = coupon == null ? void 0 : coupon.percentOff) != null ? _ref6 : 0);
|
|
340
367
|
const expired = (coupon == null ? void 0 : coupon.expiresAtMs) != null && Number(coupon.expiresAtMs) < Date.now();
|
|
341
368
|
// A PRE-FILTER, no longer the enforcement (AGL-2453). It answers early so
|
|
342
369
|
// an obviously spent code 400s before a claim is minted, and it counts
|
|
@@ -633,13 +660,13 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
633
660
|
// paths quietly diverge. Behaviour here is unchanged.
|
|
634
661
|
let recurringTaxRateId = '';
|
|
635
662
|
if (isSubscription && taxCents > 0) {
|
|
636
|
-
var
|
|
637
|
-
recurringTaxRateId = (
|
|
663
|
+
var _ref7;
|
|
664
|
+
recurringTaxRateId = (_ref7 = await resolveManualTaxRateId({
|
|
638
665
|
hostRef,
|
|
639
666
|
taxPct,
|
|
640
667
|
taxLabel,
|
|
641
668
|
headers: stripeKeyHeader('tax-rate')
|
|
642
|
-
})) != null ?
|
|
669
|
+
})) != null ? _ref7 : '';
|
|
643
670
|
if (!recurringTaxRateId) {
|
|
644
671
|
// Nothing was sold — hand the key back so the same button works
|
|
645
672
|
// once Stripe does (AGL-1697).
|
|
@@ -732,10 +759,10 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
732
759
|
// The unnamed `Local pickup` rate gives way to the store's pickup
|
|
733
760
|
// locations, which the shopper chooses before checkout (AGL-3624).
|
|
734
761
|
if (localPlan.kind === 'shipping' && (shippingSettings == null ? void 0 : shippingSettings.localPickup) && shippingPlan.options.some((option)=>option.rateId === CommerceModel.LOCAL_PICKUP_RATE_ID)) {
|
|
735
|
-
var
|
|
762
|
+
var _ref8;
|
|
736
763
|
const { pickupLocations } = await readLocalFulfillmentStore({
|
|
737
764
|
hostRef,
|
|
738
|
-
storeSettings: (
|
|
765
|
+
storeSettings: (_ref8 = storeSettings.data == null ? void 0 : storeSettings.data.call(storeSettings)) != null ? _ref8 : null,
|
|
739
766
|
host: null
|
|
740
767
|
});
|
|
741
768
|
if (pickupLocations.length) {
|
|
@@ -923,6 +950,8 @@ import { ensureCheckoutDomain } from "./payment-method-domains.js";
|
|
|
923
950
|
'metadata[productId]': productId
|
|
924
951
|
}, variantId ? {
|
|
925
952
|
'metadata[variantId]': variantId
|
|
953
|
+
} : {}, useDayKey ? {
|
|
954
|
+
'metadata[useDayKey]': useDayKey
|
|
926
955
|
} : {}, {
|
|
927
956
|
'metadata[quantity]': String(quantity),
|
|
928
957
|
'metadata[feeCents]': String(feeCents)
|