@aglyn/plugins-commerce 1.0.0-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +10 -0
- package/package.json +57 -0
- package/src/index.d.ts +38 -0
- package/src/index.js +38 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/account.d.ts +31 -0
- package/src/lib/components/account.js +645 -0
- package/src/lib/components/account.js.map +1 -0
- package/src/lib/components/cart.d.ts +38 -0
- package/src/lib/components/cart.js +851 -0
- package/src/lib/components/cart.js.map +1 -0
- package/src/lib/components/commerce-console-page.d.ts +32 -0
- package/src/lib/components/commerce-console-page.js +296 -0
- package/src/lib/components/commerce-console-page.js.map +1 -0
- package/src/lib/components/commerce-console-sections.d.ts +34 -0
- package/src/lib/components/commerce-console-sections.js +62 -0
- package/src/lib/components/commerce-console-sections.js.map +1 -0
- package/src/lib/components/console/catalog-organization-card.component.d.ts +14 -0
- package/src/lib/components/console/catalog-organization-card.component.js +1087 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-analytics-card.component.d.ts +27 -0
- package/src/lib/components/console/commerce-analytics-card.component.js +310 -0
- package/src/lib/components/console/commerce-analytics-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-glance-card.component.d.ts +20 -0
- package/src/lib/components/console/commerce-glance-card.component.js +340 -0
- package/src/lib/components/console/commerce-glance-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-stat-tile.component.d.ts +37 -0
- package/src/lib/components/console/commerce-stat-tile.component.js +72 -0
- package/src/lib/components/console/commerce-stat-tile.component.js.map +1 -0
- package/src/lib/components/console/discounts-card.component.d.ts +14 -0
- package/src/lib/components/console/discounts-card.component.js +443 -0
- package/src/lib/components/console/discounts-card.component.js.map +1 -0
- package/src/lib/components/console/entitlement-gate.component.d.ts +76 -0
- package/src/lib/components/console/entitlement-gate.component.js +115 -0
- package/src/lib/components/console/entitlement-gate.component.js.map +1 -0
- package/src/lib/components/console/gift-cards-card.component.d.ts +29 -0
- package/src/lib/components/console/gift-cards-card.component.js +379 -0
- package/src/lib/components/console/gift-cards-card.component.js.map +1 -0
- package/src/lib/components/console/host-coupons-card.component.d.ts +14 -0
- package/src/lib/components/console/host-coupons-card.component.js +252 -0
- package/src/lib/components/console/host-coupons-card.component.js.map +1 -0
- package/src/lib/components/console/host-orders-card.component.d.ts +13 -0
- package/src/lib/components/console/host-orders-card.component.js +861 -0
- package/src/lib/components/console/host-orders-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.d.ts +14 -0
- package/src/lib/components/console/locations-card.component.js +256 -0
- package/src/lib/components/console/locations-card.component.js.map +1 -0
- package/src/lib/components/console/member-posts-card.component.d.ts +8 -0
- package/src/lib/components/console/member-posts-card.component.js +283 -0
- package/src/lib/components/console/member-posts-card.component.js.map +1 -0
- package/src/lib/components/console/newest-site-users-card.component.d.ts +36 -0
- package/src/lib/components/console/newest-site-users-card.component.js +126 -0
- package/src/lib/components/console/newest-site-users-card.component.js.map +1 -0
- package/src/lib/components/console/order-detail-dialog.component.d.ts +28 -0
- package/src/lib/components/console/order-detail-dialog.component.js +976 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -0
- package/src/lib/components/console/paid-media.d.ts +127 -0
- package/src/lib/components/console/paid-media.js +397 -0
- package/src/lib/components/console/paid-media.js.map +1 -0
- package/src/lib/components/console/payments-settings-card.component.d.ts +13 -0
- package/src/lib/components/console/payments-settings-card.component.js +295 -0
- package/src/lib/components/console/payments-settings-card.component.js.map +1 -0
- package/src/lib/components/console/pos-page.component.d.ts +13 -0
- package/src/lib/components/console/pos-page.component.js +916 -0
- package/src/lib/components/console/pos-page.component.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.d.ts +32 -0
- package/src/lib/components/console/product-editor-dialog.component.js +1374 -0
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -0
- package/src/lib/components/console/products-hub-card.component.d.ts +16 -0
- package/src/lib/components/console/products-hub-card.component.js +1280 -0
- package/src/lib/components/console/products-hub-card.component.js.map +1 -0
- package/src/lib/components/console/products-hub-zone.component.d.ts +50 -0
- package/src/lib/components/console/products-hub-zone.component.js +200 -0
- package/src/lib/components/console/products-hub-zone.component.js.map +1 -0
- package/src/lib/components/console/recovery-queue-card.component.d.ts +39 -0
- package/src/lib/components/console/recovery-queue-card.component.js +262 -0
- package/src/lib/components/console/recovery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/registers-card.component.d.ts +21 -0
- package/src/lib/components/console/registers-card.component.js +296 -0
- package/src/lib/components/console/registers-card.component.js.map +1 -0
- package/src/lib/components/console/reservations-card.component.d.ts +14 -0
- package/src/lib/components/console/reservations-card.component.js +650 -0
- package/src/lib/components/console/reservations-card.component.js.map +1 -0
- package/src/lib/components/console/reviews-moderation-card.component.d.ts +8 -0
- package/src/lib/components/console/reviews-moderation-card.component.js +235 -0
- package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -0
- package/src/lib/components/console/shipping-settings-card.component.d.ts +38 -0
- package/src/lib/components/console/shipping-settings-card.component.js +560 -0
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.d.ts +31 -0
- package/src/lib/components/console/stock-movements-card.component.js +333 -0
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -0
- package/src/lib/components/console/store-settings-card.component.d.ts +14 -0
- package/src/lib/components/console/store-settings-card.component.js +300 -0
- package/src/lib/components/console/store-settings-card.component.js.map +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.d.ts +73 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js +408 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -0
- package/src/lib/components/console/suppliers-card.component.d.ts +8 -0
- package/src/lib/components/console/suppliers-card.component.js +328 -0
- package/src/lib/components/console/suppliers-card.component.js.map +1 -0
- package/src/lib/components/console/tax-settings-card.component.d.ts +14 -0
- package/src/lib/components/console/tax-settings-card.component.js +473 -0
- package/src/lib/components/console/tax-settings-card.component.js.map +1 -0
- package/src/lib/components/gate.d.ts +39 -0
- package/src/lib/components/gate.js +202 -0
- package/src/lib/components/gate.js.map +1 -0
- package/src/lib/components/gated-video.d.ts +40 -0
- package/src/lib/components/gated-video.js +366 -0
- package/src/lib/components/gated-video.js.map +1 -0
- package/src/lib/components/member-feed.d.ts +32 -0
- package/src/lib/components/member-feed.js +198 -0
- package/src/lib/components/member-feed.js.map +1 -0
- package/src/lib/components/member-recovery.d.ts +35 -0
- package/src/lib/components/member-recovery.js +313 -0
- package/src/lib/components/member-recovery.js.map +1 -0
- package/src/lib/components/member-signin.d.ts +35 -0
- package/src/lib/components/member-signin.js +257 -0
- package/src/lib/components/member-signin.js.map +1 -0
- package/src/lib/components/member-signup.d.ts +34 -0
- package/src/lib/components/member-signup.js +287 -0
- package/src/lib/components/member-signup.js.map +1 -0
- package/src/lib/components/newsletter-signup.d.ts +39 -0
- package/src/lib/components/newsletter-signup.js +229 -0
- package/src/lib/components/newsletter-signup.js.map +1 -0
- package/src/lib/components/product-detail.d.ts +38 -0
- package/src/lib/components/product-detail.js +1022 -0
- package/src/lib/components/product-detail.js.map +1 -0
- package/src/lib/components/product-grid.d.ts +67 -0
- package/src/lib/components/product-grid.js +909 -0
- package/src/lib/components/product-grid.js.map +1 -0
- package/src/lib/components/product-reviews.d.ts +32 -0
- package/src/lib/components/product-reviews.js +349 -0
- package/src/lib/components/product-reviews.js.map +1 -0
- package/src/lib/components/related-products.d.ts +33 -0
- package/src/lib/components/related-products.js +232 -0
- package/src/lib/components/related-products.js.map +1 -0
- package/src/lib/components/reservation-widget.d.ts +33 -0
- package/src/lib/components/reservation-widget.js +418 -0
- package/src/lib/components/reservation-widget.js.map +1 -0
- package/src/lib/components/storefront-payment-element-fallback.d.ts +18 -0
- package/src/lib/components/storefront-payment-element-fallback.js +51 -0
- package/src/lib/components/storefront-payment-element-fallback.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +78 -0
- package/src/lib/components/storefront-payment-element.js +156 -0
- package/src/lib/components/storefront-payment-element.js.map +1 -0
- package/src/lib/components/wishlist.d.ts +46 -0
- package/src/lib/components/wishlist.js +304 -0
- package/src/lib/components/wishlist.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +18 -0
- package/src/lib/constants/bundle-common.js +18 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/product-filters.d.ts +35 -0
- package/src/lib/constants/product-filters.js +109 -0
- package/src/lib/constants/product-filters.js.map +1 -0
- package/src/lib/model/commerce-cart.d.ts +52 -0
- package/src/lib/model/commerce-cart.js +102 -0
- package/src/lib/model/commerce-cart.js.map +1 -0
- package/src/lib/model/commerce-connect-transfer.d.ts +243 -0
- package/src/lib/model/commerce-connect-transfer.js +231 -0
- package/src/lib/model/commerce-connect-transfer.js.map +1 -0
- package/src/lib/model/commerce-discounts.d.ts +164 -0
- package/src/lib/model/commerce-discounts.js +231 -0
- package/src/lib/model/commerce-discounts.js.map +1 -0
- package/src/lib/model/commerce-dispute.d.ts +124 -0
- package/src/lib/model/commerce-dispute.js +225 -0
- package/src/lib/model/commerce-dispute.js.map +1 -0
- package/src/lib/model/commerce-gift-cards.d.ts +107 -0
- package/src/lib/model/commerce-gift-cards.js +121 -0
- package/src/lib/model/commerce-gift-cards.js.map +1 -0
- package/src/lib/model/commerce-io.d.ts +36 -0
- package/src/lib/model/commerce-io.js +245 -0
- package/src/lib/model/commerce-io.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +1040 -0
- package/src/lib/model/commerce-orders.js +1022 -0
- package/src/lib/model/commerce-orders.js.map +1 -0
- package/src/lib/model/commerce-promotions.d.ts +188 -0
- package/src/lib/model/commerce-promotions.js +199 -0
- package/src/lib/model/commerce-promotions.js.map +1 -0
- package/src/lib/model/commerce-reservations.d.ts +175 -0
- package/src/lib/model/commerce-reservations.js +157 -0
- package/src/lib/model/commerce-reservations.js.map +1 -0
- package/src/lib/model/commerce-shipping.d.ts +316 -0
- package/src/lib/model/commerce-shipping.js +484 -0
- package/src/lib/model/commerce-shipping.js.map +1 -0
- package/src/lib/model/commerce-stock-holds.d.ts +199 -0
- package/src/lib/model/commerce-stock-holds.js +190 -0
- package/src/lib/model/commerce-stock-holds.js.map +1 -0
- package/src/lib/model/commerce-subscription-status.d.ts +67 -0
- package/src/lib/model/commerce-subscription-status.js +76 -0
- package/src/lib/model/commerce-subscription-status.js.map +1 -0
- package/src/lib/model/commerce-tax-decision.d.ts +222 -0
- package/src/lib/model/commerce-tax-decision.js +165 -0
- package/src/lib/model/commerce-tax-decision.js.map +1 -0
- package/src/lib/model/commerce-tax.d.ts +176 -0
- package/src/lib/model/commerce-tax.js +92 -0
- package/src/lib/model/commerce-tax.js.map +1 -0
- package/src/lib/model/commerce.d.ts +551 -0
- package/src/lib/model/commerce.js +739 -0
- package/src/lib/model/commerce.js.map +1 -0
- package/src/lib/model/index.d.ts +40 -0
- package/src/lib/model/index.js +40 -0
- package/src/lib/model/index.js.map +1 -0
- package/src/lib/model/order-figures.d.ts +48 -0
- package/src/lib/model/order-figures.js +74 -0
- package/src/lib/model/order-figures.js.map +1 -0
- package/src/lib/model/plugin-permissions.d.ts +23 -0
- package/src/lib/model/plugin-permissions.js +34 -0
- package/src/lib/model/plugin-permissions.js.map +1 -0
- package/src/lib/model/purchase-analytics.d.ts +186 -0
- package/src/lib/model/purchase-analytics.js +216 -0
- package/src/lib/model/purchase-analytics.js.map +1 -0
- package/src/lib/plugin-config.d.ts +62 -0
- package/src/lib/plugin-config.js +78 -0
- package/src/lib/plugin-config.js.map +1 -0
- package/src/lib/plugin.d.ts +28 -0
- package/src/lib/plugin.js +147 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/server/billing-webhook.d.ts +26 -0
- package/src/lib/server/billing-webhook.js +4011 -0
- package/src/lib/server/billing-webhook.js.map +1 -0
- package/src/lib/server/cancel-order.d.ts +87 -0
- package/src/lib/server/cancel-order.js +368 -0
- package/src/lib/server/cancel-order.js.map +1 -0
- package/src/lib/server/cart-checkout.d.ts +25 -0
- package/src/lib/server/cart-checkout.js +976 -0
- package/src/lib/server/cart-checkout.js.map +1 -0
- package/src/lib/server/cart-cookie.d.ts +32 -0
- package/src/lib/server/cart-cookie.js +77 -0
- package/src/lib/server/cart-cookie.js.map +1 -0
- package/src/lib/server/cart.d.ts +34 -0
- package/src/lib/server/cart.js +181 -0
- package/src/lib/server/cart.js.map +1 -0
- package/src/lib/server/catalog.d.ts +127 -0
- package/src/lib/server/catalog.js +277 -0
- package/src/lib/server/catalog.js.map +1 -0
- package/src/lib/server/checkout.d.ts +36 -0
- package/src/lib/server/checkout.js +915 -0
- package/src/lib/server/checkout.js.map +1 -0
- package/src/lib/server/connect.d.ts +26 -0
- package/src/lib/server/connect.js +238 -0
- package/src/lib/server/connect.js.map +1 -0
- package/src/lib/server/contact-refund.d.ts +117 -0
- package/src/lib/server/contact-refund.js +196 -0
- package/src/lib/server/contact-refund.js.map +1 -0
- package/src/lib/server/download.d.ts +39 -0
- package/src/lib/server/download.js +206 -0
- package/src/lib/server/download.js.map +1 -0
- package/src/lib/server/draft-order.d.ts +26 -0
- package/src/lib/server/draft-order.js +706 -0
- package/src/lib/server/draft-order.js.map +1 -0
- package/src/lib/server/feed.d.ts +24 -0
- package/src/lib/server/feed.js +59 -0
- package/src/lib/server/feed.js.map +1 -0
- package/src/lib/server/fulfill-order.d.ts +97 -0
- package/src/lib/server/fulfill-order.js +235 -0
- package/src/lib/server/fulfill-order.js.map +1 -0
- package/src/lib/server/gate.d.ts +36 -0
- package/src/lib/server/gate.js +112 -0
- package/src/lib/server/gate.js.map +1 -0
- package/src/lib/server/gift-cards.d.ts +42 -0
- package/src/lib/server/gift-cards.js +219 -0
- package/src/lib/server/gift-cards.js.map +1 -0
- package/src/lib/server/low-stock.d.ts +49 -0
- package/src/lib/server/low-stock.js +60 -0
- package/src/lib/server/low-stock.js.map +1 -0
- package/src/lib/server/manual-tax-rate.d.ts +82 -0
- package/src/lib/server/manual-tax-rate.js +113 -0
- package/src/lib/server/manual-tax-rate.js.map +1 -0
- package/src/lib/server/member-feed.d.ts +24 -0
- package/src/lib/server/member-feed.js +72 -0
- package/src/lib/server/member-feed.js.map +1 -0
- package/src/lib/server/member-name-search.d.ts +37 -0
- package/src/lib/server/member-name-search.js +42 -0
- package/src/lib/server/member-name-search.js.map +1 -0
- package/src/lib/server/member-post.d.ts +23 -0
- package/src/lib/server/member-post.js +166 -0
- package/src/lib/server/member-post.js.map +1 -0
- package/src/lib/server/membership-account.d.ts +37 -0
- package/src/lib/server/membership-account.js +148 -0
- package/src/lib/server/membership-account.js.map +1 -0
- package/src/lib/server/membership-admin-password.d.ts +33 -0
- package/src/lib/server/membership-admin-password.js +202 -0
- package/src/lib/server/membership-admin-password.js.map +1 -0
- package/src/lib/server/membership-content.d.ts +23 -0
- package/src/lib/server/membership-content.js +105 -0
- package/src/lib/server/membership-content.js.map +1 -0
- package/src/lib/server/membership-login.d.ts +19 -0
- package/src/lib/server/membership-login.js +137 -0
- package/src/lib/server/membership-login.js.map +1 -0
- package/src/lib/server/membership-logout.d.ts +19 -0
- package/src/lib/server/membership-logout.js +35 -0
- package/src/lib/server/membership-logout.js.map +1 -0
- package/src/lib/server/membership-recover.d.ts +60 -0
- package/src/lib/server/membership-recover.js +244 -0
- package/src/lib/server/membership-recover.js.map +1 -0
- package/src/lib/server/membership-register.d.ts +22 -0
- package/src/lib/server/membership-register.js +241 -0
- package/src/lib/server/membership-register.js.map +1 -0
- package/src/lib/server/membership-reset.d.ts +26 -0
- package/src/lib/server/membership-reset.js +88 -0
- package/src/lib/server/membership-reset.js.map +1 -0
- package/src/lib/server/membership-wishlist.d.ts +23 -0
- package/src/lib/server/membership-wishlist.js +89 -0
- package/src/lib/server/membership-wishlist.js.map +1 -0
- package/src/lib/server/membership.d.ts +96 -0
- package/src/lib/server/membership.js +222 -0
- package/src/lib/server/membership.js.map +1 -0
- package/src/lib/server/native-checkout.d.ts +170 -0
- package/src/lib/server/native-checkout.js +193 -0
- package/src/lib/server/native-checkout.js.map +1 -0
- package/src/lib/server/newsletter.d.ts +23 -0
- package/src/lib/server/newsletter.js +323 -0
- package/src/lib/server/newsletter.js.map +1 -0
- package/src/lib/server/notify-restock.d.ts +22 -0
- package/src/lib/server/notify-restock.js +84 -0
- package/src/lib/server/notify-restock.js.map +1 -0
- package/src/lib/server/order-analytics.d.ts +134 -0
- package/src/lib/server/order-analytics.js +263 -0
- package/src/lib/server/order-analytics.js.map +1 -0
- package/src/lib/server/order-figures.d.ts +33 -0
- package/src/lib/server/order-figures.js +220 -0
- package/src/lib/server/order-figures.js.map +1 -0
- package/src/lib/server/paid-media-delivery.d.ts +173 -0
- package/src/lib/server/paid-media-delivery.js +212 -0
- package/src/lib/server/paid-media-delivery.js.map +1 -0
- package/src/lib/server/pos-order.d.ts +54 -0
- package/src/lib/server/pos-order.js +1137 -0
- package/src/lib/server/pos-order.js.map +1 -0
- package/src/lib/server/process-abandoned.d.ts +54 -0
- package/src/lib/server/process-abandoned.js +222 -0
- package/src/lib/server/process-abandoned.js.map +1 -0
- package/src/lib/server/process-restock.d.ts +42 -0
- package/src/lib/server/process-restock.js +219 -0
- package/src/lib/server/process-restock.js.map +1 -0
- package/src/lib/server/product-card.d.ts +29 -0
- package/src/lib/server/product-card.js +54 -0
- package/src/lib/server/product-card.js.map +1 -0
- package/src/lib/server/product.d.ts +70 -0
- package/src/lib/server/product.js +105 -0
- package/src/lib/server/product.js.map +1 -0
- package/src/lib/server/promotion-hold.d.ts +144 -0
- package/src/lib/server/promotion-hold.js +174 -0
- package/src/lib/server/promotion-hold.js.map +1 -0
- package/src/lib/server/reconcile-stock.d.ts +106 -0
- package/src/lib/server/reconcile-stock.js +349 -0
- package/src/lib/server/reconcile-stock.js.map +1 -0
- package/src/lib/server/refund.d.ts +45 -0
- package/src/lib/server/refund.js +607 -0
- package/src/lib/server/refund.js.map +1 -0
- package/src/lib/server/related.d.ts +24 -0
- package/src/lib/server/related.js +104 -0
- package/src/lib/server/related.js.map +1 -0
- package/src/lib/server/reservation-availability.d.ts +23 -0
- package/src/lib/server/reservation-availability.js +111 -0
- package/src/lib/server/reservation-availability.js.map +1 -0
- package/src/lib/server/reserve-stock.d.ts +156 -0
- package/src/lib/server/reserve-stock.js +146 -0
- package/src/lib/server/reserve-stock.js.map +1 -0
- package/src/lib/server/reserve.d.ts +25 -0
- package/src/lib/server/reserve.js +426 -0
- package/src/lib/server/reserve.js.map +1 -0
- package/src/lib/server/restock-flag.d.ts +202 -0
- package/src/lib/server/restock-flag.js +449 -0
- package/src/lib/server/restock-flag.js.map +1 -0
- package/src/lib/server/reviews.d.ts +51 -0
- package/src/lib/server/reviews.js +132 -0
- package/src/lib/server/reviews.js.map +1 -0
- package/src/lib/server/site-page-enricher.d.ts +42 -0
- package/src/lib/server/site-page-enricher.js +149 -0
- package/src/lib/server/site-page-enricher.js.map +1 -0
- package/src/lib/server/site-page-resolver.d.ts +26 -0
- package/src/lib/server/site-page-resolver.js +223 -0
- package/src/lib/server/site-page-resolver.js.map +1 -0
- package/src/lib/server/stock-hold.d.ts +127 -0
- package/src/lib/server/stock-hold.js +258 -0
- package/src/lib/server/stock-hold.js.map +1 -0
- package/src/lib/server/storefront-tax-record.d.ts +22 -0
- package/src/lib/server/storefront-tax-record.js +218 -0
- package/src/lib/server/storefront-tax-record.js.map +1 -0
- package/src/lib/server/storefront-tax.d.ts +197 -0
- package/src/lib/server/storefront-tax.js +245 -0
- package/src/lib/server/storefront-tax.js.map +1 -0
- package/src/lib/server/stream.d.ts +25 -0
- package/src/lib/server/stream.js +191 -0
- package/src/lib/server/stream.js.map +1 -0
- package/src/lib/server/subscription-portal.d.ts +24 -0
- package/src/lib/server/subscription-portal.js +91 -0
- package/src/lib/server/subscription-portal.js.map +1 -0
- package/src/lib/server/supplier-outbox.d.ts +190 -0
- package/src/lib/server/supplier-outbox.js +342 -0
- package/src/lib/server/supplier-outbox.js.map +1 -0
- package/src/lib/server/supplier-update.d.ts +23 -0
- package/src/lib/server/supplier-update.js +289 -0
- package/src/lib/server/supplier-update.js.map +1 -0
- package/src/lib/server/tax-profile.d.ts +29 -0
- package/src/lib/server/tax-profile.js +40 -0
- package/src/lib/server/tax-profile.js.map +1 -0
- package/src/lib/server.d.ts +32 -0
- package/src/lib/server.js +311 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/site.d.ts +27 -0
- package/src/lib/site.js +134 -0
- package/src/lib/site.js.map +1 -0
- package/src/lib/utils/escape-html.d.ts +41 -0
- package/src/lib/utils/escape-html.js +41 -0
- package/src/lib/utils/escape-html.js.map +1 -0
- package/src/lib/utils/generate-preset-id.d.ts +19 -0
- package/src/lib/utils/generate-preset-id.js +25 -0
- package/src/lib/utils/generate-preset-id.js.map +1 -0
- package/src/lib/utils/member-continue.d.ts +45 -0
- package/src/lib/utils/member-continue.js +49 -0
- package/src/lib/utils/member-continue.js.map +1 -0
- package/src/lib/utils/use-storefront-purchase-event.d.ts +60 -0
- package/src/lib/utils/use-storefront-purchase-event.js +142 -0
- package/src/lib/utils/use-storefront-purchase-event.js.map +1 -0
|
@@ -0,0 +1,216 @@
|
|
|
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
|
+
*/ /** Money, to two decimals. A float sum of cents produces `59.99999999999999`. */ function toAmount(cents) {
|
|
17
|
+
return Math.round(cents) / 100;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the `purchase` a TENANT STOREFRONT reports to the MERCHANT's GA4
|
|
21
|
+
* property (AGL-1641).
|
|
22
|
+
*
|
|
23
|
+
* ## Whose revenue this is — the decision, not an inference
|
|
24
|
+
*
|
|
25
|
+
* This is the exact inverse of the marketplace call in AGL-1639, and the
|
|
26
|
+
* reason is the property the hit lands in. There, the GA property is OURS, the
|
|
27
|
+
* platform fee IS what Aglyn was paid, and `value` had to be platform net so
|
|
28
|
+
* that a marketplace sale and a subscription meant the same thing when GA
|
|
29
|
+
* added them up. Here the property is the MERCHANT's — `gtag` on a tenant site
|
|
30
|
+
* is loaded with `host.analytics.gaMeasurementId`, their measurement id — and
|
|
31
|
+
* on their storefront the merchant is the seller. Aglyn's cut is not a share
|
|
32
|
+
* of this sale from their side; it is a cost of making it.
|
|
33
|
+
*
|
|
34
|
+
* So `feeCents` is NOT subtracted. Subtracting it would report the merchant's
|
|
35
|
+
* gross margin after our fee as though it were their sales revenue, which is
|
|
36
|
+
* not a number any merchant's books, tax return or ad platform recognises.
|
|
37
|
+
*
|
|
38
|
+
* Getting this backwards is the expensive mistake: reporting platform net into
|
|
39
|
+
* a merchant's property would show every merchant on Aglyn a revenue figure a
|
|
40
|
+
* few percent of their real one.
|
|
41
|
+
*
|
|
42
|
+
* ## Tax is excluded, and no `tax` param is sent
|
|
43
|
+
*
|
|
44
|
+
* Tax collected is money held for a taxing authority, not revenue, whoever
|
|
45
|
+
* holds it — and on a storefront that is often Aglyn rather than the merchant,
|
|
46
|
+
* since Terms §10.7 makes Aglyn a marketplace facilitator where applicable law
|
|
47
|
+
* gives it a collection obligation (AGL-1956). Either way it is not the
|
|
48
|
+
* merchant's sales revenue. Every mature ecommerce integration reports revenue
|
|
49
|
+
* ex-tax and so do we.
|
|
50
|
+
*
|
|
51
|
+
* No GA4 `tax` param either, following AGL-1639 for the same reason it applied
|
|
52
|
+
* there: `value` already EXCLUDES tax, and GA4's `tax` is documented as a cost
|
|
53
|
+
* associated with the transaction — a component of the value beside it. Sent
|
|
54
|
+
* next to an ex-tax `value` it asserts a relationship that does not hold, and
|
|
55
|
+
* invites exactly the subtraction that would double-remove it.
|
|
56
|
+
*
|
|
57
|
+
* ## Why `value` derives from `totalCents` and not from the parts
|
|
58
|
+
*
|
|
59
|
+
* `totalCents` is overwritten with Stripe's `amount_total` when the webhook
|
|
60
|
+
* writes the order (`billing-webhook.ts`), so it is the one field that
|
|
61
|
+
* reconciles with Stripe by construction: it is Stripe's own number, verbatim.
|
|
62
|
+
*
|
|
63
|
+
* `taxCents` was described here as likewise `total_details.amount_tax`, Stripe's
|
|
64
|
+
* own. On the cart path it is. On the BUY-NOW path it was 0 on every order,
|
|
65
|
+
* because `checkout.ts` sends manual destination tax as an ordinary
|
|
66
|
+
* `line_items[1]` product line that Stripe never classifies as tax — so this
|
|
67
|
+
* `value` reported tax-inclusive gross into the merchant's property, the
|
|
68
|
+
* AGL-1639 overstatement, live. AGL-1711 composes the stored `taxCents` from
|
|
69
|
+
* `amount_tax` plus that line-item tax, and fixes `quantity` and
|
|
70
|
+
* `unitAmountCents` (hardcoded to 1 and to the whole charge) in the same place.
|
|
71
|
+
* Nothing here changed: the three fields this reads are simply true now.
|
|
72
|
+
*
|
|
73
|
+
* The parts used NOT to reconcile, and that is why this derivation exists.
|
|
74
|
+
* `computeOrderTotals` was called with `feeCents`, `taxCents` and
|
|
75
|
+
* `discountCents` but **never `shippingCents`**, so a stored `OrderTotals`
|
|
76
|
+
* recorded `shippingCents: 0` on every online order while the shipping the
|
|
77
|
+
* shopper paid sat inside `amount_total`. Building `value` from
|
|
78
|
+
* `itemsCents + shippingCents - discountCents` would therefore have silently
|
|
79
|
+
* dropped all shipping revenue, understating orders that carried it and
|
|
80
|
+
* leaving orders that did not looking correct. Same failure shape as the
|
|
81
|
+
* AGL-1639 overstatement, opposite sign.
|
|
82
|
+
*
|
|
83
|
+
* AGL-1698 fixed the storage — `computeCheckoutSessionTotals` passes
|
|
84
|
+
* `total_details.amount_shipping`, and the parts now sum to the total. The
|
|
85
|
+
* derivation stays on `totalCents` anyway, for a reason that outlives the bug:
|
|
86
|
+
* `totalCents` is Stripe's `amount_total` verbatim, whereas `itemsCents` is
|
|
87
|
+
* priced from the host's product docs, so a price edit between session
|
|
88
|
+
* creation and webhook delivery would make our sum disagree with the charge.
|
|
89
|
+
*
|
|
90
|
+
* ## A GA4 `shipping` param IS sent — and a `tax` one still is not
|
|
91
|
+
*
|
|
92
|
+
* These two look like an inconsistency and are not. Do not tidy them into
|
|
93
|
+
* agreement in either direction (AGL-1722).
|
|
94
|
+
*
|
|
95
|
+
* `shipping` is a COMPONENT of the `value` reported beside it: `value` is
|
|
96
|
+
* `totalCents - taxCents`, and the shipping the shopper paid is inside that
|
|
97
|
+
* number. GA4's `shipping` is documented as exactly that — shipping charged
|
|
98
|
+
* ON the transaction — so sending it decomposes the value rather than
|
|
99
|
+
* contradicting it, and a merchant can read "of the $105 you sold, $10 was
|
|
100
|
+
* shipping" without any figure being counted twice.
|
|
101
|
+
*
|
|
102
|
+
* `tax` is the opposite: `value` already EXCLUDES it. Sending a `tax` beside
|
|
103
|
+
* an ex-tax `value` asserts a relationship that does not hold and invites the
|
|
104
|
+
* subtraction that removes tax a second time. AGL-1639 and AGL-1641 both
|
|
105
|
+
* declined it for that reason and this change does not disturb them.
|
|
106
|
+
*
|
|
107
|
+
* The param was withheld until now for a truthfulness reason that has since
|
|
108
|
+
* expired twice. AGL-1641 left it out because the stored `shippingCents` was
|
|
109
|
+
* structurally 0 — sending it would have asserted FREE SHIPPING on every
|
|
110
|
+
* order rather than saying nothing. AGL-1698 fixed the storage but the Stripe
|
|
111
|
+
* figure was still structurally 0, because no Checkout Session we created
|
|
112
|
+
* declared `shipping_options`. AGL-1707 wired the merchant's configured zones
|
|
113
|
+
* and rates into the cart session and AGL-1720 into the buy-now one, so
|
|
114
|
+
* `amount_shipping` is a real number on both storefront paths for a merchant
|
|
115
|
+
* who set shipping up. Only the plumbing was left, and it is built here:
|
|
116
|
+
* `shippingCents` rides `StorefrontPurchaseSource` to the wire shape.
|
|
117
|
+
*
|
|
118
|
+
* A 0 now means what it says. A download ships nothing, a merchant who saved
|
|
119
|
+
* no rates charges nothing, and POS and draft orders resolve no shipping — on
|
|
120
|
+
* all of those `shipping: 0` is a true statement about that order, not the old
|
|
121
|
+
* structural zero, so it is sent rather than omitted. Omitting it would leave
|
|
122
|
+
* the merchant's shipping column sparse for a reason GA cannot tell apart from
|
|
123
|
+
* "not tracked".
|
|
124
|
+
*
|
|
125
|
+
* ## Worked example — the spec fixture
|
|
126
|
+
*
|
|
127
|
+
* A $100 item, a $5 coupon, $10 shipping chosen at Stripe Checkout, $9.08 tax,
|
|
128
|
+
* and a 5% Aglyn fee:
|
|
129
|
+
*
|
|
130
|
+
* itemsCents 10000 line snapshot
|
|
131
|
+
* - discountCents 500 Stripe `total_details.amount_discount`
|
|
132
|
+
* + shippingCents 1000 Stripe `total_details.amount_shipping`
|
|
133
|
+
* + taxCents 908 Stripe `total_details.amount_tax`
|
|
134
|
+
* = totalCents 11408 Stripe `amount_total`, verbatim
|
|
135
|
+
* - taxCents - 908 held for the state, not revenue
|
|
136
|
+
* = GA `value` 10500 sent as 105.00 (goods 95.00 + shipping 10.00)
|
|
137
|
+
* GA `shipping` 1000 sent as 10.00 — INSIDE the 105.00 above, a
|
|
138
|
+
* decomposition of it and not an addition
|
|
139
|
+
* GA `tax` — not sent; `value` is already ex-tax
|
|
140
|
+
*
|
|
141
|
+
* feeCents 475 Aglyn's cut — NOT subtracted; the merchant's
|
|
142
|
+
* cost of sale, and our revenue is reported in
|
|
143
|
+
* OUR property by the subscription/marketplace
|
|
144
|
+
* `purchase`, not by this one.
|
|
145
|
+
*
|
|
146
|
+
* Before AGL-1698 the stored parts summed to 10408, not 11408: the 1000 gap was
|
|
147
|
+
* the shipping, and it is exactly what a parts-based `value` would have lost.
|
|
148
|
+
* They reconcile now, which `commerce-orders.spec.ts` pins; the guard below
|
|
149
|
+
* survives as a guard, since the derivation must not drift back to the parts.
|
|
150
|
+
*
|
|
151
|
+
* Returns `null` when there is nothing truthful to send — no transaction id,
|
|
152
|
+
* or a non-positive value. A dropped event is a gap in the merchant's report;
|
|
153
|
+
* a fabricated one is a wrong number in it, and the second is worse.
|
|
154
|
+
*/ export function buildStorefrontPurchaseParams(source) {
|
|
155
|
+
var _ref, _ref1, _ref2, _ref3, _ref4;
|
|
156
|
+
const transactionId = String((_ref = source == null ? void 0 : source.transactionId) != null ? _ref : '').trim();
|
|
157
|
+
if (!transactionId) return null;
|
|
158
|
+
const totalCents = Math.round(Number((_ref1 = source == null ? void 0 : source.totalCents) != null ? _ref1 : 0));
|
|
159
|
+
const taxCents = Math.max(0, Math.round(Number((_ref2 = source == null ? void 0 : source.taxCents) != null ? _ref2 : 0)));
|
|
160
|
+
const netCents = totalCents - taxCents;
|
|
161
|
+
if (!Number.isFinite(netCents) || netCents <= 0) return null;
|
|
162
|
+
// Clamped like `taxCents`, and for the same reason: a negative component
|
|
163
|
+
// would be subtracted out of a `value` that does not move with it.
|
|
164
|
+
const shippingCents = Math.max(0, Math.round(Number((_ref3 = source == null ? void 0 : source.shippingCents) != null ? _ref3 : 0)));
|
|
165
|
+
return {
|
|
166
|
+
transaction_id: transactionId,
|
|
167
|
+
// No currency is stored on an order and `buildBeginCheckoutParams` takes
|
|
168
|
+
// the same default, so the storefront's two ecommerce events agree.
|
|
169
|
+
currency: 'USD',
|
|
170
|
+
value: toAmount(netCents),
|
|
171
|
+
// ALWAYS sent, including as 0. `value` is ex-tax and shipping is inside
|
|
172
|
+
// it, so `shipping` describes the number beside it rather than adding to
|
|
173
|
+
// it — and 0 is a true statement about an order that carried no shipping
|
|
174
|
+
// (a download, a merchant who configured no rates, POS, a draft), not the
|
|
175
|
+
// old structural zero. Omitting it on those would leave the merchant's
|
|
176
|
+
// shipping column sparse for a reason GA cannot distinguish from "not
|
|
177
|
+
// tracked".
|
|
178
|
+
shipping: toAmount(shippingCents),
|
|
179
|
+
items: ((_ref4 = source == null ? void 0 : source.lineItems) != null ? _ref4 : []).map((line)=>{
|
|
180
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
181
|
+
return {
|
|
182
|
+
// The PRODUCT id, matching `view_item` / `add_to_cart` /
|
|
183
|
+
// `begin_checkout`, so GA joins all four into one per-product funnel.
|
|
184
|
+
// A variant id here would break that join at the last step.
|
|
185
|
+
item_id: String((_ref = line == null ? void 0 : line.productId) != null ? _ref : ''),
|
|
186
|
+
item_name: String((_ref1 = line == null ? void 0 : line.name) != null ? _ref1 : ''),
|
|
187
|
+
price: toAmount(Number((_ref2 = line == null ? void 0 : line.unitAmountCents) != null ? _ref2 : 0)),
|
|
188
|
+
quantity: Number((_ref3 = line == null ? void 0 : line.quantity) != null ? _ref3 : 1)
|
|
189
|
+
};
|
|
190
|
+
})
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Reduce a stored order to the wire shape above. Server-side only — it reads
|
|
195
|
+
* fields the projection exists to withhold.
|
|
196
|
+
*/ export function toStorefrontPurchaseSource(transactionId, order) {
|
|
197
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
198
|
+
var _order_totals, _order_totals1, _order_totals2;
|
|
199
|
+
return {
|
|
200
|
+
transactionId,
|
|
201
|
+
totalCents: Number((_ref = order == null ? void 0 : (_order_totals = order.totals) == null ? void 0 : _order_totals.totalCents) != null ? _ref : 0),
|
|
202
|
+
taxCents: Number((_ref1 = order == null ? void 0 : (_order_totals1 = order.totals) == null ? void 0 : _order_totals1.taxCents) != null ? _ref1 : 0),
|
|
203
|
+
shippingCents: Number((_ref2 = order == null ? void 0 : (_order_totals2 = order.totals) == null ? void 0 : _order_totals2.shippingCents) != null ? _ref2 : 0),
|
|
204
|
+
lineItems: ((_ref3 = order == null ? void 0 : order.lineItems) != null ? _ref3 : []).map((line)=>{
|
|
205
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
206
|
+
return {
|
|
207
|
+
productId: String((_ref = line == null ? void 0 : line.productId) != null ? _ref : ''),
|
|
208
|
+
name: String((_ref1 = line == null ? void 0 : line.name) != null ? _ref1 : ''),
|
|
209
|
+
quantity: Number((_ref2 = line == null ? void 0 : line.quantity) != null ? _ref2 : 1),
|
|
210
|
+
unitAmountCents: Number((_ref3 = line == null ? void 0 : line.unitAmountCents) != null ? _ref3 : 0)
|
|
211
|
+
};
|
|
212
|
+
})
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
//# sourceMappingURL=purchase-analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/purchase-analytics.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 { AnalyticsEventParams } from '@aglyn/aglyn/app-utils/analytics-events'\nimport type { HostOrder } from './commerce-orders'\n\n/**\n * The GA-safe projection of a storefront order (AGL-1641). Deliberately NOT\n * `HostOrder`: this shape crosses the wire to a shopper's browser, so it can\n * only ever hold what a `purchase` event needs. `customerEmail`,\n * `customerName`, `shippingAddress` and `billingAddress` are absent by\n * construction rather than by a `delete` somebody has to remember.\n */\nexport interface StorefrontPurchaseSource {\n /** Stripe Checkout Session id — also the order doc id. */\n transactionId: string\n totalCents: number\n taxCents: number\n /**\n * Stripe's `total_details.amount_shipping` as the webhook stored it — or\n * `shipping_cost.amount_total` on a subscription invoice, which has no\n * `total_details`. Reported as GA4's `shipping`, NOT subtracted from\n * `value`: it is part of what the merchant sold.\n */\n shippingCents: number\n lineItems: {\n productId: string\n name: string\n quantity: number\n unitAmountCents: number\n }[]\n}\n\n/** Money, to two decimals. A float sum of cents produces `59.99999999999999`. */\nfunction toAmount(cents: number): number {\n return Math.round(cents) / 100\n}\n\n/**\n * Build the `purchase` a TENANT STOREFRONT reports to the MERCHANT's GA4\n * property (AGL-1641).\n *\n * ## Whose revenue this is — the decision, not an inference\n *\n * This is the exact inverse of the marketplace call in AGL-1639, and the\n * reason is the property the hit lands in. There, the GA property is OURS, the\n * platform fee IS what Aglyn was paid, and `value` had to be platform net so\n * that a marketplace sale and a subscription meant the same thing when GA\n * added them up. Here the property is the MERCHANT's — `gtag` on a tenant site\n * is loaded with `host.analytics.gaMeasurementId`, their measurement id — and\n * on their storefront the merchant is the seller. Aglyn's cut is not a share\n * of this sale from their side; it is a cost of making it.\n *\n * So `feeCents` is NOT subtracted. Subtracting it would report the merchant's\n * gross margin after our fee as though it were their sales revenue, which is\n * not a number any merchant's books, tax return or ad platform recognises.\n *\n * Getting this backwards is the expensive mistake: reporting platform net into\n * a merchant's property would show every merchant on Aglyn a revenue figure a\n * few percent of their real one.\n *\n * ## Tax is excluded, and no `tax` param is sent\n *\n * Tax collected is money held for a taxing authority, not revenue, whoever\n * holds it — and on a storefront that is often Aglyn rather than the merchant,\n * since Terms §10.7 makes Aglyn a marketplace facilitator where applicable law\n * gives it a collection obligation (AGL-1956). Either way it is not the\n * merchant's sales revenue. Every mature ecommerce integration reports revenue\n * ex-tax and so do we.\n *\n * No GA4 `tax` param either, following AGL-1639 for the same reason it applied\n * there: `value` already EXCLUDES tax, and GA4's `tax` is documented as a cost\n * associated with the transaction — a component of the value beside it. Sent\n * next to an ex-tax `value` it asserts a relationship that does not hold, and\n * invites exactly the subtraction that would double-remove it.\n *\n * ## Why `value` derives from `totalCents` and not from the parts\n *\n * `totalCents` is overwritten with Stripe's `amount_total` when the webhook\n * writes the order (`billing-webhook.ts`), so it is the one field that\n * reconciles with Stripe by construction: it is Stripe's own number, verbatim.\n *\n * `taxCents` was described here as likewise `total_details.amount_tax`, Stripe's\n * own. On the cart path it is. On the BUY-NOW path it was 0 on every order,\n * because `checkout.ts` sends manual destination tax as an ordinary\n * `line_items[1]` product line that Stripe never classifies as tax — so this\n * `value` reported tax-inclusive gross into the merchant's property, the\n * AGL-1639 overstatement, live. AGL-1711 composes the stored `taxCents` from\n * `amount_tax` plus that line-item tax, and fixes `quantity` and\n * `unitAmountCents` (hardcoded to 1 and to the whole charge) in the same place.\n * Nothing here changed: the three fields this reads are simply true now.\n *\n * The parts used NOT to reconcile, and that is why this derivation exists.\n * `computeOrderTotals` was called with `feeCents`, `taxCents` and\n * `discountCents` but **never `shippingCents`**, so a stored `OrderTotals`\n * recorded `shippingCents: 0` on every online order while the shipping the\n * shopper paid sat inside `amount_total`. Building `value` from\n * `itemsCents + shippingCents - discountCents` would therefore have silently\n * dropped all shipping revenue, understating orders that carried it and\n * leaving orders that did not looking correct. Same failure shape as the\n * AGL-1639 overstatement, opposite sign.\n *\n * AGL-1698 fixed the storage — `computeCheckoutSessionTotals` passes\n * `total_details.amount_shipping`, and the parts now sum to the total. The\n * derivation stays on `totalCents` anyway, for a reason that outlives the bug:\n * `totalCents` is Stripe's `amount_total` verbatim, whereas `itemsCents` is\n * priced from the host's product docs, so a price edit between session\n * creation and webhook delivery would make our sum disagree with the charge.\n *\n * ## A GA4 `shipping` param IS sent — and a `tax` one still is not\n *\n * These two look like an inconsistency and are not. Do not tidy them into\n * agreement in either direction (AGL-1722).\n *\n * `shipping` is a COMPONENT of the `value` reported beside it: `value` is\n * `totalCents - taxCents`, and the shipping the shopper paid is inside that\n * number. GA4's `shipping` is documented as exactly that — shipping charged\n * ON the transaction — so sending it decomposes the value rather than\n * contradicting it, and a merchant can read \"of the $105 you sold, $10 was\n * shipping\" without any figure being counted twice.\n *\n * `tax` is the opposite: `value` already EXCLUDES it. Sending a `tax` beside\n * an ex-tax `value` asserts a relationship that does not hold and invites the\n * subtraction that removes tax a second time. AGL-1639 and AGL-1641 both\n * declined it for that reason and this change does not disturb them.\n *\n * The param was withheld until now for a truthfulness reason that has since\n * expired twice. AGL-1641 left it out because the stored `shippingCents` was\n * structurally 0 — sending it would have asserted FREE SHIPPING on every\n * order rather than saying nothing. AGL-1698 fixed the storage but the Stripe\n * figure was still structurally 0, because no Checkout Session we created\n * declared `shipping_options`. AGL-1707 wired the merchant's configured zones\n * and rates into the cart session and AGL-1720 into the buy-now one, so\n * `amount_shipping` is a real number on both storefront paths for a merchant\n * who set shipping up. Only the plumbing was left, and it is built here:\n * `shippingCents` rides `StorefrontPurchaseSource` to the wire shape.\n *\n * A 0 now means what it says. A download ships nothing, a merchant who saved\n * no rates charges nothing, and POS and draft orders resolve no shipping — on\n * all of those `shipping: 0` is a true statement about that order, not the old\n * structural zero, so it is sent rather than omitted. Omitting it would leave\n * the merchant's shipping column sparse for a reason GA cannot tell apart from\n * \"not tracked\".\n *\n * ## Worked example — the spec fixture\n *\n * A $100 item, a $5 coupon, $10 shipping chosen at Stripe Checkout, $9.08 tax,\n * and a 5% Aglyn fee:\n *\n * itemsCents 10000 line snapshot\n * - discountCents 500 Stripe `total_details.amount_discount`\n * + shippingCents 1000 Stripe `total_details.amount_shipping`\n * + taxCents 908 Stripe `total_details.amount_tax`\n * = totalCents 11408 Stripe `amount_total`, verbatim\n * - taxCents - 908 held for the state, not revenue\n * = GA `value` 10500 sent as 105.00 (goods 95.00 + shipping 10.00)\n * GA `shipping` 1000 sent as 10.00 — INSIDE the 105.00 above, a\n * decomposition of it and not an addition\n * GA `tax` — not sent; `value` is already ex-tax\n *\n * feeCents 475 Aglyn's cut — NOT subtracted; the merchant's\n * cost of sale, and our revenue is reported in\n * OUR property by the subscription/marketplace\n * `purchase`, not by this one.\n *\n * Before AGL-1698 the stored parts summed to 10408, not 11408: the 1000 gap was\n * the shipping, and it is exactly what a parts-based `value` would have lost.\n * They reconcile now, which `commerce-orders.spec.ts` pins; the guard below\n * survives as a guard, since the derivation must not drift back to the parts.\n *\n * Returns `null` when there is nothing truthful to send — no transaction id,\n * or a non-positive value. A dropped event is a gap in the merchant's report;\n * a fabricated one is a wrong number in it, and the second is worse.\n */\nexport function buildStorefrontPurchaseParams(\n source: StorefrontPurchaseSource,\n): AnalyticsEventParams['purchase'] | null {\n const transactionId = String(source?.transactionId ?? '').trim()\n if (!transactionId) return null\n\n const totalCents = Math.round(Number(source?.totalCents ?? 0))\n const taxCents = Math.max(0, Math.round(Number(source?.taxCents ?? 0)))\n const netCents = totalCents - taxCents\n if (!Number.isFinite(netCents) || netCents <= 0) return null\n // Clamped like `taxCents`, and for the same reason: a negative component\n // would be subtracted out of a `value` that does not move with it.\n const shippingCents = Math.max(0, Math.round(Number(source?.shippingCents ?? 0)))\n\n return {\n transaction_id: transactionId,\n // No currency is stored on an order and `buildBeginCheckoutParams` takes\n // the same default, so the storefront's two ecommerce events agree.\n currency: 'USD',\n value: toAmount(netCents),\n // ALWAYS sent, including as 0. `value` is ex-tax and shipping is inside\n // it, so `shipping` describes the number beside it rather than adding to\n // it — and 0 is a true statement about an order that carried no shipping\n // (a download, a merchant who configured no rates, POS, a draft), not the\n // old structural zero. Omitting it on those would leave the merchant's\n // shipping column sparse for a reason GA cannot distinguish from \"not\n // tracked\".\n shipping: toAmount(shippingCents),\n items: (source?.lineItems ?? []).map((line) => ({\n // The PRODUCT id, matching `view_item` / `add_to_cart` /\n // `begin_checkout`, so GA joins all four into one per-product funnel.\n // A variant id here would break that join at the last step.\n item_id: String(line?.productId ?? ''),\n item_name: String(line?.name ?? ''),\n price: toAmount(Number(line?.unitAmountCents ?? 0)),\n quantity: Number(line?.quantity ?? 1),\n })),\n // No `billing_interval`: a storefront order is not a subscription.\n }\n}\n\n/**\n * Reduce a stored order to the wire shape above. Server-side only — it reads\n * fields the projection exists to withhold.\n */\nexport function toStorefrontPurchaseSource(\n transactionId: string,\n order: Pick<HostOrder, 'totals' | 'lineItems'>,\n): StorefrontPurchaseSource {\n return {\n transactionId,\n totalCents: Number(order?.totals?.totalCents ?? 0),\n taxCents: Number(order?.totals?.taxCents ?? 0),\n shippingCents: Number(order?.totals?.shippingCents ?? 0),\n lineItems: (order?.lineItems ?? []).map((line) => ({\n productId: String(line?.productId ?? ''),\n name: String(line?.name ?? ''),\n quantity: Number(line?.quantity ?? 1),\n unitAmountCents: Number(line?.unitAmountCents ?? 0),\n })),\n }\n}\n"],"names":["toAmount","cents","Math","round","buildStorefrontPurchaseParams","source","transactionId","String","trim","totalCents","Number","taxCents","max","netCents","isFinite","shippingCents","transaction_id","currency","value","shipping","items","lineItems","map","line","item_id","productId","item_name","name","price","unitAmountCents","quantity","toStorefrontPurchaseSource","order","totals"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAgCD,+EAA+E,GAC/E,SAASA,SAASC,KAAa;IAC7B,OAAOC,KAAKC,KAAK,CAACF,SAAS;AAC7B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIC,GACD,OAAO,SAASG,8BACdC,MAAgC;;IAEhC,MAAMC,gBAAgBC,eAAOF,0BAAAA,OAAQC,aAAa,mBAAI,IAAIE,IAAI;IAC9D,IAAI,CAACF,eAAe,OAAO;IAE3B,MAAMG,aAAaP,KAAKC,KAAK,CAACO,gBAAOL,0BAAAA,OAAQI,UAAU,oBAAI;IAC3D,MAAME,WAAWT,KAAKU,GAAG,CAAC,GAAGV,KAAKC,KAAK,CAACO,gBAAOL,0BAAAA,OAAQM,QAAQ,oBAAI;IACnE,MAAME,WAAWJ,aAAaE;IAC9B,IAAI,CAACD,OAAOI,QAAQ,CAACD,aAAaA,YAAY,GAAG,OAAO;IACxD,yEAAyE;IACzE,mEAAmE;IACnE,MAAME,gBAAgBb,KAAKU,GAAG,CAAC,GAAGV,KAAKC,KAAK,CAACO,gBAAOL,0BAAAA,OAAQU,aAAa,oBAAI;IAE7E,OAAO;QACLC,gBAAgBV;QAChB,yEAAyE;QACzE,oEAAoE;QACpEW,UAAU;QACVC,OAAOlB,SAASa;QAChB,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,0EAA0E;QAC1E,uEAAuE;QACvE,sEAAsE;QACtE,YAAY;QACZM,UAAUnB,SAASe;QACnBK,OAAO,UAACf,0BAAAA,OAAQgB,SAAS,oBAAI,EAAE,EAAEC,GAAG,CAAC,CAACC;;mBAAU;gBAC9C,yDAAyD;gBACzD,sEAAsE;gBACtE,4DAA4D;gBAC5DC,SAASjB,eAAOgB,wBAAAA,KAAME,SAAS,mBAAI;gBACnCC,WAAWnB,gBAAOgB,wBAAAA,KAAMI,IAAI,oBAAI;gBAChCC,OAAO5B,SAASU,gBAAOa,wBAAAA,KAAMM,eAAe,oBAAI;gBAChDC,UAAUpB,gBAAOa,wBAAAA,KAAMO,QAAQ,oBAAI;YACrC;;IAEF;AACF;AAEA;;;CAGC,GACD,OAAO,SAASC,2BACdzB,aAAqB,EACrB0B,KAA8C;;QAIzBA,eACFA,gBACKA;IAJxB,OAAO;QACL1B;QACAG,YAAYC,eAAOsB,0BAAAA,gBAAAA,MAAOC,MAAM,qBAAbD,cAAevB,UAAU,mBAAI;QAChDE,UAAUD,gBAAOsB,0BAAAA,iBAAAA,MAAOC,MAAM,qBAAbD,eAAerB,QAAQ,oBAAI;QAC5CI,eAAeL,gBAAOsB,0BAAAA,iBAAAA,MAAOC,MAAM,qBAAbD,eAAejB,aAAa,oBAAI;QACtDM,WAAW,UAACW,yBAAAA,MAAOX,SAAS,oBAAI,EAAE,EAAEC,GAAG,CAAC,CAACC;;mBAAU;gBACjDE,WAAWlB,eAAOgB,wBAAAA,KAAME,SAAS,mBAAI;gBACrCE,MAAMpB,gBAAOgB,wBAAAA,KAAMI,IAAI,oBAAI;gBAC3BG,UAAUpB,gBAAOa,wBAAAA,KAAMO,QAAQ,oBAAI;gBACnCD,iBAAiBnB,gBAAOa,wBAAAA,KAAMM,eAAe,oBAAI;YACnD;;IACF;AACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
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 { PluginConfigSchema } from '@aglyn/aglyn';
|
|
18
|
+
/**
|
|
19
|
+
* The ceiling a register may discount to, when the merchant has not set one
|
|
20
|
+
* (AGL-2161).
|
|
21
|
+
*
|
|
22
|
+
* 100, i.e. today's behaviour exactly. That is deliberate and is the one
|
|
23
|
+
* number in this fix that is NOT a safety judgement:
|
|
24
|
+
*
|
|
25
|
+
* - A full comp is a legitimate register operation — a damaged item, a
|
|
26
|
+
* goodwill gesture, a staff meal — and every merchant on the platform has
|
|
27
|
+
* had it since POS shipped.
|
|
28
|
+
* - Any lower default would change what merchants charge their own customers
|
|
29
|
+
* on the day it deployed, without them asking. Picking that number is a
|
|
30
|
+
* merchant policy decision, not a bug fix, and inventing one here would be
|
|
31
|
+
* the same class of mistake as inventing a billing rate.
|
|
32
|
+
*
|
|
33
|
+
* What AGL-2161 actually fixes is that there was no ceiling to set and no
|
|
34
|
+
* refusal when one was exceeded: the request body's `discountPct` was clamped
|
|
35
|
+
* into range and rung up, so a register sending `150` silently comped the
|
|
36
|
+
* whole sale. The ceiling is now real, enforced server-side, refused rather
|
|
37
|
+
* than clamped, and one config value away from being lower.
|
|
38
|
+
*/
|
|
39
|
+
export declare const POS_MAX_DISCOUNT_PCT_DEFAULT = 100;
|
|
40
|
+
/**
|
|
41
|
+
* Commerce plugin config schema (AGL-428 framework, AGL-2161 adopter).
|
|
42
|
+
*
|
|
43
|
+
* PURE DATA (type-only aglyn import), the same shape as bookings': the client
|
|
44
|
+
* barrel registers it via '@aglyn/aglyn' and the /server entry via
|
|
45
|
+
* '@aglyn/aglyn/server', so neither bundle drags in the other's barrel.
|
|
46
|
+
*
|
|
47
|
+
* `min`/`max` are not decoration — `mergePluginConfig` coerces a stored value
|
|
48
|
+
* into the declared range and falls back to the default on junk, so the
|
|
49
|
+
* ceiling itself cannot be forged out of bounds by a manager editing the
|
|
50
|
+
* settings doc directly.
|
|
51
|
+
*/
|
|
52
|
+
export declare const COMMERCE_CONFIG_SCHEMA: PluginConfigSchema;
|
|
53
|
+
/**
|
|
54
|
+
* The ceiling for one org, read defensively (AGL-2161).
|
|
55
|
+
*
|
|
56
|
+
* Spelled here rather than at the call site so the POS route and any later
|
|
57
|
+
* reader cannot disagree about what a missing or malformed value means. The
|
|
58
|
+
* framework has already clamped and defaulted by the time this runs; the
|
|
59
|
+
* second `Number.isFinite` guard is for the schema-less case, where
|
|
60
|
+
* `getPluginConfig` returns the raw doc untouched.
|
|
61
|
+
*/
|
|
62
|
+
export declare function posMaxDiscountPct(config: Record<string, unknown> | null | undefined): number;
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
* The ceiling a register may discount to, when the merchant has not set one
|
|
18
|
+
* (AGL-2161).
|
|
19
|
+
*
|
|
20
|
+
* 100, i.e. today's behaviour exactly. That is deliberate and is the one
|
|
21
|
+
* number in this fix that is NOT a safety judgement:
|
|
22
|
+
*
|
|
23
|
+
* - A full comp is a legitimate register operation — a damaged item, a
|
|
24
|
+
* goodwill gesture, a staff meal — and every merchant on the platform has
|
|
25
|
+
* had it since POS shipped.
|
|
26
|
+
* - Any lower default would change what merchants charge their own customers
|
|
27
|
+
* on the day it deployed, without them asking. Picking that number is a
|
|
28
|
+
* merchant policy decision, not a bug fix, and inventing one here would be
|
|
29
|
+
* the same class of mistake as inventing a billing rate.
|
|
30
|
+
*
|
|
31
|
+
* What AGL-2161 actually fixes is that there was no ceiling to set and no
|
|
32
|
+
* refusal when one was exceeded: the request body's `discountPct` was clamped
|
|
33
|
+
* into range and rung up, so a register sending `150` silently comped the
|
|
34
|
+
* whole sale. The ceiling is now real, enforced server-side, refused rather
|
|
35
|
+
* than clamped, and one config value away from being lower.
|
|
36
|
+
*/ export const POS_MAX_DISCOUNT_PCT_DEFAULT = 100;
|
|
37
|
+
/**
|
|
38
|
+
* Commerce plugin config schema (AGL-428 framework, AGL-2161 adopter).
|
|
39
|
+
*
|
|
40
|
+
* PURE DATA (type-only aglyn import), the same shape as bookings': the client
|
|
41
|
+
* barrel registers it via '@aglyn/aglyn' and the /server entry via
|
|
42
|
+
* '@aglyn/aglyn/server', so neither bundle drags in the other's barrel.
|
|
43
|
+
*
|
|
44
|
+
* `min`/`max` are not decoration — `mergePluginConfig` coerces a stored value
|
|
45
|
+
* into the declared range and falls back to the default on junk, so the
|
|
46
|
+
* ceiling itself cannot be forged out of bounds by a manager editing the
|
|
47
|
+
* settings doc directly.
|
|
48
|
+
*/ export const COMMERCE_CONFIG_SCHEMA = {
|
|
49
|
+
pluginId: 'commerce',
|
|
50
|
+
fields: [
|
|
51
|
+
{
|
|
52
|
+
key: 'posMaxDiscountPct',
|
|
53
|
+
label: 'Maximum register discount (%)',
|
|
54
|
+
type: 'number',
|
|
55
|
+
min: 0,
|
|
56
|
+
max: 100,
|
|
57
|
+
description: 'The largest discount the point of sale will accept on a sale. ' + 'A register that asks for more is refused, and the sale is not rung ' + 'up. Set to 0 to stop staff discounting at the register entirely.'
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
defaults: {
|
|
61
|
+
posMaxDiscountPct: POS_MAX_DISCOUNT_PCT_DEFAULT
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The ceiling for one org, read defensively (AGL-2161).
|
|
66
|
+
*
|
|
67
|
+
* Spelled here rather than at the call site so the POS route and any later
|
|
68
|
+
* reader cannot disagree about what a missing or malformed value means. The
|
|
69
|
+
* framework has already clamped and defaulted by the time this runs; the
|
|
70
|
+
* second `Number.isFinite` guard is for the schema-less case, where
|
|
71
|
+
* `getPluginConfig` returns the raw doc untouched.
|
|
72
|
+
*/ export function posMaxDiscountPct(config) {
|
|
73
|
+
const raw = Number(config == null ? void 0 : config['posMaxDiscountPct']);
|
|
74
|
+
if (!Number.isFinite(raw)) return POS_MAX_DISCOUNT_PCT_DEFAULT;
|
|
75
|
+
return Math.min(100, Math.max(0, raw));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=plugin-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/plugin-config.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 { PluginConfigSchema } from '@aglyn/aglyn'\n\n/**\n * The ceiling a register may discount to, when the merchant has not set one\n * (AGL-2161).\n *\n * 100, i.e. today's behaviour exactly. That is deliberate and is the one\n * number in this fix that is NOT a safety judgement:\n *\n * - A full comp is a legitimate register operation — a damaged item, a\n * goodwill gesture, a staff meal — and every merchant on the platform has\n * had it since POS shipped.\n * - Any lower default would change what merchants charge their own customers\n * on the day it deployed, without them asking. Picking that number is a\n * merchant policy decision, not a bug fix, and inventing one here would be\n * the same class of mistake as inventing a billing rate.\n *\n * What AGL-2161 actually fixes is that there was no ceiling to set and no\n * refusal when one was exceeded: the request body's `discountPct` was clamped\n * into range and rung up, so a register sending `150` silently comped the\n * whole sale. The ceiling is now real, enforced server-side, refused rather\n * than clamped, and one config value away from being lower.\n */\nexport const POS_MAX_DISCOUNT_PCT_DEFAULT = 100\n\n/**\n * Commerce plugin config schema (AGL-428 framework, AGL-2161 adopter).\n *\n * PURE DATA (type-only aglyn import), the same shape as bookings': the client\n * barrel registers it via '@aglyn/aglyn' and the /server entry via\n * '@aglyn/aglyn/server', so neither bundle drags in the other's barrel.\n *\n * `min`/`max` are not decoration — `mergePluginConfig` coerces a stored value\n * into the declared range and falls back to the default on junk, so the\n * ceiling itself cannot be forged out of bounds by a manager editing the\n * settings doc directly.\n */\nexport const COMMERCE_CONFIG_SCHEMA: PluginConfigSchema = {\n pluginId: 'commerce',\n fields: [\n {\n key: 'posMaxDiscountPct',\n label: 'Maximum register discount (%)',\n type: 'number',\n min: 0,\n max: 100,\n description:\n 'The largest discount the point of sale will accept on a sale. ' +\n 'A register that asks for more is refused, and the sale is not rung ' +\n 'up. Set to 0 to stop staff discounting at the register entirely.',\n },\n ],\n defaults: { posMaxDiscountPct: POS_MAX_DISCOUNT_PCT_DEFAULT },\n}\n\n/**\n * The ceiling for one org, read defensively (AGL-2161).\n *\n * Spelled here rather than at the call site so the POS route and any later\n * reader cannot disagree about what a missing or malformed value means. The\n * framework has already clamped and defaulted by the time this runs; the\n * second `Number.isFinite` guard is for the schema-less case, where\n * `getPluginConfig` returns the raw doc untouched.\n */\nexport function posMaxDiscountPct(\n config: Record<string, unknown> | null | undefined,\n): number {\n const raw = Number(config?.['posMaxDiscountPct'])\n if (!Number.isFinite(raw)) return POS_MAX_DISCOUNT_PCT_DEFAULT\n return Math.min(100, Math.max(0, raw))\n}\n"],"names":["POS_MAX_DISCOUNT_PCT_DEFAULT","COMMERCE_CONFIG_SCHEMA","pluginId","fields","key","label","type","min","max","description","defaults","posMaxDiscountPct","config","raw","Number","isFinite","Math"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAID;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,MAAMA,+BAA+B,IAAG;AAE/C;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,yBAA6C;IACxDC,UAAU;IACVC,QAAQ;QACN;YACEC,KAAK;YACLC,OAAO;YACPC,MAAM;YACNC,KAAK;YACLC,KAAK;YACLC,aACE,mEACA,wEACA;QACJ;KACD;IACDC,UAAU;QAAEC,mBAAmBX;IAA6B;AAC9D,EAAC;AAED;;;;;;;;CAQC,GACD,OAAO,SAASW,kBACdC,MAAkD;IAElD,MAAMC,MAAMC,OAAOF,0BAAAA,MAAQ,CAAC,oBAAoB;IAChD,IAAI,CAACE,OAAOC,QAAQ,CAACF,MAAM,OAAOb;IAClC,OAAOgB,KAAKT,GAAG,CAAC,KAAKS,KAAKR,GAAG,CAAC,GAAGK;AACnC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
/**
|
|
18
|
+
* Console half (AGL-395): registers the Products nav item in the
|
|
19
|
+
* ConsoleExtension registry so the commerce console surface is owned by the
|
|
20
|
+
* plugin, like events and email. The page body still lives in the console
|
|
21
|
+
* app (`/[hostId]/products`): its product editor depends on the app's media
|
|
22
|
+
* browser, which transitively pulls in the org/session context, so a full
|
|
23
|
+
* body relocation needs a plugin-consumable media-picker context first —
|
|
24
|
+
* tracked as follow-up. The nav item omits a `Component`, so the shell's
|
|
25
|
+
* nav renders the link and the existing named route serves the page.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerCommerceConsole(): void;
|
|
28
|
+
export * from './site';
|
|
@@ -0,0 +1,147 @@
|
|
|
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 Aglyn from "@aglyn/aglyn";
|
|
17
|
+
import { mdiStorefrontOutline } from "@aglyn/shared-data-mdi";
|
|
18
|
+
import { lazy } from "react";
|
|
19
|
+
const PosConsolePage = lazy(()=>import("./components/console/pos-page.component.js"));
|
|
20
|
+
const CommerceGlanceCard = lazy(()=>import("./components/console/commerce-glance-card.component.js"));
|
|
21
|
+
const NewestSiteUsersCard = lazy(()=>import("./components/console/newest-site-users-card.component.js"));
|
|
22
|
+
import { COMMERCE_CONSOLE_SECTIONS } from "./components/commerce-console-sections.js";
|
|
23
|
+
import { BUNDLE_ID } from "./constants/bundle-common.js";
|
|
24
|
+
import { COMMERCE_PERMISSIONS } from "./model/plugin-permissions.js";
|
|
25
|
+
import { COMMERCE_CONFIG_SCHEMA } from "./plugin-config.js";
|
|
26
|
+
/** Code-split: the Products console page only loads when opened. */ const CommerceConsolePage = lazy(()=>import("./components/commerce-console-page.js"));
|
|
27
|
+
/**
|
|
28
|
+
* Console half (AGL-395): registers the Products nav item in the
|
|
29
|
+
* ConsoleExtension registry so the commerce console surface is owned by the
|
|
30
|
+
* plugin, like events and email. The page body still lives in the console
|
|
31
|
+
* app (`/[hostId]/products`): its product editor depends on the app's media
|
|
32
|
+
* browser, which transitively pulls in the org/session context, so a full
|
|
33
|
+
* body relocation needs a plugin-consumable media-picker context first —
|
|
34
|
+
* tracked as follow-up. The nav item omits a `Component`, so the shell's
|
|
35
|
+
* nav renders the link and the existing named route serves the page.
|
|
36
|
+
*/ export function registerCommerceConsole() {
|
|
37
|
+
// Plugin-declared permissions (AGL-435): tier defaults ride every
|
|
38
|
+
// resolved role set; custom roles override key-by-key.
|
|
39
|
+
Aglyn.registerPluginPermissions(COMMERCE_PERMISSIONS);
|
|
40
|
+
// Register discount ceiling (AGL-2161) — the generic settings card renders
|
|
41
|
+
// it from this schema, so there is no bespoke UI to keep in sync.
|
|
42
|
+
Aglyn.registerPluginConfigSchema(COMMERCE_CONFIG_SCHEMA);
|
|
43
|
+
Aglyn.registerConsoleExtension({
|
|
44
|
+
pluginId: BUNDLE_ID,
|
|
45
|
+
displayName: 'Commerce',
|
|
46
|
+
// Dashboard/analytics glance card (AGL-419): rendered through the
|
|
47
|
+
// shell's 'commerceGlance' widget slot.
|
|
48
|
+
widgets: [
|
|
49
|
+
{
|
|
50
|
+
slot: 'commerceGlance',
|
|
51
|
+
widgetId: 'commerce-glance',
|
|
52
|
+
title: 'Commerce',
|
|
53
|
+
Component: CommerceGlanceCard
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
navItems: [
|
|
57
|
+
{
|
|
58
|
+
label: 'Products',
|
|
59
|
+
href: '/products',
|
|
60
|
+
icon: {
|
|
61
|
+
path: mdiStorefrontOutline.path
|
|
62
|
+
},
|
|
63
|
+
// Sections as ROUTES (AGL-2501): `/products/orders` and friends are
|
|
64
|
+
// real URLs the shell resolves and gates, so the page mounts the one
|
|
65
|
+
// being read instead of subscribing all six.
|
|
66
|
+
sections: COMMERCE_CONSOLE_SECTIONS,
|
|
67
|
+
header: {
|
|
68
|
+
title: 'Products',
|
|
69
|
+
icon: {
|
|
70
|
+
path: mdiStorefrontOutline.path
|
|
71
|
+
},
|
|
72
|
+
// The overview, not `catalog`: this surface is the whole commerce
|
|
73
|
+
// console — Catalog, Orders, Promotions and Reservations.
|
|
74
|
+
docsTopic: 'commerce'
|
|
75
|
+
},
|
|
76
|
+
Component: CommerceConsolePage
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
// POS register (AGL-312/419): relocated from the app's /pos route —
|
|
80
|
+
// the generic [pluginSlug] shell now serves it at the same URL.
|
|
81
|
+
label: 'POS',
|
|
82
|
+
href: '/pos',
|
|
83
|
+
/*
|
|
84
|
+
* WHO may open the register, declared on THIS nav item rather than on
|
|
85
|
+
* the extension.
|
|
86
|
+
*
|
|
87
|
+
* A key here narrows one surface; a key on the extension would gate
|
|
88
|
+
* every surface it registers, and Products is the sibling — a catalog
|
|
89
|
+
* anyone who works on the site may open. The register is the one that
|
|
90
|
+
* takes money and lists checked-in guests by name, so the two
|
|
91
|
+
* genuinely have different answers and only this one is narrowed.
|
|
92
|
+
*
|
|
93
|
+
* `managePos` rather than a dotted catalog key because it is the key
|
|
94
|
+
* the sale itself is refused by: `server/pos-order.ts` resolves the
|
|
95
|
+
* member's permission map and returns 403 unless `managePos` holds.
|
|
96
|
+
* The shell answers this declaration out of that same resolved map, so
|
|
97
|
+
* the console offers a register exactly to the people the route will
|
|
98
|
+
* accept a sale from — the gate and its server twin cannot disagree,
|
|
99
|
+
* because they are reading one value.
|
|
100
|
+
*
|
|
101
|
+
* `pos-order.ts` stays the enforcement point regardless. This decides
|
|
102
|
+
* whether the surface is built at all, which is the part a check
|
|
103
|
+
* inside the page cannot do: by the time the page can refuse itself it
|
|
104
|
+
* has mounted and its product, register, location and reservation
|
|
105
|
+
* listeners are already open.
|
|
106
|
+
*/ permission: 'managePos',
|
|
107
|
+
icon: {
|
|
108
|
+
path: mdiStorefrontOutline.path
|
|
109
|
+
},
|
|
110
|
+
header: {
|
|
111
|
+
title: 'Point of Sale',
|
|
112
|
+
docsTopic: 'pos'
|
|
113
|
+
},
|
|
114
|
+
Component: PosConsolePage
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
});
|
|
118
|
+
/*
|
|
119
|
+
* The USER ACCOUNTS half, registered under its own id.
|
|
120
|
+
*
|
|
121
|
+
* `accounts` is a switch rather than a bundle: the member blocks and every
|
|
122
|
+
* `membership/*` handler ship inside this package, which is why the id
|
|
123
|
+
* carries no loader manifest entry of its own. A second extension is how a
|
|
124
|
+
* card about visitor accounts is gated on the switch that decides whether
|
|
125
|
+
* the site serves them — `listConsoleWidgets` filters by the workspace's
|
|
126
|
+
* effective plugin ids, and `accounts` is default-OFF per site.
|
|
127
|
+
*
|
|
128
|
+
* A separate call rather than more widgets on the commerce extension: the
|
|
129
|
+
* registry is keyed by `pluginId` and that key IS the gate, so folding this
|
|
130
|
+
* card in above would have kept the dashboard defect it fixes — `Newest
|
|
131
|
+
* site users` on a site whose /signin returns 404.
|
|
132
|
+
*/ Aglyn.registerConsoleExtension({
|
|
133
|
+
pluginId: Aglyn.ACCOUNTS_PLUGIN_ID,
|
|
134
|
+
displayName: 'User Accounts',
|
|
135
|
+
widgets: [
|
|
136
|
+
{
|
|
137
|
+
slot: Aglyn.CONSOLE_WIDGET_SLOTS.hostDashboard,
|
|
138
|
+
widgetId: 'accounts-newest-site-users',
|
|
139
|
+
title: 'Newest site users',
|
|
140
|
+
Component: NewestSiteUsersCard
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
export * from "./site.js";
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/plugin.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { mdiStorefrontOutline } from '@aglyn/shared-data-mdi'\nimport { lazy } from 'react'\nconst PosConsolePage = lazy(() => import('./components/console/pos-page.component'))\nconst CommerceGlanceCard = lazy(\n () => import('./components/console/commerce-glance-card.component'),\n)\nconst NewestSiteUsersCard = lazy(\n () => import('./components/console/newest-site-users-card.component'),\n)\nimport { COMMERCE_CONSOLE_SECTIONS } from './components/commerce-console-sections'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { COMMERCE_PERMISSIONS } from './model/plugin-permissions'\nimport { COMMERCE_CONFIG_SCHEMA } from './plugin-config'\n\n/** Code-split: the Products console page only loads when opened. */\nconst CommerceConsolePage = lazy(() => import('./components/commerce-console-page'))\n\n/**\n * Console half (AGL-395): registers the Products nav item in the\n * ConsoleExtension registry so the commerce console surface is owned by the\n * plugin, like events and email. The page body still lives in the console\n * app (`/[hostId]/products`): its product editor depends on the app's media\n * browser, which transitively pulls in the org/session context, so a full\n * body relocation needs a plugin-consumable media-picker context first —\n * tracked as follow-up. The nav item omits a `Component`, so the shell's\n * nav renders the link and the existing named route serves the page.\n */\nexport function registerCommerceConsole(): void {\n // Plugin-declared permissions (AGL-435): tier defaults ride every\n // resolved role set; custom roles override key-by-key.\n Aglyn.registerPluginPermissions(COMMERCE_PERMISSIONS)\n // Register discount ceiling (AGL-2161) — the generic settings card renders\n // it from this schema, so there is no bespoke UI to keep in sync.\n Aglyn.registerPluginConfigSchema(COMMERCE_CONFIG_SCHEMA)\n Aglyn.registerConsoleExtension({\n pluginId: BUNDLE_ID,\n displayName: 'Commerce',\n // Dashboard/analytics glance card (AGL-419): rendered through the\n // shell's 'commerceGlance' widget slot.\n widgets: [\n {\n slot: 'commerceGlance',\n widgetId: 'commerce-glance',\n title: 'Commerce',\n Component: CommerceGlanceCard,\n },\n ],\n navItems: [\n {\n label: 'Products',\n href: '/products',\n icon: { path: mdiStorefrontOutline.path },\n // Sections as ROUTES (AGL-2501): `/products/orders` and friends are\n // real URLs the shell resolves and gates, so the page mounts the one\n // being read instead of subscribing all six.\n sections: COMMERCE_CONSOLE_SECTIONS,\n header: {\n title: 'Products',\n icon: { path: mdiStorefrontOutline.path },\n // The overview, not `catalog`: this surface is the whole commerce\n // console — Catalog, Orders, Promotions and Reservations.\n docsTopic: 'commerce',\n },\n Component: CommerceConsolePage,\n },\n {\n // POS register (AGL-312/419): relocated from the app's /pos route —\n // the generic [pluginSlug] shell now serves it at the same URL.\n label: 'POS',\n href: '/pos',\n /*\n * WHO may open the register, declared on THIS nav item rather than on\n * the extension.\n *\n * A key here narrows one surface; a key on the extension would gate\n * every surface it registers, and Products is the sibling — a catalog\n * anyone who works on the site may open. The register is the one that\n * takes money and lists checked-in guests by name, so the two\n * genuinely have different answers and only this one is narrowed.\n *\n * `managePos` rather than a dotted catalog key because it is the key\n * the sale itself is refused by: `server/pos-order.ts` resolves the\n * member's permission map and returns 403 unless `managePos` holds.\n * The shell answers this declaration out of that same resolved map, so\n * the console offers a register exactly to the people the route will\n * accept a sale from — the gate and its server twin cannot disagree,\n * because they are reading one value.\n *\n * `pos-order.ts` stays the enforcement point regardless. This decides\n * whether the surface is built at all, which is the part a check\n * inside the page cannot do: by the time the page can refuse itself it\n * has mounted and its product, register, location and reservation\n * listeners are already open.\n */\n permission: 'managePos',\n icon: { path: mdiStorefrontOutline.path },\n header: { title: 'Point of Sale', docsTopic: 'pos' },\n Component: PosConsolePage,\n },\n ],\n })\n /*\n * The USER ACCOUNTS half, registered under its own id.\n *\n * `accounts` is a switch rather than a bundle: the member blocks and every\n * `membership/*` handler ship inside this package, which is why the id\n * carries no loader manifest entry of its own. A second extension is how a\n * card about visitor accounts is gated on the switch that decides whether\n * the site serves them — `listConsoleWidgets` filters by the workspace's\n * effective plugin ids, and `accounts` is default-OFF per site.\n *\n * A separate call rather than more widgets on the commerce extension: the\n * registry is keyed by `pluginId` and that key IS the gate, so folding this\n * card in above would have kept the dashboard defect it fixes — `Newest\n * site users` on a site whose /signin returns 404.\n */\n Aglyn.registerConsoleExtension({\n pluginId: Aglyn.ACCOUNTS_PLUGIN_ID,\n displayName: 'User Accounts',\n widgets: [\n {\n slot: Aglyn.CONSOLE_WIDGET_SLOTS.hostDashboard,\n widgetId: 'accounts-newest-site-users',\n title: 'Newest site users',\n Component: NewestSiteUsersCard,\n },\n ],\n })\n}\n\nexport * from './site'\n"],"names":["Aglyn","mdiStorefrontOutline","lazy","PosConsolePage","CommerceGlanceCard","NewestSiteUsersCard","COMMERCE_CONSOLE_SECTIONS","BUNDLE_ID","COMMERCE_PERMISSIONS","COMMERCE_CONFIG_SCHEMA","CommerceConsolePage","registerCommerceConsole","registerPluginPermissions","registerPluginConfigSchema","registerConsoleExtension","pluginId","displayName","widgets","slot","widgetId","title","Component","navItems","label","href","icon","path","sections","header","docsTopic","permission","ACCOUNTS_PLUGIN_ID","CONSOLE_WIDGET_SLOTS","hostDashboard"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,YAAYA,WAAW,eAAc;AACrC,SAASC,oBAAoB,QAAQ,yBAAwB;AAC7D,SAASC,IAAI,QAAQ,QAAO;AAC5B,MAAMC,iBAAiBD,KAAK,IAAM,MAAM,CAAC;AACzC,MAAME,qBAAqBF,KACzB,IAAM,MAAM,CAAC;AAEf,MAAMG,sBAAsBH,KAC1B,IAAM,MAAM,CAAC;AAEf,SAASI,yBAAyB,QAAQ,4CAAwC;AAClF,SAASC,SAAS,QAAQ,+BAA2B;AACrD,SAASC,oBAAoB,QAAQ,gCAA4B;AACjE,SAASC,sBAAsB,QAAQ,qBAAiB;AAExD,kEAAkE,GAClE,MAAMC,sBAAsBR,KAAK,IAAM,MAAM,CAAC;AAE9C;;;;;;;;;CASC,GACD,OAAO,SAASS;IACd,kEAAkE;IAClE,uDAAuD;IACvDX,MAAMY,yBAAyB,CAACJ;IAChC,2EAA2E;IAC3E,kEAAkE;IAClER,MAAMa,0BAA0B,CAACJ;IACjCT,MAAMc,wBAAwB,CAAC;QAC7BC,UAAUR;QACVS,aAAa;QACb,kEAAkE;QAClE,wCAAwC;QACxCC,SAAS;YACP;gBACEC,MAAM;gBACNC,UAAU;gBACVC,OAAO;gBACPC,WAAWjB;YACb;SACD;QACDkB,UAAU;YACR;gBACEC,OAAO;gBACPC,MAAM;gBACNC,MAAM;oBAAEC,MAAMzB,qBAAqByB,IAAI;gBAAC;gBACxC,oEAAoE;gBACpE,qEAAqE;gBACrE,6CAA6C;gBAC7CC,UAAUrB;gBACVsB,QAAQ;oBACNR,OAAO;oBACPK,MAAM;wBAAEC,MAAMzB,qBAAqByB,IAAI;oBAAC;oBACxC,kEAAkE;oBAClE,0DAA0D;oBAC1DG,WAAW;gBACb;gBACAR,WAAWX;YACb;YACA;gBACE,oEAAoE;gBACpE,gEAAgE;gBAChEa,OAAO;gBACPC,MAAM;gBACN;;;;;;;;;;;;;;;;;;;;;;;SAuBC,GACDM,YAAY;gBACZL,MAAM;oBAAEC,MAAMzB,qBAAqByB,IAAI;gBAAC;gBACxCE,QAAQ;oBAAER,OAAO;oBAAiBS,WAAW;gBAAM;gBACnDR,WAAWlB;YACb;SACD;IACH;IACA;;;;;;;;;;;;;;GAcC,GACDH,MAAMc,wBAAwB,CAAC;QAC7BC,UAAUf,MAAM+B,kBAAkB;QAClCf,aAAa;QACbC,SAAS;YACP;gBACEC,MAAMlB,MAAMgC,oBAAoB,CAACC,aAAa;gBAC9Cd,UAAU;gBACVC,OAAO;gBACPC,WAAWhB;YACb;SACD;IACH;AACF;AAEA,cAAc,YAAQ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 { BillingWebhookHandler } from '@aglyn/aglyn/server';
|
|
18
|
+
/**
|
|
19
|
+
* Commerce sections of the platform Stripe webhook (AGL-418): relocated
|
|
20
|
+
* verbatim from the console route — subscriptions sync, reservations,
|
|
21
|
+
* cart orders, draft orders, Commerce Starter orders, plus the license-key
|
|
22
|
+
* assignment helper (AGL-308). Registered via registerCommerceConsoleApi;
|
|
23
|
+
* every section is idempotent by doc key and self-selects on
|
|
24
|
+
* `object.metadata.type`, exactly as the inline route sections did.
|
|
25
|
+
*/
|
|
26
|
+
export declare const commerceBillingWebhookHandler: BillingWebhookHandler;
|