@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,127 @@
|
|
|
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 { PluginApiHandler } from '@aglyn/aglyn/server';
|
|
18
|
+
import * as CommerceModel from '../model';
|
|
19
|
+
export interface PublicCatalogItem {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
slug: string;
|
|
23
|
+
type: CommerceModel.ProductType;
|
|
24
|
+
priceUsd: number;
|
|
25
|
+
maxPriceUsd: number;
|
|
26
|
+
compareAtPriceUsd?: number;
|
|
27
|
+
imageUrl?: string;
|
|
28
|
+
soldOut: boolean;
|
|
29
|
+
tags?: string[];
|
|
30
|
+
}
|
|
31
|
+
/** Host category surfaced to grids for filter chips (AGL-561). */
|
|
32
|
+
export interface PublicCatalogCategory {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
slug: string;
|
|
36
|
+
}
|
|
37
|
+
/** Price facet surfaced to grids to bound a range slider (AGL-564). */
|
|
38
|
+
export interface PublicCatalogPriceBounds {
|
|
39
|
+
minCents: number;
|
|
40
|
+
maxCents: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Displayed price in cents (AGL-564): the low end of the variant range —
|
|
44
|
+
* the number grid cards render (`$X` / `From $X`) — so price filtering
|
|
45
|
+
* matches what visitors see.
|
|
46
|
+
*/
|
|
47
|
+
export declare function displayedPriceCents(product: Pick<CommerceModel.HostProduct, 'variants'>): number;
|
|
48
|
+
/**
|
|
49
|
+
* Case-insensitive catalog search (AGL-561): matches the product name,
|
|
50
|
+
* description, or any tag. An empty/blank query matches everything.
|
|
51
|
+
*/
|
|
52
|
+
export declare function matchesCatalogQuery(product: Pick<CommerceModel.HostProduct, 'name' | 'description' | 'tags'>, query: string): boolean;
|
|
53
|
+
/** A catalog query, already parsed and bounded. */
|
|
54
|
+
export interface PublicCatalogQuery {
|
|
55
|
+
hostId: string;
|
|
56
|
+
collectionId?: string;
|
|
57
|
+
collectionSlug?: string;
|
|
58
|
+
categoryId?: string;
|
|
59
|
+
categorySlug?: string;
|
|
60
|
+
tag?: string;
|
|
61
|
+
/** Free-text search over name, description and tags. */
|
|
62
|
+
query?: string;
|
|
63
|
+
type?: CommerceModel.ProductType | '';
|
|
64
|
+
/** Explicit id list in the given order (wishlist rendering, AGL-297). */
|
|
65
|
+
ids?: string[];
|
|
66
|
+
minPriceCents?: number;
|
|
67
|
+
maxPriceCents?: number;
|
|
68
|
+
sort?: string;
|
|
69
|
+
/** Page size, 1–100. */
|
|
70
|
+
limit?: number;
|
|
71
|
+
offset?: number;
|
|
72
|
+
/** Include category + price facets in the result. */
|
|
73
|
+
facets?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Optional per-render dedupe (see {@link CatalogReadScope}). Absent for a
|
|
76
|
+
* one-off call such as the API route, where there is nothing to share with.
|
|
77
|
+
*/
|
|
78
|
+
reads?: CatalogReadScope;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Reads shared by every catalog query in ONE render, for ONE host.
|
|
82
|
+
*
|
|
83
|
+
* The products read does not vary with the query — the whole catalog is
|
|
84
|
+
* fetched and then filtered in memory by collection, category, tag, price and
|
|
85
|
+
* search text. A page carrying four product grids therefore issued four
|
|
86
|
+
* identical 500-document reads and threw three of them away.
|
|
87
|
+
*
|
|
88
|
+
* This shares the READ, never the RESULT. Each grid still filters and sorts
|
|
89
|
+
* the shared snapshot independently, because a collection-scoped grid and an
|
|
90
|
+
* all-products grid on the same page must not receive each other's items.
|
|
91
|
+
*
|
|
92
|
+
* Scoped to one host and one render deliberately: it holds a promise, not
|
|
93
|
+
* data, so nothing is cached across requests and no staleness window opens.
|
|
94
|
+
* Reusing a scope for a second host would serve that host the first one's
|
|
95
|
+
* catalog, which is why it is created per render rather than per module.
|
|
96
|
+
*/
|
|
97
|
+
export interface CatalogReadScope {
|
|
98
|
+
products?: Promise<FirebaseFirestore.QuerySnapshot>;
|
|
99
|
+
categories?: Promise<FirebaseFirestore.QuerySnapshot>;
|
|
100
|
+
}
|
|
101
|
+
/** A fresh read scope. One per render, never reused across hosts. */
|
|
102
|
+
export declare function createCatalogReadScope(): CatalogReadScope;
|
|
103
|
+
/** What both the API route and the SSR seed hand to a product grid. */
|
|
104
|
+
export interface PublicCatalogResult {
|
|
105
|
+
items: PublicCatalogItem[];
|
|
106
|
+
nextOffset?: number;
|
|
107
|
+
categories?: PublicCatalogCategory[];
|
|
108
|
+
priceBounds?: PublicCatalogPriceBounds;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Public catalog listing (AGL-291): active products for storefront
|
|
112
|
+
* blocks — filterable by collection/category slug or tag, sortable,
|
|
113
|
+
* capped at 100 items per request. Storefront catalog UX (AGL-561)
|
|
114
|
+
* adds text search, a product-type filter, offset paging (for Load
|
|
115
|
+
* more), and facets for filter chips. The price-range filter (AGL-564)
|
|
116
|
+
* bounds on the displayed price and reports `priceBounds`.
|
|
117
|
+
* Read-only public data; prices here are display-only (charges always
|
|
118
|
+
* come from the docs server-side).
|
|
119
|
+
*
|
|
120
|
+
* Extracted from the handler (AGL-659) so the site-page enricher seeds a
|
|
121
|
+
* grid's first page through THIS function rather than a reimplementation
|
|
122
|
+
* of it. A seed that filters or sorts differently from the API would
|
|
123
|
+
* server-render one set of products and hydrate to another.
|
|
124
|
+
*/
|
|
125
|
+
export declare function queryPublicCatalog(params: PublicCatalogQuery): Promise<PublicCatalogResult>;
|
|
126
|
+
/** Public catalog listing endpoint — a thin parse over queryPublicCatalog. */
|
|
127
|
+
export declare const catalogHandler: PluginApiHandler;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
import * as Aglyn from "@aglyn/aglyn/server";
|
|
18
|
+
import * as CommerceModel from "../model/index.js";
|
|
19
|
+
import { firebaseAdmin } from "@aglyn/tenant-data-admin";
|
|
20
|
+
/**
|
|
21
|
+
* Displayed price in cents (AGL-564): the low end of the variant range —
|
|
22
|
+
* the number grid cards render (`$X` / `From $X`) — so price filtering
|
|
23
|
+
* matches what visitors see.
|
|
24
|
+
*/ export function displayedPriceCents(product) {
|
|
25
|
+
return Math.round(CommerceModel.productPriceRange(product)[0] * 100);
|
|
26
|
+
}
|
|
27
|
+
/** Non-negative integer cents from a query param; undefined otherwise. */ function parsePriceCents(value) {
|
|
28
|
+
const raw = String(value != null ? value : '').trim();
|
|
29
|
+
if (!raw) return undefined;
|
|
30
|
+
const cents = Number(raw);
|
|
31
|
+
if (!Number.isFinite(cents) || cents < 0) return undefined;
|
|
32
|
+
return Math.round(cents);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Case-insensitive catalog search (AGL-561): matches the product name,
|
|
36
|
+
* description, or any tag. An empty/blank query matches everything.
|
|
37
|
+
*/ export function matchesCatalogQuery(product, query) {
|
|
38
|
+
var _product_description, _product_tags;
|
|
39
|
+
const needle = query.trim().toLowerCase();
|
|
40
|
+
if (!needle) return true;
|
|
41
|
+
return product.name.toLowerCase().includes(needle) || ((_product_description = product.description) != null ? _product_description : '').toLowerCase().includes(needle) || ((_product_tags = product.tags) != null ? _product_tags : []).some((tag)=>tag.toLowerCase().includes(needle));
|
|
42
|
+
}
|
|
43
|
+
/** A fresh read scope. One per render, never reused across hosts. */ export function createCatalogReadScope() {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Public catalog listing (AGL-291): active products for storefront
|
|
48
|
+
* blocks — filterable by collection/category slug or tag, sortable,
|
|
49
|
+
* capped at 100 items per request. Storefront catalog UX (AGL-561)
|
|
50
|
+
* adds text search, a product-type filter, offset paging (for Load
|
|
51
|
+
* more), and facets for filter chips. The price-range filter (AGL-564)
|
|
52
|
+
* bounds on the displayed price and reports `priceBounds`.
|
|
53
|
+
* Read-only public data; prices here are display-only (charges always
|
|
54
|
+
* come from the docs server-side).
|
|
55
|
+
*
|
|
56
|
+
* Extracted from the handler (AGL-659) so the site-page enricher seeds a
|
|
57
|
+
* grid's first page through THIS function rather than a reimplementation
|
|
58
|
+
* of it. A seed that filters or sorts differently from the API would
|
|
59
|
+
* server-render one set of products and hydrate to another.
|
|
60
|
+
*/ export async function queryPublicCatalog(params) {
|
|
61
|
+
var _params_collectionSlug, _params_categorySlug, _params_collectionId, _params_categoryId, _params_tag, _params_query, _params_type, _params_ids, _params_limit, _params_offset;
|
|
62
|
+
var _categoriesSnapshot_docs_;
|
|
63
|
+
const { hostId } = params;
|
|
64
|
+
const collectionSlug = (_params_collectionSlug = params.collectionSlug) != null ? _params_collectionSlug : '';
|
|
65
|
+
const categorySlug = (_params_categorySlug = params.categorySlug) != null ? _params_categorySlug : '';
|
|
66
|
+
// Id-based filters are preferred (rename-safe, AGL-343); slugs remain
|
|
67
|
+
// for legacy screens and template-URL resolution.
|
|
68
|
+
const collectionIdParam = (_params_collectionId = params.collectionId) != null ? _params_collectionId : '';
|
|
69
|
+
const categoryIdParam = (_params_categoryId = params.categoryId) != null ? _params_categoryId : '';
|
|
70
|
+
const tag = (_params_tag = params.tag) != null ? _params_tag : '';
|
|
71
|
+
const query = (_params_query = params.query) != null ? _params_query : '';
|
|
72
|
+
const type = [
|
|
73
|
+
'physical',
|
|
74
|
+
'digital',
|
|
75
|
+
'service'
|
|
76
|
+
].includes((_params_type = params.type) != null ? _params_type : '') ? params.type : '';
|
|
77
|
+
const ids = ((_params_ids = params.ids) != null ? _params_ids : []).slice(0, 100);
|
|
78
|
+
const minPriceCents = params.minPriceCents;
|
|
79
|
+
const maxPriceCents = params.maxPriceCents;
|
|
80
|
+
const sort = params.sort || 'name';
|
|
81
|
+
const max = Math.min(100, Math.max(1, Number((_params_limit = params.limit) != null ? _params_limit : 24)));
|
|
82
|
+
const offset = Math.max(0, Math.round(Number((_params_offset = params.offset) != null ? _params_offset : 0)) || 0);
|
|
83
|
+
const wantFacets = Boolean(params.facets);
|
|
84
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
85
|
+
const hostRef = firestore.collection('hosts').doc(hostId);
|
|
86
|
+
const reads = params.reads;
|
|
87
|
+
// Assigned into the scope BEFORE it is awaited, so grids running together
|
|
88
|
+
// under one `Promise.all` share the single in-flight read rather than each
|
|
89
|
+
// starting their own and racing to store it.
|
|
90
|
+
const sharedProducts = ()=>{
|
|
91
|
+
var _reads, _products;
|
|
92
|
+
return reads ? (_products = (_reads = reads).products) != null ? _products : _reads.products = hostRef.collection('products').limit(500).get() : hostRef.collection('products').limit(500).get();
|
|
93
|
+
};
|
|
94
|
+
const sharedCategories = ()=>{
|
|
95
|
+
var _reads, _categories;
|
|
96
|
+
return reads ? (_categories = (_reads = reads).categories) != null ? _categories : _reads.categories = hostRef.collection('productCategories').limit(200).get() : hostRef.collection('productCategories').limit(200).get();
|
|
97
|
+
};
|
|
98
|
+
const [productsSnapshot, collectionsSnapshot, categoriesSnapshot, collectionByIdSnapshot, facetsSnapshot] = await Promise.all([
|
|
99
|
+
sharedProducts(),
|
|
100
|
+
// limit(5) not 1: content collections share this path and a slug is
|
|
101
|
+
// unique only within a kind (AGL-954) — the catalog match is picked
|
|
102
|
+
// out below rather than trusting whichever doc came back first.
|
|
103
|
+
!collectionIdParam && collectionSlug ? hostRef.collection('collections').where('slug', '==', collectionSlug).limit(5).get() : null,
|
|
104
|
+
!categoryIdParam && categorySlug ? hostRef.collection('productCategories').where('slug', '==', categorySlug).limit(1).get() : null,
|
|
105
|
+
collectionIdParam ? hostRef.collection('collections').doc(collectionIdParam).get() : null,
|
|
106
|
+
wantFacets ? sharedCategories() : null
|
|
107
|
+
]);
|
|
108
|
+
const collectionById = (collectionByIdSnapshot == null ? void 0 : collectionByIdSnapshot.exists) && Aglyn.hostCollectionKind(collectionByIdSnapshot.data()) === 'catalog' ? collectionByIdSnapshot : undefined;
|
|
109
|
+
const collection = collectionById != null ? collectionById : collectionsSnapshot == null ? void 0 : collectionsSnapshot.docs.find((docSnapshot)=>Aglyn.hostCollectionKind(docSnapshot.data()) === 'catalog');
|
|
110
|
+
const categoryId = categoryIdParam || (categoriesSnapshot == null ? void 0 : (_categoriesSnapshot_docs_ = categoriesSnapshot.docs[0]) == null ? void 0 : _categoriesSnapshot_docs_.id);
|
|
111
|
+
let products = productsSnapshot.docs.map((docSnapshot)=>_extends({}, CommerceModel.liftLegacyProduct(docSnapshot.data()), {
|
|
112
|
+
$id: docSnapshot.id
|
|
113
|
+
})).filter((product)=>!product.deletedAt && product.status === 'active');
|
|
114
|
+
if (collection) {
|
|
115
|
+
const shaped = collection.data();
|
|
116
|
+
products = products.filter((product)=>CommerceModel.matchesCollection(product, shaped, product.$id));
|
|
117
|
+
if (shaped.mode === 'manual') {
|
|
118
|
+
var _shaped_productIds;
|
|
119
|
+
const order = new Map(((_shaped_productIds = shaped.productIds) != null ? _shaped_productIds : []).map((id, index)=>[
|
|
120
|
+
id,
|
|
121
|
+
index
|
|
122
|
+
]));
|
|
123
|
+
products.sort((a, b)=>{
|
|
124
|
+
var _order_get, _order_get1;
|
|
125
|
+
return ((_order_get = order.get(a.$id)) != null ? _order_get : 999) - ((_order_get1 = order.get(b.$id)) != null ? _order_get1 : 999);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (categoryId) {
|
|
130
|
+
products = products.filter((product)=>{
|
|
131
|
+
var _product_categoryIds;
|
|
132
|
+
return ((_product_categoryIds = product.categoryIds) != null ? _product_categoryIds : []).includes(categoryId);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (tag) {
|
|
136
|
+
products = products.filter((product)=>{
|
|
137
|
+
var _product_tags;
|
|
138
|
+
return ((_product_tags = product.tags) != null ? _product_tags : []).includes(tag);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// Storefront catalog UX (AGL-561): type filter + text search.
|
|
142
|
+
if (type) {
|
|
143
|
+
products = products.filter((product)=>product.type === type);
|
|
144
|
+
}
|
|
145
|
+
if (query.trim()) {
|
|
146
|
+
products = products.filter((product)=>matchesCatalogQuery(product, query));
|
|
147
|
+
}
|
|
148
|
+
// Wishlist rendering (AGL-297): explicit id list, given order.
|
|
149
|
+
if (ids.length) {
|
|
150
|
+
const order = new Map(ids.map((id, index)=>[
|
|
151
|
+
id,
|
|
152
|
+
index
|
|
153
|
+
]));
|
|
154
|
+
products = products.filter((product)=>order.has(product.$id)).sort((a, b)=>{
|
|
155
|
+
var _order_get, _order_get1;
|
|
156
|
+
return ((_order_get = order.get(a.$id)) != null ? _order_get : 0) - ((_order_get1 = order.get(b.$id)) != null ? _order_get1 : 0);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Price facets + filter (AGL-564): bounds are computed before the
|
|
160
|
+
// price filter (with everything else applied) so the grid's slider
|
|
161
|
+
// stays anchored while the visitor narrows it. Both use the
|
|
162
|
+
// displayed price — the low end of the variant range grid cards
|
|
163
|
+
// show — so filtering matches what visitors see.
|
|
164
|
+
const priceBounds = wantFacets && products.length ? {
|
|
165
|
+
minCents: Math.min(...products.map(displayedPriceCents)),
|
|
166
|
+
maxCents: Math.max(...products.map(displayedPriceCents))
|
|
167
|
+
} : undefined;
|
|
168
|
+
if (minPriceCents != null || maxPriceCents != null) {
|
|
169
|
+
products = products.filter((product)=>{
|
|
170
|
+
const cents = displayedPriceCents(product);
|
|
171
|
+
return (minPriceCents == null || cents >= minPriceCents) && (maxPriceCents == null || cents <= maxPriceCents);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (sort === 'price-asc' || sort === 'price-desc') {
|
|
175
|
+
products.sort((a, b)=>{
|
|
176
|
+
const [minA] = CommerceModel.productPriceRange(a);
|
|
177
|
+
const [minB] = CommerceModel.productPriceRange(b);
|
|
178
|
+
return sort === 'price-asc' ? minA - minB : minB - minA;
|
|
179
|
+
});
|
|
180
|
+
} else if (sort === 'newest') {
|
|
181
|
+
products.sort((a, b)=>{
|
|
182
|
+
var _b_createdAtMs, _a_createdAtMs;
|
|
183
|
+
return ((_b_createdAtMs = b.createdAtMs) != null ? _b_createdAtMs : 0) - ((_a_createdAtMs = a.createdAtMs) != null ? _a_createdAtMs : 0);
|
|
184
|
+
});
|
|
185
|
+
} else if (!ids.length && (!collection || collection.data().mode !== 'manual')) {
|
|
186
|
+
products.sort((a, b)=>a.name.localeCompare(b.name));
|
|
187
|
+
}
|
|
188
|
+
// Offset paging (AGL-561): grids pass `offset` for Load more;
|
|
189
|
+
// `nextOffset` comes back only while more filtered items remain.
|
|
190
|
+
const page = products.slice(offset, offset + max);
|
|
191
|
+
const nextOffset = offset + max < products.length ? offset + max : undefined;
|
|
192
|
+
const items = page.map((product)=>{
|
|
193
|
+
var _ref;
|
|
194
|
+
var _product_mediaUrls, _product_mediaUrls1, _product_tags;
|
|
195
|
+
const [minPrice, maxPrice] = CommerceModel.productPriceRange(product);
|
|
196
|
+
const primary = product.variants[0];
|
|
197
|
+
const inventory = CommerceModel.productInventory(product);
|
|
198
|
+
return _extends({
|
|
199
|
+
id: product.$id,
|
|
200
|
+
name: product.name,
|
|
201
|
+
slug: product.slug,
|
|
202
|
+
type: product.type,
|
|
203
|
+
priceUsd: minPrice,
|
|
204
|
+
maxPriceUsd: maxPrice
|
|
205
|
+
}, (primary == null ? void 0 : primary.compareAtPriceUsd) ? {
|
|
206
|
+
compareAtPriceUsd: primary.compareAtPriceUsd
|
|
207
|
+
} : {}, ((_product_mediaUrls = product.mediaUrls) == null ? void 0 : _product_mediaUrls[0]) || product.imageUrl ? {
|
|
208
|
+
imageUrl: (_ref = (_product_mediaUrls1 = product.mediaUrls) == null ? void 0 : _product_mediaUrls1[0]) != null ? _ref : product.imageUrl
|
|
209
|
+
} : {}, {
|
|
210
|
+
soldOut: inventory != null && inventory <= 0 && product.oversellPolicy !== 'backorder'
|
|
211
|
+
}, ((_product_tags = product.tags) == null ? void 0 : _product_tags.length) ? {
|
|
212
|
+
tags: product.tags
|
|
213
|
+
} : {});
|
|
214
|
+
});
|
|
215
|
+
// Category facets (AGL-561): id/name/slug for grid filter chips,
|
|
216
|
+
// parent-tree order preserved (order, then name).
|
|
217
|
+
const categories = facetsSnapshot ? facetsSnapshot.docs.map((docSnapshot)=>{
|
|
218
|
+
var _data_name, _data_slug, _data_order;
|
|
219
|
+
const data = docSnapshot.data();
|
|
220
|
+
return {
|
|
221
|
+
id: docSnapshot.id,
|
|
222
|
+
name: String((_data_name = data.name) != null ? _data_name : ''),
|
|
223
|
+
slug: String((_data_slug = data.slug) != null ? _data_slug : ''),
|
|
224
|
+
order: Number((_data_order = data.order) != null ? _data_order : 0)
|
|
225
|
+
};
|
|
226
|
+
}).sort((a, b)=>a.order - b.order || a.name.localeCompare(b.name)).map(({ id, name, slug })=>({
|
|
227
|
+
id,
|
|
228
|
+
name,
|
|
229
|
+
slug
|
|
230
|
+
})) : undefined;
|
|
231
|
+
return _extends({
|
|
232
|
+
items
|
|
233
|
+
}, nextOffset != null ? {
|
|
234
|
+
nextOffset
|
|
235
|
+
} : {}, categories ? {
|
|
236
|
+
categories
|
|
237
|
+
} : {}, priceBounds ? {
|
|
238
|
+
priceBounds
|
|
239
|
+
} : {});
|
|
240
|
+
}
|
|
241
|
+
/** Public catalog listing endpoint — a thin parse over queryPublicCatalog. */ export const catalogHandler = async (req, res)=>{
|
|
242
|
+
var _req_query_hostId;
|
|
243
|
+
const hostId = String((_req_query_hostId = req.query.hostId) != null ? _req_query_hostId : '');
|
|
244
|
+
if (!hostId) return res.status(400).json({
|
|
245
|
+
error: 'Missing hostId'
|
|
246
|
+
});
|
|
247
|
+
try {
|
|
248
|
+
var _req_query_collection, _req_query_category, _req_query_collectionId, _req_query_categoryId, _req_query_tag, _req_query_q, _req_query_type, _req_query_ids, _req_query_sort, _req_query_limit, _req_query_offset, _req_query_facets;
|
|
249
|
+
const result = await queryPublicCatalog({
|
|
250
|
+
hostId,
|
|
251
|
+
collectionSlug: String((_req_query_collection = req.query.collection) != null ? _req_query_collection : ''),
|
|
252
|
+
categorySlug: String((_req_query_category = req.query.category) != null ? _req_query_category : ''),
|
|
253
|
+
collectionId: String((_req_query_collectionId = req.query.collectionId) != null ? _req_query_collectionId : ''),
|
|
254
|
+
categoryId: String((_req_query_categoryId = req.query.categoryId) != null ? _req_query_categoryId : ''),
|
|
255
|
+
tag: String((_req_query_tag = req.query.tag) != null ? _req_query_tag : ''),
|
|
256
|
+
query: String((_req_query_q = req.query.q) != null ? _req_query_q : ''),
|
|
257
|
+
type: String((_req_query_type = req.query.type) != null ? _req_query_type : ''),
|
|
258
|
+
ids: String((_req_query_ids = req.query.ids) != null ? _req_query_ids : '').split(',').map((id)=>id.trim()).filter(Boolean),
|
|
259
|
+
// Price-range filter (AGL-564): integer cents on the displayed price.
|
|
260
|
+
minPriceCents: parsePriceCents(req.query.minPriceCents),
|
|
261
|
+
maxPriceCents: parsePriceCents(req.query.maxPriceCents),
|
|
262
|
+
sort: String((_req_query_sort = req.query.sort) != null ? _req_query_sort : 'name'),
|
|
263
|
+
limit: Number((_req_query_limit = req.query.limit) != null ? _req_query_limit : 24),
|
|
264
|
+
offset: Number((_req_query_offset = req.query.offset) != null ? _req_query_offset : 0),
|
|
265
|
+
facets: String((_req_query_facets = req.query.facets) != null ? _req_query_facets : '') === '1'
|
|
266
|
+
});
|
|
267
|
+
res.setHeader('Cache-Control', 'public, s-maxage=60, stale-while-revalidate=300');
|
|
268
|
+
return res.status(200).json(result);
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error(error);
|
|
271
|
+
return res.status(500).json({
|
|
272
|
+
error: 'Catalog unavailable'
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/catalog.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'\n\nexport interface PublicCatalogItem {\n id: string\n name: string\n slug: string\n type: CommerceModel.ProductType\n priceUsd: number\n maxPriceUsd: number\n compareAtPriceUsd?: number\n imageUrl?: string\n soldOut: boolean\n tags?: string[]\n}\n\n/** Host category surfaced to grids for filter chips (AGL-561). */\nexport interface PublicCatalogCategory {\n id: string\n name: string\n slug: string\n}\n\n/** Price facet surfaced to grids to bound a range slider (AGL-564). */\nexport interface PublicCatalogPriceBounds {\n minCents: number\n maxCents: number\n}\n\n/**\n * Displayed price in cents (AGL-564): the low end of the variant range —\n * the number grid cards render (`$X` / `From $X`) — so price filtering\n * matches what visitors see.\n */\nexport function displayedPriceCents(\n product: Pick<CommerceModel.HostProduct, 'variants'>,\n): number {\n return Math.round(CommerceModel.productPriceRange(product)[0] * 100)\n}\n\n/** Non-negative integer cents from a query param; undefined otherwise. */\nfunction parsePriceCents(value: unknown): number | undefined {\n const raw = String(value ?? '').trim()\n if (!raw) return undefined\n const cents = Number(raw)\n if (!Number.isFinite(cents) || cents < 0) return undefined\n return Math.round(cents)\n}\n\n/**\n * Case-insensitive catalog search (AGL-561): matches the product name,\n * description, or any tag. An empty/blank query matches everything.\n */\nexport function matchesCatalogQuery(\n product: Pick<CommerceModel.HostProduct, 'name' | 'description' | 'tags'>,\n query: string,\n): boolean {\n const needle = query.trim().toLowerCase()\n if (!needle) return true\n return (\n product.name.toLowerCase().includes(needle) ||\n (product.description ?? '').toLowerCase().includes(needle) ||\n (product.tags ?? []).some((tag) => tag.toLowerCase().includes(needle))\n )\n}\n\n/** A catalog query, already parsed and bounded. */\nexport interface PublicCatalogQuery {\n hostId: string\n collectionId?: string\n collectionSlug?: string\n categoryId?: string\n categorySlug?: string\n tag?: string\n /** Free-text search over name, description and tags. */\n query?: string\n type?: CommerceModel.ProductType | ''\n /** Explicit id list in the given order (wishlist rendering, AGL-297). */\n ids?: string[]\n minPriceCents?: number\n maxPriceCents?: number\n sort?: string\n /** Page size, 1–100. */\n limit?: number\n offset?: number\n /** Include category + price facets in the result. */\n facets?: boolean\n /**\n * Optional per-render dedupe (see {@link CatalogReadScope}). Absent for a\n * one-off call such as the API route, where there is nothing to share with.\n */\n reads?: CatalogReadScope\n}\n\n/**\n * Reads shared by every catalog query in ONE render, for ONE host.\n *\n * The products read does not vary with the query — the whole catalog is\n * fetched and then filtered in memory by collection, category, tag, price and\n * search text. A page carrying four product grids therefore issued four\n * identical 500-document reads and threw three of them away.\n *\n * This shares the READ, never the RESULT. Each grid still filters and sorts\n * the shared snapshot independently, because a collection-scoped grid and an\n * all-products grid on the same page must not receive each other's items.\n *\n * Scoped to one host and one render deliberately: it holds a promise, not\n * data, so nothing is cached across requests and no staleness window opens.\n * Reusing a scope for a second host would serve that host the first one's\n * catalog, which is why it is created per render rather than per module.\n */\nexport interface CatalogReadScope {\n products?: Promise<FirebaseFirestore.QuerySnapshot>\n categories?: Promise<FirebaseFirestore.QuerySnapshot>\n}\n\n/** A fresh read scope. One per render, never reused across hosts. */\nexport function createCatalogReadScope(): CatalogReadScope {\n return {}\n}\n\n/** What both the API route and the SSR seed hand to a product grid. */\nexport interface PublicCatalogResult {\n items: PublicCatalogItem[]\n nextOffset?: number\n categories?: PublicCatalogCategory[]\n priceBounds?: PublicCatalogPriceBounds\n}\n\n/**\n * Public catalog listing (AGL-291): active products for storefront\n * blocks — filterable by collection/category slug or tag, sortable,\n * capped at 100 items per request. Storefront catalog UX (AGL-561)\n * adds text search, a product-type filter, offset paging (for Load\n * more), and facets for filter chips. The price-range filter (AGL-564)\n * bounds on the displayed price and reports `priceBounds`.\n * Read-only public data; prices here are display-only (charges always\n * come from the docs server-side).\n *\n * Extracted from the handler (AGL-659) so the site-page enricher seeds a\n * grid's first page through THIS function rather than a reimplementation\n * of it. A seed that filters or sorts differently from the API would\n * server-render one set of products and hydrate to another.\n */\nexport async function queryPublicCatalog(\n params: PublicCatalogQuery,\n): Promise<PublicCatalogResult> {\n const { hostId } = params\n const collectionSlug = params.collectionSlug ?? ''\n const categorySlug = params.categorySlug ?? ''\n // Id-based filters are preferred (rename-safe, AGL-343); slugs remain\n // for legacy screens and template-URL resolution.\n const collectionIdParam = params.collectionId ?? ''\n const categoryIdParam = params.categoryId ?? ''\n const tag = params.tag ?? ''\n const query = params.query ?? ''\n const type = ['physical', 'digital', 'service'].includes(params.type ?? '')\n ? (params.type as CommerceModel.ProductType)\n : ''\n const ids = (params.ids ?? []).slice(0, 100)\n const minPriceCents = params.minPriceCents\n const maxPriceCents = params.maxPriceCents\n const sort = params.sort || 'name'\n const max = Math.min(100, Math.max(1, Number(params.limit ?? 24)))\n const offset = Math.max(0, Math.round(Number(params.offset ?? 0)) || 0)\n const wantFacets = Boolean(params.facets)\n\n const firestore = firebaseAdmin.app().firestore()\n const hostRef = firestore.collection('hosts').doc(hostId)\n const reads = params.reads\n // Assigned into the scope BEFORE it is awaited, so grids running together\n // under one `Promise.all` share the single in-flight read rather than each\n // starting their own and racing to store it.\n const sharedProducts = () =>\n (reads\n ? (reads.products ??= hostRef.collection('products').limit(500).get())\n : hostRef.collection('products').limit(500).get())\n const sharedCategories = () =>\n (reads\n ? (reads.categories ??=\n hostRef.collection('productCategories').limit(200).get())\n : hostRef.collection('productCategories').limit(200).get())\n const [\n productsSnapshot,\n collectionsSnapshot,\n categoriesSnapshot,\n collectionByIdSnapshot,\n facetsSnapshot,\n ] =\n await Promise.all([\n sharedProducts(),\n // limit(5) not 1: content collections share this path and a slug is\n // unique only within a kind (AGL-954) — the catalog match is picked\n // out below rather than trusting whichever doc came back first.\n !collectionIdParam && collectionSlug\n ? hostRef\n .collection('collections')\n .where('slug', '==', collectionSlug)\n .limit(5)\n .get()\n : null,\n !categoryIdParam && categorySlug\n ? hostRef\n .collection('productCategories')\n .where('slug', '==', categorySlug)\n .limit(1)\n .get()\n : null,\n collectionIdParam\n ? hostRef.collection('collections').doc(collectionIdParam).get()\n : null,\n wantFacets ? sharedCategories() : null,\n ])\n const collectionById =\n collectionByIdSnapshot?.exists &&\n Aglyn.hostCollectionKind(collectionByIdSnapshot.data()) === 'catalog'\n ? collectionByIdSnapshot\n : undefined\n const collection =\n collectionById ??\n collectionsSnapshot?.docs.find(\n (docSnapshot) => Aglyn.hostCollectionKind(docSnapshot.data()) === 'catalog',\n )\n const categoryId = categoryIdParam || categoriesSnapshot?.docs[0]?.id\n\n let products = productsSnapshot.docs\n .map((docSnapshot) => ({\n ...CommerceModel.liftLegacyProduct(docSnapshot.data() as any),\n $id: docSnapshot.id,\n }))\n .filter((product) => !product.deletedAt && product.status === 'active')\n if (collection) {\n const shaped = collection.data() as CommerceModel.HostCollection\n products = products.filter((product) =>\n CommerceModel.matchesCollection(product, shaped, product.$id),\n )\n if (shaped.mode === 'manual') {\n const order = new Map(\n (shaped.productIds ?? []).map((id, index) => [id, index]),\n )\n products.sort(\n (a, b) => (order.get(a.$id) ?? 999) - (order.get(b.$id) ?? 999),\n )\n }\n }\n if (categoryId) {\n products = products.filter((product) =>\n (product.categoryIds ?? []).includes(categoryId),\n )\n }\n if (tag) {\n products = products.filter((product) =>\n (product.tags ?? []).includes(tag),\n )\n }\n // Storefront catalog UX (AGL-561): type filter + text search.\n if (type) {\n products = products.filter((product) => product.type === type)\n }\n if (query.trim()) {\n products = products.filter((product) =>\n matchesCatalogQuery(product, query),\n )\n }\n // Wishlist rendering (AGL-297): explicit id list, given order.\n if (ids.length) {\n const order = new Map(ids.map((id, index) => [id, index]))\n products = products\n .filter((product) => order.has(product.$id))\n .sort((a, b) => (order.get(a.$id) ?? 0) - (order.get(b.$id) ?? 0))\n }\n // Price facets + filter (AGL-564): bounds are computed before the\n // price filter (with everything else applied) so the grid's slider\n // stays anchored while the visitor narrows it. Both use the\n // displayed price — the low end of the variant range grid cards\n // show — so filtering matches what visitors see.\n const priceBounds: PublicCatalogPriceBounds | undefined =\n wantFacets && products.length\n ? {\n minCents: Math.min(...products.map(displayedPriceCents)),\n maxCents: Math.max(...products.map(displayedPriceCents)),\n }\n : undefined\n if (minPriceCents != null || maxPriceCents != null) {\n products = products.filter((product) => {\n const cents = displayedPriceCents(product)\n return (\n (minPriceCents == null || cents >= minPriceCents) &&\n (maxPriceCents == null || cents <= maxPriceCents)\n )\n })\n }\n if (sort === 'price-asc' || sort === 'price-desc') {\n products.sort((a, b) => {\n const [minA] = CommerceModel.productPriceRange(a)\n const [minB] = CommerceModel.productPriceRange(b)\n return sort === 'price-asc' ? minA - minB : minB - minA\n })\n } else if (sort === 'newest') {\n products.sort((a, b) => (b.createdAtMs ?? 0) - (a.createdAtMs ?? 0))\n } else if (\n !ids.length &&\n (!collection || (collection.data() as any).mode !== 'manual')\n ) {\n products.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n // Offset paging (AGL-561): grids pass `offset` for Load more;\n // `nextOffset` comes back only while more filtered items remain.\n const page = products.slice(offset, offset + max)\n const nextOffset =\n offset + max < products.length ? offset + max : undefined\n\n const items: PublicCatalogItem[] = page.map((product) => {\n const [minPrice, maxPrice] = CommerceModel.productPriceRange(product)\n const primary = product.variants[0]\n const inventory = CommerceModel.productInventory(product)\n return {\n id: product.$id,\n name: product.name,\n slug: product.slug,\n type: product.type,\n priceUsd: minPrice,\n maxPriceUsd: maxPrice,\n ...(primary?.compareAtPriceUsd\n ? { compareAtPriceUsd: primary.compareAtPriceUsd }\n : {}),\n ...(product.mediaUrls?.[0] || product.imageUrl\n ? { imageUrl: product.mediaUrls?.[0] ?? product.imageUrl }\n : {}),\n soldOut:\n inventory != null &&\n inventory <= 0 &&\n product.oversellPolicy !== 'backorder',\n ...(product.tags?.length ? { tags: product.tags } : {}),\n }\n })\n // Category facets (AGL-561): id/name/slug for grid filter chips,\n // parent-tree order preserved (order, then name).\n const categories: PublicCatalogCategory[] | undefined = facetsSnapshot\n ? facetsSnapshot.docs\n .map((docSnapshot) => {\n const data = docSnapshot.data() as CommerceModel.ProductCategory\n return {\n id: docSnapshot.id,\n name: String(data.name ?? ''),\n slug: String(data.slug ?? ''),\n order: Number(data.order ?? 0),\n }\n })\n .sort((a, b) => a.order - b.order || a.name.localeCompare(b.name))\n .map(({ id, name, slug }) => ({ id, name, slug }))\n : undefined\n\n return {\n items,\n ...(nextOffset != null ? { nextOffset } : {}),\n ...(categories ? { categories } : {}),\n ...(priceBounds ? { priceBounds } : {}),\n }\n}\n\n/** Public catalog listing endpoint — a thin parse over queryPublicCatalog. */\nexport const catalogHandler: PluginApiHandler = async (req, res) => {\n const hostId = String(req.query.hostId ?? '')\n if (!hostId) return res.status(400).json({ error: 'Missing hostId' })\n\n try {\n const result = await queryPublicCatalog({\n hostId,\n collectionSlug: String(req.query.collection ?? ''),\n categorySlug: String(req.query.category ?? ''),\n collectionId: String(req.query.collectionId ?? ''),\n categoryId: String(req.query.categoryId ?? ''),\n tag: String(req.query.tag ?? ''),\n query: String(req.query.q ?? ''),\n type: String(req.query.type ?? '') as CommerceModel.ProductType | '',\n ids: String(req.query.ids ?? '')\n .split(',')\n .map((id) => id.trim())\n .filter(Boolean),\n // Price-range filter (AGL-564): integer cents on the displayed price.\n minPriceCents: parsePriceCents(req.query.minPriceCents),\n maxPriceCents: parsePriceCents(req.query.maxPriceCents),\n sort: String(req.query.sort ?? 'name'),\n limit: Number(req.query.limit ?? 24),\n offset: Number(req.query.offset ?? 0),\n facets: String(req.query.facets ?? '') === '1',\n })\n res.setHeader(\n 'Cache-Control',\n 'public, s-maxage=60, stale-while-revalidate=300',\n )\n return res.status(200).json(result)\n } catch (error) {\n console.error(error)\n return res.status(500).json({ error: 'Catalog unavailable' })\n }\n}\n"],"names":["Aglyn","CommerceModel","firebaseAdmin","displayedPriceCents","product","Math","round","productPriceRange","parsePriceCents","value","raw","String","trim","undefined","cents","Number","isFinite","matchesCatalogQuery","query","needle","toLowerCase","name","includes","description","tags","some","tag","createCatalogReadScope","queryPublicCatalog","params","categoriesSnapshot","hostId","collectionSlug","categorySlug","collectionIdParam","collectionId","categoryIdParam","categoryId","type","ids","slice","minPriceCents","maxPriceCents","sort","max","min","limit","offset","wantFacets","Boolean","facets","firestore","app","hostRef","collection","doc","reads","sharedProducts","products","get","sharedCategories","categories","productsSnapshot","collectionsSnapshot","collectionByIdSnapshot","facetsSnapshot","Promise","all","where","collectionById","exists","hostCollectionKind","data","docs","find","docSnapshot","id","map","liftLegacyProduct","$id","filter","deletedAt","status","shaped","matchesCollection","mode","order","Map","productIds","index","a","b","categoryIds","length","has","priceBounds","minCents","maxCents","minA","minB","createdAtMs","localeCompare","page","nextOffset","items","minPrice","maxPrice","primary","variants","inventory","productInventory","slug","priceUsd","maxPriceUsd","compareAtPriceUsd","mediaUrls","imageUrl","soldOut","oversellPolicy","catalogHandler","req","res","json","error","result","category","q","split","setHeader","console"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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 { PluginApiHandler } from '@aglyn/aglyn/server';
|
|
18
|
+
/**
|
|
19
|
+
* Commerce Starter checkout (AGL-90): a site visitor buys a product. The
|
|
20
|
+
* price ALWAYS comes from the host's product doc (never the request), the
|
|
21
|
+
* money goes to the host owner's Connect account (AGL-46 onboarding) as a
|
|
22
|
+
* DESTINATION charge, and the webhook records the order under the host.
|
|
23
|
+
* 501 without Stripe env.
|
|
24
|
+
*
|
|
25
|
+
* Two claims in this comment were stale and are corrected here (AGL-2295),
|
|
26
|
+
* both in the direction that matters:
|
|
27
|
+
*
|
|
28
|
+
* - The fee is NOT "2%". It is `resolveTransactionFeePct(org, productType)`
|
|
29
|
+
* — a per-plan, per-product-type ladder with per-org staff overrides,
|
|
30
|
+
* resolved per request. 2% is one cell of sixteen (Starter, physical).
|
|
31
|
+
* - Selling is gated on `commerce`, not on `marketplaceSelling` (AGL-470).
|
|
32
|
+
* They are different entitlements on different plans: `marketplaceSelling`
|
|
33
|
+
* gates the marketplace, and reading this comment as current would gate a
|
|
34
|
+
* storefront on the wrong one.
|
|
35
|
+
*/
|
|
36
|
+
export declare const checkoutHandler: PluginApiHandler;
|