@mohasinac/appkit 4.65.0 โ 4.67.0
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/dist/.build-stamp.json +3 -3
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
- package/dist/_internal/client/features/digital-code/DigitalContentPoolManager.js +5 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +1 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -1
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +6 -2
- package/dist/_internal/client/features/lottery/LotteryAdminSlotView.js +5 -1
- package/dist/_internal/client/features/lottery/LotteryDetailView.js +6 -1
- package/dist/_internal/client/features/lottery/LotteryEntriesView.js +6 -1
- package/dist/_internal/client/features/lottery/LotteryListView.js +7 -1
- package/dist/_internal/client/features/lottery/LotteryPullForm.js +3 -1
- package/dist/_internal/client/features/lottery/LotterySlotGrid.js +3 -1
- package/dist/_internal/client/features/lottery/PrizeDrawLotteryDetailView.js +6 -1
- package/dist/_internal/client/features/maintenance/index.d.ts +1 -0
- package/dist/_internal/client/features/maintenance/index.js +1 -0
- package/dist/_internal/client/features/maintenance/views/CacheInvalidationPanel.d.ts +33 -0
- package/dist/_internal/client/features/maintenance/views/CacheInvalidationPanel.js +96 -0
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -1
- package/dist/_internal/client/scaffolds/AppShell.js +3 -1
- package/dist/_internal/server/features/account/data.js +2 -1
- package/dist/_internal/server/features/auctions/service.js +1 -1
- package/dist/_internal/server/features/auth/capabilities.js +1 -1
- package/dist/_internal/server/features/auth/permissions.js +1 -1
- package/dist/_internal/server/features/brands/actions.js +1 -1
- package/dist/_internal/server/features/brands/data.js +1 -1
- package/dist/_internal/server/features/brands/service.js +1 -1
- package/dist/_internal/server/features/bundles/actions.js +1 -1
- package/dist/_internal/server/features/bundles/data.js +2 -2
- package/dist/_internal/server/features/cart/actions.js +1 -1
- package/dist/_internal/server/features/cart/data.js +1 -1
- package/dist/_internal/server/features/cart/service.js +1 -1
- package/dist/_internal/server/features/categories/data.js +1 -1
- package/dist/_internal/server/features/checkout/actions.js +2 -2
- package/dist/_internal/server/features/checkout/group-rule-revalidation.js +1 -1
- package/dist/_internal/server/features/checkout/locked-lines.js +1 -1
- package/dist/_internal/server/features/checkout/upi-resolution.js +2 -1
- package/dist/_internal/server/features/grouped/data.js +2 -1
- package/dist/_internal/server/features/history/actions.d.ts +1 -1
- package/dist/_internal/server/features/history/actions.js +1 -1
- package/dist/_internal/server/features/history/data.d.ts +1 -1
- package/dist/_internal/server/features/history/data.js +1 -1
- package/dist/_internal/server/features/item-requests/data.js +1 -1
- package/dist/_internal/server/features/messages/actions.js +1 -1
- package/dist/_internal/server/features/payouts/actions.js +1 -1
- package/dist/_internal/server/features/pre-orders/actions.js +1 -1
- package/dist/_internal/server/features/pre-orders/service.js +1 -1
- package/dist/_internal/server/features/prize-draws/actions.js +1 -1
- package/dist/_internal/server/features/products/actions.js +1 -1
- package/dist/_internal/server/features/products/data.js +1 -1
- package/dist/_internal/server/features/products/list-public.js +1 -1
- package/dist/_internal/server/features/products/service.js +1 -1
- package/dist/_internal/server/features/products/surface-counts.d.ts +26 -0
- package/dist/_internal/server/features/products/surface-counts.js +60 -0
- package/dist/_internal/server/features/promotions/actions.js +1 -1
- package/dist/_internal/server/features/promotions/adapters.js +9 -0
- package/dist/_internal/server/features/promotions/data.d.ts +24 -3
- package/dist/_internal/server/features/promotions/data.js +41 -6
- package/dist/_internal/server/features/promotions/index.d.ts +1 -1
- package/dist/_internal/server/features/promotions/index.js +1 -1
- package/dist/_internal/server/features/promotions/service.js +1 -1
- package/dist/_internal/server/features/seo/sitemap.js +39 -5
- package/dist/_internal/server/features/shared/listing-data-factory.js +1 -1
- package/dist/_internal/server/features/shipping/courier-block.js +1 -1
- package/dist/_internal/server/features/site-settings/adapters.d.ts +16 -0
- package/dist/_internal/server/features/site-settings/adapters.js +11 -0
- package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +1 -1
- package/dist/_internal/server/features/stores/data.js +1 -1
- package/dist/_internal/server/features/sublisting-categories/data.js +1 -1
- package/dist/_internal/server/features/wishlist/actions.d.ts +1 -1
- package/dist/_internal/server/features/wishlist/actions.js +1 -1
- package/dist/_internal/server/features/wishlist/data.d.ts +1 -1
- package/dist/_internal/server/features/wishlist/data.js +1 -1
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +1 -1
- package/dist/_internal/server/jobs/core/cartPrune.js +1 -1
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.js +1 -1
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +1 -1
- package/dist/_internal/server/jobs/core/couponExpiry.js +1 -1
- package/dist/_internal/server/jobs/core/dailyDataCleanup.js +2 -1
- package/dist/_internal/server/jobs/core/draftPrune.js +1 -1
- package/dist/_internal/server/jobs/core/hardBanReinstatement.js +1 -1
- package/dist/_internal/server/jobs/core/newsletterExport.js +1 -1
- package/dist/_internal/server/jobs/core/notificationPrune.js +1 -1
- package/dist/_internal/server/jobs/core/onJobCreated.js +1 -1
- package/dist/_internal/server/jobs/core/onOrderCreate.js +3 -1
- package/dist/_internal/server/jobs/core/onProductWrite.js +35 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +2 -1
- package/dist/_internal/server/jobs/core/onScamReportRejected.js +1 -1
- package/dist/_internal/server/jobs/core/onScamReportVerified.js +1 -1
- package/dist/_internal/server/jobs/core/revenueRollup.js +1 -1
- package/dist/_internal/server/jobs/core/runJobOnce.js +1 -1
- package/dist/_internal/server/jobs/core/sellerStandingRollup.js +1 -1
- package/dist/_internal/server/jobs/core/surfaceCountsRollup.d.ts +55 -0
- package/dist/_internal/server/jobs/core/surfaceCountsRollup.js +128 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +1 -1
- package/dist/_internal/server/jobs/handlers/countersReconcile.js +54 -1
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.js +1 -1
- package/dist/_internal/shared/actions/action-registry.js +28 -0
- package/dist/_internal/shared/cache/revalidate-targets.js +66 -47
- package/dist/_internal/shared/features/blog/schema.d.ts +12 -12
- package/dist/_internal/shared/features/brands/schema.d.ts +19 -19
- package/dist/_internal/shared/features/cart/schema.d.ts +17 -17
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +60 -60
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +2 -2
- package/dist/_internal/shared/features/promotions/schema.d.ts +12 -12
- package/dist/_internal/shared/features/reviews/schema.d.ts +3 -3
- package/dist/_internal/shared/features/site-settings/types.d.ts +17 -0
- package/dist/_internal/shared/listing-types/feature-flags.d.ts +45 -0
- package/dist/_internal/shared/listing-types/feature-flags.js +51 -0
- package/dist/client.d.ts +225 -118
- package/dist/client.js +150 -74
- package/dist/constants/api-endpoints.d.ts +3 -0
- package/dist/constants/api-endpoints.js +11 -0
- package/dist/errors/error-handler.d.ts +1 -1
- package/dist/features/about/components/AboutView.js +9 -1
- package/dist/features/about/components/DeveloperView.js +8 -2
- package/dist/features/about/components/FAQPageView.js +5 -2
- package/dist/features/about/components/FeesView.js +4 -1
- package/dist/features/about/components/GstExplainerView.js +6 -1
- package/dist/features/about/components/GuidesHubView.js +5 -1
- package/dist/features/about/components/HelpPageView.js +6 -2
- package/dist/features/about/components/HowAuctionsWorkView.js +6 -2
- package/dist/features/about/components/HowCheckoutWorksView.js +6 -2
- package/dist/features/about/components/HowEmiWorksView.js +7 -2
- package/dist/features/about/components/HowOffersWorkView.js +6 -2
- package/dist/features/about/components/HowOrdersWorkView.js +6 -2
- package/dist/features/about/components/HowPayoutsWorkView.js +6 -2
- package/dist/features/about/components/HowPreOrdersWorkView.js +6 -2
- package/dist/features/about/components/HowReviewsWorkView.js +6 -2
- package/dist/features/about/components/PolicyPageView.js +6 -3
- package/dist/features/about/components/ProseHero.js +3 -1
- package/dist/features/about/components/PublicProfileView.js +6 -1
- package/dist/features/about/components/SecurityPrivacyView.js +6 -2
- package/dist/features/about/components/ShippingPolicyView.js +7 -3
- package/dist/features/about/components/SpotAFakeView.js +6 -1
- package/dist/features/about/components/TrackOrderView.js +5 -2
- package/dist/features/about/components/UnauthorizedView.js +5 -2
- package/dist/features/about/schemas/index.d.ts +18 -18
- package/dist/features/account/components/AddressBook.js +4 -1
- package/dist/features/account/components/AddressFilters.js +1 -1
- package/dist/features/account/components/AddressForm.js +1 -1
- package/dist/features/account/components/AddressSelectorCreate.js +2 -1
- package/dist/features/account/components/AddressesIndexListing.js +5 -1
- package/dist/features/account/components/BecomeSellerView.js +2 -1
- package/dist/features/account/components/BuyerAccountGuideView.js +6 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +5 -1
- package/dist/features/account/components/BuyerOrdersGuideView.js +5 -1
- package/dist/features/account/components/BuyerShoppingGuideView.js +5 -1
- package/dist/features/account/components/LinkedAccountsSection.js +5 -1
- package/dist/features/account/components/NotificationBell.js +8 -1
- package/dist/features/account/components/NotificationPreferencesPanel.js +6 -1
- package/dist/features/account/components/OrderDetailView.d.ts +1 -1
- package/dist/features/account/components/OrderDetailView.js +1 -1
- package/dist/features/account/components/ProfileView.d.ts +1 -1
- package/dist/features/account/components/ProfileView.js +1 -1
- package/dist/features/account/components/UserAccountHubView.d.ts +1 -1
- package/dist/features/account/components/UserAccountHubView.js +1 -1
- package/dist/features/account/components/UserBidsView.js +5 -1
- package/dist/features/account/components/UserOffersPanel.js +9 -1
- package/dist/features/account/components/UserOrderTrackView.d.ts +1 -1
- package/dist/features/account/components/UserOrderTrackView.js +1 -1
- package/dist/features/account/components/UserOrdersView.js +6 -1
- package/dist/features/account/components/UserReturnsView.js +3 -1
- package/dist/features/account/components/UserSidebar.js +8 -1
- package/dist/features/account/schemas/index.d.ts +10 -10
- package/dist/features/addresses/schemas/address-form.d.ts +16 -16
- package/dist/features/addresses/schemas/index.d.ts +2 -2
- package/dist/features/admin/actions/admin-actions.d.ts +3 -3
- package/dist/features/admin/actions/admin-coupon-actions.d.ts +1 -1
- package/dist/features/admin/actions/admin-read-actions.d.ts +3 -3
- package/dist/features/admin/components/AdminActionIndexView.d.ts +1 -1
- package/dist/features/admin/components/AdminActionIndexView.js +7 -1
- package/dist/features/admin/components/AdminAdEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminAdEditorView.js +8 -1
- package/dist/features/admin/components/AdminAddressBookView.js +8 -1
- package/dist/features/admin/components/AdminAddressClustersView.js +7 -1
- package/dist/features/admin/components/AdminAddressEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminAddressEditorView.js +4 -1
- package/dist/features/admin/components/AdminAddressesView.js +6 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +1 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -1
- package/dist/features/admin/components/AdminAnalyticsGuideView.js +5 -1
- package/dist/features/admin/components/AdminAnalyticsView.js +4 -2
- package/dist/features/admin/components/AdminArtView.d.ts +1 -1
- package/dist/features/admin/components/AdminArtView.js +1 -1
- package/dist/features/admin/components/AdminAuditLogView.d.ts +1 -1
- package/dist/features/admin/components/AdminAuditLogView.js +5 -1
- package/dist/features/admin/components/AdminBeysView.d.ts +1 -1
- package/dist/features/admin/components/AdminBeysView.js +3 -1
- package/dist/features/admin/components/AdminBidsView.d.ts +1 -1
- package/dist/features/admin/components/AdminBidsView.js +7 -2
- package/dist/features/admin/components/AdminBlogEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminBlogEditorView.js +14 -2
- package/dist/features/admin/components/AdminBlogView.d.ts +1 -1
- package/dist/features/admin/components/AdminBlogView.js +2 -1
- package/dist/features/admin/components/AdminBrandEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminBrandEditorView.js +7 -2
- package/dist/features/admin/components/AdminBrandsView.d.ts +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +4 -2
- package/dist/features/admin/components/AdminBundleEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +3 -1
- package/dist/features/admin/components/AdminBundlesView.js +7 -1
- package/dist/features/admin/components/AdminCarouselEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +12 -2
- package/dist/features/admin/components/AdminCarouselGroupEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminCarouselView.d.ts +1 -1
- package/dist/features/admin/components/AdminCarouselView.js +16 -2
- package/dist/features/admin/components/AdminCartsView.d.ts +1 -1
- package/dist/features/admin/components/AdminCartsView.js +3 -1
- package/dist/features/admin/components/AdminCatalogGuideView.js +5 -1
- package/dist/features/admin/components/AdminCategoriesView.d.ts +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +3 -1
- package/dist/features/admin/components/AdminCategoryEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminClassifiedView.d.ts +1 -1
- package/dist/features/admin/components/AdminClassifiedView.js +1 -1
- package/dist/features/admin/components/AdminContactView.d.ts +1 -1
- package/dist/features/admin/components/AdminContactView.js +5 -1
- package/dist/features/admin/components/AdminContentGuideView.js +5 -1
- package/dist/features/admin/components/AdminCouponEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +5 -1
- package/dist/features/admin/components/AdminCouponsView.d.ts +1 -1
- package/dist/features/admin/components/AdminCouponsView.js +6 -1
- package/dist/features/admin/components/AdminDashboardView.d.ts +1 -1
- package/dist/features/admin/components/AdminDashboardView.js +2 -2
- package/dist/features/admin/components/AdminDigitalCodesView.d.ts +1 -1
- package/dist/features/admin/components/AdminDigitalCodesView.js +1 -1
- package/dist/features/admin/components/AdminFaqEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminFaqEditorView.js +12 -2
- package/dist/features/admin/components/AdminFaqsView.d.ts +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +3 -1
- package/dist/features/admin/components/AdminFeatureEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminFeatureEditorView.js +6 -1
- package/dist/features/admin/components/AdminFeaturesView.d.ts +1 -1
- package/dist/features/admin/components/AdminFeaturesView.js +2 -1
- package/dist/features/admin/components/AdminFulfillmentView.js +2 -1
- package/dist/features/admin/components/AdminGatewayEventsView.d.ts +1 -1
- package/dist/features/admin/components/AdminGatewayEventsView.js +8 -1
- package/dist/features/admin/components/AdminGroupedListingsView.d.ts +1 -1
- package/dist/features/admin/components/AdminGroupedListingsView.js +7 -2
- package/dist/features/admin/components/AdminGuideHubView.js +6 -1
- package/dist/features/admin/components/AdminHistoryView.d.ts +1 -1
- package/dist/features/admin/components/AdminHistoryView.js +1 -1
- package/dist/features/admin/components/AdminIntegrationsView.js +6 -1
- package/dist/features/admin/components/AdminInvoicingView.js +6 -1
- package/dist/features/admin/components/AdminLiveView.d.ts +1 -1
- package/dist/features/admin/components/AdminLiveView.js +1 -1
- package/dist/features/admin/components/AdminMediaView.d.ts +1 -1
- package/dist/features/admin/components/AdminMediaView.js +11 -1
- package/dist/features/admin/components/AdminMoneyCasesView.d.ts +1 -1
- package/dist/features/admin/components/AdminMoneyCasesView.js +7 -1
- package/dist/features/admin/components/AdminNavEditorView.js +3 -1
- package/dist/features/admin/components/AdminNavigationView.d.ts +1 -1
- package/dist/features/admin/components/AdminNavigationView.js +10 -1
- package/dist/features/admin/components/AdminNewsletterView.d.ts +1 -1
- package/dist/features/admin/components/AdminNewsletterView.js +7 -1
- package/dist/features/admin/components/AdminNotificationsView.d.ts +1 -1
- package/dist/features/admin/components/AdminNotificationsView.js +5 -1
- package/dist/features/admin/components/AdminOffersView.d.ts +1 -1
- package/dist/features/admin/components/AdminOffersView.js +5 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +8 -2
- package/dist/features/admin/components/AdminOrdersGuideView.js +4 -1
- package/dist/features/admin/components/AdminOrdersView.d.ts +1 -1
- package/dist/features/admin/components/AdminOrdersView.js +3 -1
- package/dist/features/admin/components/AdminPartsView.d.ts +1 -1
- package/dist/features/admin/components/AdminPartsView.js +3 -1
- package/dist/features/admin/components/AdminPaymentClustersView.js +7 -1
- package/dist/features/admin/components/AdminPaymentMethodsView.js +7 -1
- package/dist/features/admin/components/AdminPaymentsGuideView.js +4 -1
- package/dist/features/admin/components/AdminPayoutsView.d.ts +1 -1
- package/dist/features/admin/components/AdminPayoutsView.js +5 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +1 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.js +7 -1
- package/dist/features/admin/components/AdminProductEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminProductEditorView.js +1 -1
- package/dist/features/admin/components/AdminProductsView.d.ts +1 -1
- package/dist/features/admin/components/AdminProductsView.js +5 -2
- package/dist/features/admin/components/AdminReturnRequestsView.js +3 -1
- package/dist/features/admin/components/AdminReviewsView.d.ts +1 -1
- package/dist/features/admin/components/AdminReviewsView.js +8 -1
- package/dist/features/admin/components/AdminScammersView.d.ts +1 -1
- package/dist/features/admin/components/AdminScammersView.js +5 -1
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsManager.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.d.ts +1 -1
- package/dist/features/admin/components/AdminSessionsView.js +6 -1
- package/dist/features/admin/components/AdminSidebar.js +7 -1
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +5 -1
- package/dist/features/admin/components/AdminSiteSettingsView.d.ts +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +2 -2
- package/dist/features/admin/components/AdminSparesView.d.ts +1 -1
- package/dist/features/admin/components/AdminSparesView.js +1 -1
- package/dist/features/admin/components/AdminStickersView.d.ts +1 -1
- package/dist/features/admin/components/AdminStickersView.js +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +1 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +7 -1
- package/dist/features/admin/components/AdminStoresGuideView.js +5 -1
- package/dist/features/admin/components/AdminStoresView.d.ts +1 -1
- package/dist/features/admin/components/AdminStoresView.js +4 -1
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +8 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +12 -1
- package/dist/features/admin/components/AdminSupportTicketsView.d.ts +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +4 -1
- package/dist/features/admin/components/AdminTaxCodeEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminTaxCodeEditorView.js +4 -1
- package/dist/features/admin/components/AdminTaxCodesView.d.ts +1 -1
- package/dist/features/admin/components/AdminTaxCodesView.js +1 -1
- package/dist/features/admin/components/AdminTeamGuideView.js +5 -1
- package/dist/features/admin/components/AdminTeamView.d.ts +1 -1
- package/dist/features/admin/components/AdminTeamView.js +4 -1
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +4 -1
- package/dist/features/admin/components/AdminTesterChecklistView.d.ts +1 -1
- package/dist/features/admin/components/AdminTesterChecklistView.js +4 -1
- package/dist/features/admin/components/AdminTopBar.js +1 -1
- package/dist/features/admin/components/AdminTrustGuideView.js +5 -1
- package/dist/features/admin/components/AdminUserEditorView.js +12 -1
- package/dist/features/admin/components/AdminUsersGuideView.js +5 -1
- package/dist/features/admin/components/AdminUsersView.d.ts +1 -1
- package/dist/features/admin/components/AdminViewCards.js +4 -1
- package/dist/features/admin/components/AdminWishlistsView.d.ts +1 -1
- package/dist/features/admin/components/AdminWishlistsView.js +1 -1
- package/dist/features/admin/components/DashboardStats.js +3 -1
- package/dist/features/admin/components/DataListingView.d.ts +1 -1
- package/dist/features/admin/components/DataListingView.js +14 -2
- package/dist/features/admin/components/DataTable.js +7 -1
- package/dist/features/admin/components/OwnerQuickActions.js +2 -1
- package/dist/features/admin/components/QuickEditMenu.js +2 -1
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +6 -1
- package/dist/features/admin/components/ViewNotificationModal.js +6 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +2 -1
- package/dist/features/admin/components/analytics/AdminStatCard.js +3 -1
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +3 -1
- package/dist/features/admin/components/sections/adminSectionsTypes.js +1 -0
- package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
- package/dist/features/admin/hooks/useOptimisticRowFlag.js +1 -1
- package/dist/features/admin/schemas/action-index-form.d.ts +2 -2
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +12 -12
- package/dist/features/admin/schemas/admin-ops-forms.d.ts +8 -8
- package/dist/features/admin/schemas/admin-user-form.d.ts +8 -8
- package/dist/features/admin/schemas/nav-item-form.d.ts +8 -8
- package/dist/features/auctions/actions/bid-actions.js +1 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +6 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +11 -2
- package/dist/features/auctions/components/AuctionFilters.js +1 -1
- package/dist/features/auctions/components/AuctionLiveStatusBadge.js +1 -1
- package/dist/features/auctions/components/AuctionsListView.js +3 -1
- package/dist/features/auctions/components/CollapsibleBidHistory.js +4 -1
- package/dist/features/auctions/components/LiveBidPrice.js +3 -1
- package/dist/features/auctions/components/LiveMinIncrement.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.d.ts +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +8 -1
- package/dist/features/auctions/schemas/index.d.ts +34 -34
- package/dist/features/auth/components/ForgotPasswordView.js +6 -1
- package/dist/features/auth/components/Guards.js +4 -1
- package/dist/features/auth/components/LoginForm.js +7 -1
- package/dist/features/auth/components/OAuthLoadingView.js +3 -1
- package/dist/features/auth/components/RegisterForm.js +5 -1
- package/dist/features/auth/components/ResetPasswordView.js +6 -1
- package/dist/features/auth/components/SocialAuthButtons.js +4 -1
- package/dist/features/auth/components/VerifyEmailView.js +4 -1
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/before-after/components/BeforeAfterGallery.js +3 -1
- package/dist/features/before-after/components/BeforeAfterSlider.js +3 -1
- package/dist/features/before-after/schemas/index.d.ts +4 -4
- package/dist/features/beys/components/BeyDetailPageView.js +7 -1
- package/dist/features/blog/actions/blog-actions.d.ts +39 -39
- package/dist/features/blog/components/BlogFeaturedCard.js +6 -1
- package/dist/features/blog/components/BlogFilters.js +1 -1
- package/dist/features/blog/components/BlogIndexListing.js +7 -1
- package/dist/features/blog/components/BlogIndexPageView.js +3 -1
- package/dist/features/blog/components/BlogListView.js +6 -1
- package/dist/features/blog/components/BlogPostForm.js +9 -2
- package/dist/features/blog/components/BlogPostView.js +5 -1
- package/dist/features/blog/schemas/blog-form.d.ts +10 -10
- package/dist/features/blog/schemas/index.d.ts +80 -80
- package/dist/features/cart/components/CartDrawer.js +6 -1
- package/dist/features/cart/components/CartGroupLineRow.js +5 -1
- package/dist/features/cart/components/CartPriceBreakdown.js +4 -1
- package/dist/features/cart/components/CartSummary.js +2 -1
- package/dist/features/cart/components/CartView.js +3 -1
- package/dist/features/cart/components/CheckoutAddressStep.js +3 -1
- package/dist/features/cart/components/CheckoutSuccessView.d.ts +1 -1
- package/dist/features/cart/components/CheckoutSuccessView.js +1 -1
- package/dist/features/cart/components/CheckoutView.js +3 -1
- package/dist/features/cart/components/PointsTenderPicker.js +3 -1
- package/dist/features/cart/components/ShippingPicker.js +4 -1
- package/dist/features/cart/components/StoreAddonsPicker.js +3 -1
- package/dist/features/cart/schemas/index.d.ts +30 -30
- package/dist/features/catalogue/actions/approve-catalogue-listing.js +1 -1
- package/dist/features/catalogue/actions/list-from-catalogue.js +2 -1
- package/dist/features/catalogue/actions/submit-for-approval.js +1 -1
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +6 -1
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +1 -1
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +6 -1
- package/dist/features/catalogue/components/PublicCatalogueView.js +5 -1
- package/dist/features/catalogue/components/UserCatalogueView.js +7 -1
- package/dist/features/catalogue/schemas/validation.d.ts +12 -12
- package/dist/features/catalogue/utils/product-from-item.js +1 -1
- package/dist/features/categories/components/BrandDetailPageView.js +6 -2
- package/dist/features/categories/components/BrandDetailTabs.js +2 -1
- package/dist/features/categories/components/BreadcrumbTrail.js +4 -2
- package/dist/features/categories/components/BundleBuyNowCta.js +5 -2
- package/dist/features/categories/components/BundleCollage.js +5 -1
- package/dist/features/categories/components/BundleDetailView.js +6 -1
- package/dist/features/categories/components/BundleDynamicRuleEditor.js +6 -1
- package/dist/features/categories/components/BundleItemsPicker.js +7 -1
- package/dist/features/categories/components/BundlesListView.js +4 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +8 -1
- package/dist/features/categories/components/CategoriesIndexPageView.js +3 -1
- package/dist/features/categories/components/CategoryBundlesListing.js +8 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +7 -2
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -1
- package/dist/features/categories/components/CategoryFilters.js +1 -1
- package/dist/features/categories/components/CategoryForm.js +3 -1
- package/dist/features/categories/components/CategoryGrid.js +3 -1
- package/dist/features/categories/components/CategoryHighlightsAndFaqSection.js +3 -1
- package/dist/features/categories/components/CategoryProductsListing.js +8 -1
- package/dist/features/categories/components/CategorySelectorCreate.js +6 -1
- package/dist/features/categories/components/CategorySortSelect.js +4 -1
- package/dist/features/categories/components/CategoryStoresListing.js +2 -1
- package/dist/features/categories/components/CategoryTableColumns.js +6 -2
- package/dist/features/categories/components/CategoryTemplatePicker.js +4 -1
- package/dist/features/categories/components/CategoryTree.js +2 -1
- package/dist/features/categories/components/ConcernCard.js +3 -1
- package/dist/features/categories/components/ConcernGrid.js +1 -1
- package/dist/features/categories/components/PriceGuidanceHint.js +3 -1
- package/dist/features/categories/components/SubcategoryCardRow.js +4 -1
- package/dist/features/categories/schemas/bundle-form.d.ts +22 -22
- package/dist/features/categories/schemas/index.d.ts +100 -100
- package/dist/features/checkout/components/CheckoutStepper.js +3 -1
- package/dist/features/classified/components/ClassifiedDetailPageView.js +7 -1
- package/dist/features/classified/components/ClassifiedFilters.js +3 -1
- package/dist/features/collections/components/CollectionCard.js +4 -1
- package/dist/features/collections/schemas/index.d.ts +9 -9
- package/dist/features/consultation/components/ConsultationForm.js +3 -1
- package/dist/features/consultation/schemas/index.d.ts +8 -8
- package/dist/features/contact/components/ContactForm.js +5 -2
- package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
- package/dist/features/contact/components/ContactPageView.js +6 -1
- package/dist/features/corporate/components/CorporateInquiryForm.js +3 -1
- package/dist/features/dashboard/components/DashboardHubView.js +7 -1
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +7 -1
- package/dist/features/digital-codes/components/DigitalCodeFilters.js +1 -1
- package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +4 -1
- package/dist/features/events/components/AdminEventEditorView.d.ts +1 -1
- package/dist/features/events/components/AdminEventEditorView.js +13 -2
- package/dist/features/events/components/AdminEventEntriesView.js +10 -2
- package/dist/features/events/components/AdminEventsView.d.ts +1 -1
- package/dist/features/events/components/AdminEventsView.js +2 -1
- package/dist/features/events/components/EventBanner.js +3 -1
- package/dist/features/events/components/EventCard.js +7 -1
- package/dist/features/events/components/EventDetailView.d.ts +1 -1
- package/dist/features/events/components/EventDetailView.js +1 -1
- package/dist/features/events/components/EventFilters.js +1 -1
- package/dist/features/events/components/EventFormDrawer.js +1 -1
- package/dist/features/events/components/EventInsights.js +3 -1
- package/dist/features/events/components/EventLeaderboard.js +3 -1
- package/dist/features/events/components/EventLikeButton.js +4 -1
- package/dist/features/events/components/EventLikersRail.js +5 -1
- package/dist/features/events/components/EventOfferCard.js +3 -1
- package/dist/features/events/components/EventParticipateView.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +8 -1
- package/dist/features/events/components/EventRaffleEntryForm.js +3 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +6 -1
- package/dist/features/events/components/EventRafflesSection.js +3 -1
- package/dist/features/events/components/EventSaleBanner.js +4 -1
- package/dist/features/events/components/EventStatusBadge.js +1 -1
- package/dist/features/events/components/EventTypeBadge.js +1 -1
- package/dist/features/events/components/EventsIndexListing.js +7 -1
- package/dist/features/events/components/EventsListPageView.js +3 -1
- package/dist/features/events/components/EventsListView.js +4 -1
- package/dist/features/events/components/RelatedEventsCarousel.js +3 -1
- package/dist/features/events/components/SpinWheel.js +1 -1
- package/dist/features/events/components/SpinWheelView.js +7 -1
- package/dist/features/events/schemas/event-form.d.ts +5 -0
- package/dist/features/events/schemas/event-form.js +17 -0
- package/dist/features/events/schemas/firestore.d.ts +49 -1
- package/dist/features/events/schemas/index.d.ts +184 -184
- package/dist/features/events/utils/carousel-slide.d.ts +0 -9
- package/dist/features/events/utils/carousel-slide.js +38 -1
- package/dist/features/faq/actions/faq-actions.d.ts +12 -12
- package/dist/features/faq/components/ContactCTA.js +5 -1
- package/dist/features/faq/components/FAQAccordion.js +6 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +5 -1
- package/dist/features/faq/components/FAQHelpfulButtons.js +3 -1
- package/dist/features/faq/components/FAQPageContent.js +8 -1
- package/dist/features/faq/components/FAQSearchableList.js +2 -1
- package/dist/features/faq/components/FAQSortDropdown.js +4 -1
- package/dist/features/faq/components/RelatedFAQs.js +4 -1
- package/dist/features/faq/schemas/index.d.ts +14 -14
- package/dist/features/filters/AsyncFacetSection.js +6 -1
- package/dist/features/filters/FilterFacetSection.js +6 -1
- package/dist/features/filters/FilterPanel.js +1 -1
- package/dist/features/filters/RangeFilter.js +6 -1
- package/dist/features/filters/SwitchFilter.js +5 -1
- package/dist/features/forms/Checkbox.js +3 -1
- package/dist/features/forms/Input.js +2 -1
- package/dist/features/forms/Radio.js +3 -1
- package/dist/features/forms/Select.js +2 -1
- package/dist/features/forms/Slider.js +3 -1
- package/dist/features/forms/Textarea.js +3 -1
- package/dist/features/forms/Toggle.js +3 -1
- package/dist/features/gateway-events/schemas/index.d.ts +10 -10
- package/dist/features/grouped/components/GroupedListingDetailView.js +4 -1
- package/dist/features/grouped/components/GroupedListingEditorView.js +5 -2
- package/dist/features/grouped/components/GroupedListingsCarousel.js +1 -1
- package/dist/features/grouped/schemas/grouped-listing-form.d.ts +2 -2
- package/dist/features/grouped/schemas/index.d.ts +6 -6
- package/dist/features/history/hooks/useHistory.js +1 -1
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
- package/dist/features/homepage/components/AdSlot.js +3 -1
- package/dist/features/homepage/components/BrandsSection.js +6 -1
- package/dist/features/homepage/components/CTABannerSection.js +6 -1
- package/dist/features/homepage/components/CharacterHotspot.js +5 -1
- package/dist/features/homepage/components/CharacterHotspotForm.js +8 -1
- package/dist/features/homepage/components/CollectionCardsSection.js +4 -1
- package/dist/features/homepage/components/CustomCardsSection.js +6 -1
- package/dist/features/homepage/components/CustomerReviewsSection.js +5 -1
- package/dist/features/homepage/components/FAQSection.js +8 -1
- package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +6 -1
- package/dist/features/homepage/components/HeroCarousel.js +6 -1
- package/dist/features/homepage/components/HomepageCouponsSection.d.ts +25 -0
- package/dist/features/homepage/components/HomepageCouponsSection.js +42 -0
- package/dist/features/homepage/components/HowItWorksSection.d.ts +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +7 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +52 -4
- package/dist/features/homepage/components/NewsletterSection.js +4 -1
- package/dist/features/homepage/components/PromoGrid.js +4 -1
- package/dist/features/homepage/components/SectionCarousel.d.ts +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +6 -1
- package/dist/features/homepage/components/SecurityHighlightsSection.js +6 -1
- package/dist/features/homepage/components/ShopByCategorySection.js +7 -1
- package/dist/features/homepage/components/SocialFeedSection.js +6 -1
- package/dist/features/homepage/components/SocialPostCard.js +4 -1
- package/dist/features/homepage/components/StatsCounterSection.js +5 -1
- package/dist/features/homepage/components/TestimonialsCarousel.js +4 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -1
- package/dist/features/homepage/components/WelcomeSection.js +10 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +8 -1
- package/dist/features/homepage/lib/section-renderer.d.ts +2 -0
- package/dist/features/homepage/lib/section-renderer.js +8 -0
- package/dist/features/homepage/schemas/firestore.d.ts +23 -2
- package/dist/features/homepage/schemas/firestore.js +2 -0
- package/dist/features/homepage/schemas/index.d.ts +133 -133
- package/dist/features/inventory/components/ReceiveStationView.js +9 -1
- package/dist/features/jobs/actions/enqueue-job.js +1 -1
- package/dist/features/layout/AutoBreadcrumbs.js +3 -1
- package/dist/features/layout/BackToTop.js +2 -1
- package/dist/features/layout/BottomActions.js +5 -1
- package/dist/features/layout/BottomActionsContext.d.ts +1 -1
- package/dist/features/layout/BottomChrome.js +1 -1
- package/dist/features/layout/BottomNavItem.js +2 -1
- package/dist/features/layout/BottomNavLayout.js +1 -1
- package/dist/features/layout/BottomSheet.js +4 -1
- package/dist/features/layout/Breadcrumbs.js +2 -1
- package/dist/features/layout/FooterLayout.js +5 -1
- package/dist/features/layout/LocaleSwitcher.js +1 -1
- package/dist/features/layout/NavItem.js +2 -1
- package/dist/features/layout/NavbarLayout.js +5 -1
- package/dist/features/layout/PageTabs.js +1 -1
- package/dist/features/layout/SideActionDock.js +7 -1
- package/dist/features/layout/SidebarLayout.d.ts +1 -1
- package/dist/features/layout/SidebarLayout.js +2 -1
- package/dist/features/layout/TitleBarLayout.js +9 -1
- package/dist/features/live/components/LiveItemDetailPageView.js +7 -1
- package/dist/features/live/components/LiveItemFilters.js +3 -1
- package/dist/features/lottery/schemas/config-write.d.ts +10 -10
- package/dist/features/lottery/schemas/zod.d.ts +6 -6
- package/dist/features/media/modals/ImageCropModal.js +6 -1
- package/dist/features/media/modals/ImageEditor.js +6 -1
- package/dist/features/media/modals/VideoTrimModal.js +6 -1
- package/dist/features/media/types/index.d.ts +4 -4
- package/dist/features/media/upload/MediaUploadList.js +7 -1
- package/dist/features/orders/components/OrderAddonBadges.js +2 -1
- package/dist/features/orders/components/OrderFilters.js +1 -1
- package/dist/features/orders/components/OrderPaymentSummary.js +4 -1
- package/dist/features/orders/components/OrderProvenanceCard.js +5 -1
- package/dist/features/orders/components/OrderScopeTabs.js +1 -1
- package/dist/features/orders/components/OrderSiblingPayments.js +3 -1
- package/dist/features/orders/components/OrderStatusTimeline.js +4 -1
- package/dist/features/orders/components/OrdersList.js +4 -1
- package/dist/features/orders/components/RefundHistoryTable.js +4 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/components/YourPurchaseStrip.js +5 -1
- package/dist/features/orders/schemas/index.d.ts +86 -86
- package/dist/features/parts/components/AssemblyDrawer.js +8 -1
- package/dist/features/parts/components/ModelCompositionPanel.js +5 -1
- package/dist/features/parts/components/PartDetailPageView.js +7 -1
- package/dist/features/parts/components/PartsIndexPageView.js +6 -1
- package/dist/features/parts/components/PartsSearchBox.js +5 -1
- package/dist/features/payments/schemas/index.d.ts +10 -10
- package/dist/features/points/schemas/adjust-form.d.ts +2 -2
- package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +1 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +6 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -2
- package/dist/features/pre-orders/components/PreOrderFilters.js +1 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +11 -2
- package/dist/features/pre-orders/components/PreOrdersListView.js +3 -1
- package/dist/features/pre-orders/components/PreorderCard.js +1 -1
- package/dist/features/pre-orders/schemas/index.d.ts +15 -15
- package/dist/features/price-index/components/PriceIndexToolView.js +4 -1
- package/dist/features/pricing/components/AdminPricingView.js +4 -1
- package/dist/features/print/components/BoxLabelPrintView.js +5 -1
- package/dist/features/print/components/LabelProfilePicker.js +3 -1
- package/dist/features/print/components/labels.js +3 -1
- package/dist/features/products/columns/productTableColumns.js +5 -1
- package/dist/features/products/components/ArtStickersListView.js +3 -1
- package/dist/features/products/components/AuctionDetailView.d.ts +1 -1
- package/dist/features/products/components/AuctionDetailView.js +2 -1
- package/dist/features/products/components/AuctionsIndexListing.js +10 -2
- package/dist/features/products/components/AvailabilityScopeHint.js +3 -1
- package/dist/features/products/components/AvailabilityTabs.js +1 -1
- package/dist/features/products/components/BidHistory.js +4 -1
- package/dist/features/products/components/CityCollectiblesView.js +6 -1
- package/dist/features/products/components/CompareOverlay.js +6 -1
- package/dist/features/products/components/CustomFieldsEditor.js +6 -1
- package/dist/features/products/components/CustomSectionTabContent.js +4 -1
- package/dist/features/products/components/CustomSectionsEditor.js +6 -1
- package/dist/features/products/components/FeatureBadge.js +2 -1
- package/dist/features/products/components/GroupMemberPicker.js +8 -1
- package/dist/features/products/components/GroupSettingsPanel.js +12 -1
- package/dist/features/products/components/MakeOfferButton.js +6 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +6 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +7 -1
- package/dist/features/products/components/NonRefundableConsentModal.js +6 -1
- package/dist/features/products/components/PreOrderDetailView.d.ts +1 -1
- package/dist/features/products/components/PreOrderDetailView.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -1
- package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +7 -1
- package/dist/features/products/components/PrizeDrawWinnerMappingView.js +7 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +8 -1
- package/dist/features/products/components/PrizeDrawsListingView.js +3 -1
- package/dist/features/products/components/PrizeDrawsSection.js +3 -1
- package/dist/features/products/components/PrizeRevealModal.js +6 -1
- package/dist/features/products/components/ProductCardMetadataSection.js +3 -1
- package/dist/features/products/components/ProductDetailActions.js +4 -1
- package/dist/features/products/components/ProductDetailPageView.js +10 -2
- package/dist/features/products/components/ProductDetailView.d.ts +1 -1
- package/dist/features/products/components/ProductDetailView.js +1 -1
- package/dist/features/products/components/ProductFeatureBadges.js +4 -1
- package/dist/features/products/components/ProductFeaturesSelector.js +3 -1
- package/dist/features/products/components/ProductFilters.js +2 -1
- package/dist/features/products/components/ProductForm.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +4 -1
- package/dist/features/products/components/ProductGradingTab.js +4 -1
- package/dist/features/products/components/ProductGrid.d.ts +1 -1
- package/dist/features/products/components/ProductGrid.js +7 -1
- package/dist/features/products/components/ProductsIndexListing.js +11 -3
- package/dist/features/products/components/ProductsIndexPageView.js +6 -2
- package/dist/features/products/components/RelatedItemsSection.js +1 -1
- package/dist/features/products/components/RelatedProducts.js +3 -1
- package/dist/features/products/components/ShowGroupSection.js +7 -1
- package/dist/features/products/components/SparesListView.js +4 -1
- package/dist/features/products/components/SublistingCarouselSection.js +4 -1
- package/dist/features/products/components/SublistingCategorySelect.js +2 -1
- package/dist/features/products/hooks/useProducts.js +1 -1
- package/dist/features/products/schemas/index.d.ts +70 -70
- package/dist/features/products/schemas/product-features.validators.d.ts +52 -52
- package/dist/features/products/schemas/surface-counts.d.ts +83 -0
- package/dist/features/products/schemas/surface-counts.js +58 -0
- package/dist/features/promotions/actions/promotions-actions.js +22 -6
- package/dist/features/promotions/components/AttachedCouponsSection.js +5 -2
- package/dist/features/promotions/components/CouponCard.js +8 -1
- package/dist/features/promotions/components/CouponCodeCopyRow.js +2 -1
- package/dist/features/promotions/components/CouponHelpDetails.js +4 -1
- package/dist/features/promotions/components/CouponsIndexListing.js +12 -1
- package/dist/features/promotions/components/PromotionsView.js +4 -1
- package/dist/features/promotions/constants/attached-coupons.d.ts +14 -0
- package/dist/features/promotions/repository/coupons.repository.js +32 -2
- package/dist/features/promotions/schemas/firestore.d.ts +33 -0
- package/dist/features/promotions/schemas/firestore.js +44 -0
- package/dist/features/promotions/schemas/index.d.ts +108 -108
- package/dist/features/reviews/components/ReviewDetailPageView.js +4 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +8 -1
- package/dist/features/reviews/components/ReviewFilters.js +1 -1
- package/dist/features/reviews/components/ReviewModal.js +7 -2
- package/dist/features/reviews/components/ReviewSummary.js +4 -2
- package/dist/features/reviews/components/ReviewsIndexPageView.js +3 -1
- package/dist/features/reviews/components/ReviewsList.js +7 -2
- package/dist/features/reviews/components/ReviewsListingPanel.js +7 -1
- package/dist/features/reviews/schemas/index.d.ts +40 -40
- package/dist/features/scams/components/ScamAwarenessModal.js +7 -1
- package/dist/features/scams/components/ScamProfileView.js +11 -1
- package/dist/features/scams/constants/scammer-status-display.d.ts +1 -1
- package/dist/features/scams/schemas/index.d.ts +22 -22
- package/dist/features/scams/schemas/report-form.d.ts +4 -4
- package/dist/features/search/components/EntityTypeahead.js +5 -1
- package/dist/features/search/components/Search.js +7 -1
- package/dist/features/search/components/SearchFacetRail.js +4 -1
- package/dist/features/search/components/SearchResultsClient.js +1 -1
- package/dist/features/search/components/SearchResultsPageView.js +5 -1
- package/dist/features/seller/components/BulkStockModal.js +2 -1
- package/dist/features/seller/components/CategoryChipPicker.js +3 -1
- package/dist/features/seller/components/FulfillmentView.js +2 -1
- package/dist/features/seller/components/GroupInlineSelect.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +11 -2
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +9 -1
- package/dist/features/seller/components/SellerAnalyticsView.d.ts +1 -1
- package/dist/features/seller/components/SellerAnalyticsView.js +4 -1
- package/dist/features/seller/components/SellerBidsView.js +8 -2
- package/dist/features/seller/components/SellerBundlesView.js +7 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +5 -1
- package/dist/features/seller/components/SellerCouponsView.d.ts +1 -1
- package/dist/features/seller/components/SellerCouponsView.js +5 -1
- package/dist/features/seller/components/SellerDashboardView.d.ts +1 -1
- package/dist/features/seller/components/SellerDashboardView.js +4 -1
- package/dist/features/seller/components/SellerFeaturesView.js +8 -1
- package/dist/features/seller/components/SellerGoogleReviewsView.js +7 -1
- package/dist/features/seller/components/SellerGroupedListingsView.js +4 -1
- package/dist/features/seller/components/SellerGuideView.d.ts +1 -1
- package/dist/features/seller/components/SellerGuideView.js +1 -1
- package/dist/features/seller/components/SellerListingTypeView.js +4 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +1 -1
- package/dist/features/seller/components/SellerOffersView.js +4 -1
- package/dist/features/seller/components/SellerOrdersView.js +8 -1
- package/dist/features/seller/components/SellerPayoutHistoryTable.js +2 -1
- package/dist/features/seller/components/SellerPayoutMethodsView.js +7 -1
- package/dist/features/seller/components/SellerPayoutRequestView.js +8 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -2
- package/dist/features/seller/components/SellerPayoutStats.js +1 -1
- package/dist/features/seller/components/SellerPayoutsView.d.ts +1 -1
- package/dist/features/seller/components/SellerPayoutsView.js +10 -1
- package/dist/features/seller/components/SellerProductsCards.js +7 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +7 -1
- package/dist/features/seller/components/SellerReviewsView.js +11 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +6 -1
- package/dist/features/seller/components/SellerShippingView.js +2 -2
- package/dist/features/seller/components/SellerSidebar.js +7 -1
- package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -1
- package/dist/features/seller/components/SellerStoreSetupView.js +2 -1
- package/dist/features/seller/components/SellerStorefrontView.js +1 -1
- package/dist/features/seller/components/SellerSupportView.d.ts +1 -1
- package/dist/features/seller/components/SellerSupportView.js +4 -1
- package/dist/features/seller/components/SellersListView.d.ts +1 -1
- package/dist/features/seller/components/SellersListView.js +1 -1
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.js +1 -1
- package/dist/features/seller/components/analytics/SellerRevenueChart.js +2 -1
- package/dist/features/seller/components/analytics/SellerTopProducts.js +3 -1
- package/dist/features/seller/schemas/coupon-form.d.ts +50 -50
- package/dist/features/seller/schemas/index.d.ts +22 -22
- package/dist/features/seller/schemas/order-forms.d.ts +12 -12
- package/dist/features/server-errors/schemas/index.d.ts +4 -4
- package/dist/features/shell/CommandPalette.js +7 -1
- package/dist/features/shell/FormShell.js +5 -1
- package/dist/features/shell/SectionForm.js +4 -1
- package/dist/features/shipments/components/AdminShipmentEditorView.js +9 -1
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +11 -1
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +10 -1
- package/dist/features/shipments/components/AdminShipmentsView.d.ts +1 -1
- package/dist/features/shipments/components/AdminShipmentsView.js +3 -1
- package/dist/features/shipments/components/ShipmentItemLinkModal.js +7 -1
- package/dist/features/shipments/schemas/validation.d.ts +44 -44
- package/dist/features/site-settings/components/ActionPermissionsManager.js +7 -2
- package/dist/features/site-settings/components/NavPermissionsManager.js +6 -2
- package/dist/features/site-settings/components/ThemeManagerView.js +9 -1
- package/dist/features/status-history/components/StatusTimeline.js +4 -1
- package/dist/features/sticker-trace/components/StickerPrintPanel.js +6 -1
- package/dist/features/sticker-trace/components/StickerRetryPanel.js +4 -1
- package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +5 -1
- package/dist/features/sticker-trace/components/StickerTraceStudio.js +5 -1
- package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +5 -5
- package/dist/features/store-extensions/schemas/custom-role-form.d.ts +12 -12
- package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +2 -2
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +13 -13
- package/dist/features/store-extensions/schemas/payout-method-form.d.ts +10 -10
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +12 -12
- package/dist/features/store-extensions/schemas/store-category-form.d.ts +10 -10
- package/dist/features/stores/components/InteractiveStoreCard.js +6 -1
- package/dist/features/stores/components/SellerStandingPanel.js +3 -1
- package/dist/features/stores/components/SellerTierBadge.js +2 -1
- package/dist/features/stores/components/StoreAboutView.js +5 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.js +2 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +8 -1
- package/dist/features/stores/components/StoreAuctionsView.d.ts +1 -1
- package/dist/features/stores/components/StoreAuctionsView.js +1 -1
- package/dist/features/stores/components/StoreBundlesPageView.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +6 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +7 -1
- package/dist/features/stores/components/StoreCreateForm.js +3 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +5 -2
- package/dist/features/stores/components/StoreDigitalCodesListing.js +7 -1
- package/dist/features/stores/components/StoreFilters.js +1 -1
- package/dist/features/stores/components/StoreFinanceGuideView.js +6 -1
- package/dist/features/stores/components/StoreGuideHubView.js +6 -1
- package/dist/features/stores/components/StoreHeader.js +6 -1
- package/dist/features/stores/components/StoreListingsGuideView.js +6 -1
- package/dist/features/stores/components/StoreLiveItemsListing.js +7 -1
- package/dist/features/stores/components/StoreNavTabs.js +3 -1
- package/dist/features/stores/components/StoreOrdersGuideView.js +7 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +7 -1
- package/dist/features/stores/components/StoreProductsListing.js +8 -1
- package/dist/features/stores/components/StoreProductsView.js +5 -1
- package/dist/features/stores/components/StoreReviewsView.d.ts +1 -1
- package/dist/features/stores/components/StoreReviewsView.js +1 -1
- package/dist/features/stores/components/StoreSettingsGuideView.js +6 -1
- package/dist/features/stores/components/StoresIndexListing.js +9 -2
- package/dist/features/stores/components/StoresIndexPageView.js +4 -2
- package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
- package/dist/features/stores/schemas/index.d.ts +28 -28
- package/dist/features/support/schemas/index.d.ts +14 -14
- package/dist/features/support/schemas/ticket-create-form.d.ts +4 -4
- package/dist/features/tax-codes/schemas/tax-code-form.d.ts +4 -4
- package/dist/features/tax-codes/schemas/tax-codes.validators.d.ts +10 -10
- package/dist/features/tester/actions/checklist-item-actions.d.ts +3 -3
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +7 -1
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +5 -1
- package/dist/features/tester/components/AdminTesterFeedbackReportView.js +2 -1
- package/dist/features/tester/components/AdminTesterFeedbackView.js +5 -1
- package/dist/features/tester/components/TesterChecklistStepRow.js +8 -1
- package/dist/features/tester/components/TesterFeedbackChart.js +3 -1
- package/dist/features/tester/schemas/checklist-item-form.d.ts +2 -2
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -1
- package/dist/features/wishlist/components/WishlistCapWatcher.js +1 -1
- package/dist/features/wishlist/components/WishlistHeartButton.js +2 -1
- package/dist/features/wishlist/components/WishlistPage.js +5 -1
- package/dist/features/wishlist/components/WishlistView.js +3 -1
- package/dist/features/wishlist/hooks/useWishlistToggle.js +1 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/features/wishlist/schemas/index.d.ts +2 -2
- package/dist/index.d.ts +2496 -2453
- package/dist/index.js +1545 -1500
- package/dist/next/api/routeHandler.js +1 -1
- package/dist/react/hooks/use-action-dispatch.d.ts +1 -1
- package/dist/react/hooks/use-action-dispatch.js +1 -1
- package/dist/react/hooks/useListingSurfaceVisibility.d.ts +44 -0
- package/dist/react/hooks/useListingSurfaceVisibility.js +20 -0
- package/dist/schemas/registry.d.ts +488 -483
- package/dist/schemas/sieve.d.ts +5 -5
- package/dist/schemas/webhooks/google-oauth.d.ts +4 -4
- package/dist/server.d.ts +371 -362
- package/dist/server.js +367 -351
- package/dist/ui/components/HorizontalScroller.js +27 -2
- package/dist/ui/components/Repeater.js +4 -1
- package/dist/validation/schemas.d.ts +26 -26
- package/package.json +121 -1
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* would need a `/media/...` proxy URL per the Media Architecture rules
|
|
11
11
|
* rather than a raw signed URL).
|
|
12
12
|
*/
|
|
13
|
-
import { newsletterRepository } from "../../../../
|
|
13
|
+
import { newsletterRepository } from "../../../../core/newsletter.repository.js";
|
|
14
14
|
import { sortBy } from "../../../../constants/sort.js";
|
|
15
15
|
import { COMMON_FIELDS } from "../../../../constants/field-names.js";
|
|
16
16
|
function escape(value) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
2
|
-
import { notificationRepository } from "../../../../
|
|
2
|
+
import { notificationRepository } from "../../../../features/admin/repository/notification.repository.js";
|
|
3
3
|
import { conversationsRepository } from "../../../../features/messages/repository/conversations.repository.js";
|
|
4
4
|
import { CONVERSATION_ACTIVE_DAYS, CONVERSATION_ARCHIVE_DAYS, } from "../../../../features/messages/schemas/firestore.js";
|
|
5
5
|
import { deleteAllMessages, listAllAttachmentUrls, } from "../../../../features/messages/repository/messages.repository.js";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* `runJobOnce`, which the retry sweep also calls. One dispatch path for both
|
|
12
12
|
* entry points, or the two drift the first time either learns something.
|
|
13
13
|
*/
|
|
14
|
-
import { jobsRepository } from "../../../../
|
|
14
|
+
import { jobsRepository } from "../../../../features/jobs/repository/jobs.repository.js";
|
|
15
15
|
import { runJobOnce } from "./runJobOnce.js";
|
|
16
16
|
export async function handleJobCreated(input, ctx) {
|
|
17
17
|
const { jobId, job } = input;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
2
2
|
import { ORDER_PII_FIELDS, revealPii } from "../../../../security/index.js";
|
|
3
|
-
import { adminNotificationsRepository
|
|
3
|
+
import { adminNotificationsRepository } from "../../../../features/store-extensions/repository/rbac.repositories.js";
|
|
4
|
+
import { storeRepository } from "../../../../features/stores/repository/store.repository.js";
|
|
5
|
+
import { userRepository } from "../../../../features/auth/repository/user.repository.js";
|
|
4
6
|
import { decryptPii } from "../../../../security/index.js";
|
|
5
7
|
import { sendWhatsAppBusinessMessage, buildPurchaseAnnouncementMessage, } from "../../../../features/whatsapp-bot/server.js";
|
|
6
8
|
import { resolveKeys } from "../../../../core/integration-keys.js";
|
|
@@ -3,11 +3,14 @@ import { normalizeError } from "../../../../errors/normalize.js";
|
|
|
3
3
|
* Core: keep category metrics + store stats in sync when a product document
|
|
4
4
|
* is written. Only published products count.
|
|
5
5
|
*/
|
|
6
|
-
import { categoriesRepository
|
|
6
|
+
import { categoriesRepository } from "../../../../features/categories/repository/categories.repository.js";
|
|
7
|
+
import { storeRepository } from "../../../../features/stores/repository/store.repository.js";
|
|
7
8
|
import { ProductStatusValues } from "../../../../features/products/schemas/firestore.js";
|
|
8
9
|
import { PRODUCT_FIELDS } from "../../../../constants/field-names.js";
|
|
9
10
|
import { isListingRowAvailable } from "../../../shared/listing-types/_registry.js";
|
|
11
|
+
import { isListingType } from "../../../shared/listing-types/feature-flags.js";
|
|
10
12
|
import { notifyRevalidate, productCacheFieldsChanged } from "./revalidateNotify.js";
|
|
13
|
+
import { runSurfaceCountsRollup } from "./surfaceCountsRollup.js";
|
|
11
14
|
const UNAVAILABLE_PRODUCT_STATUSES = new Set([
|
|
12
15
|
ProductStatusValues.ARCHIVED,
|
|
13
16
|
]);
|
|
@@ -300,4 +303,35 @@ export async function handleProductWrite(input, ctx) {
|
|
|
300
303
|
// reports how many rows it had to correct.
|
|
301
304
|
ctx.logger.error("Counter update failed (non-fatal โ countersReconcile will heal it tonight)", err, { productId });
|
|
302
305
|
}
|
|
306
|
+
/*
|
|
307
|
+
* Refresh the site-wide "is this surface empty" counters.
|
|
308
|
+
*
|
|
309
|
+
* ๐ Gated on `wasCounted !== isCounted`, reusing the availability-boundary
|
|
310
|
+
* signals computed just above rather than deriving a second opinion. Those
|
|
311
|
+
* two booleans already mean "did this row enter or leave the set a public
|
|
312
|
+
* browse page would show", which is exactly and only when a surface can
|
|
313
|
+
* cross zero. A stock decrement from 9 to 8 recomputes nothing.
|
|
314
|
+
*
|
|
315
|
+
* ๐ Scoped to the AFFECTED types, never all ten. A product can change
|
|
316
|
+
* `listingType`, which empties the old surface and fills the new one, so
|
|
317
|
+
* both are probed โ and `only` makes `runSurfaceCountsRollup` merge rather
|
|
318
|
+
* than replace, so the eight types this write cannot have touched keep
|
|
319
|
+
* their measured values instead of being dropped to unknown.
|
|
320
|
+
*
|
|
321
|
+
* Non-fatal, same contract as the counters above: the nightly rollup is the
|
|
322
|
+
* healer, and an unwritten counter degrades to "unknown", which every
|
|
323
|
+
* reader shows rather than hides.
|
|
324
|
+
*/
|
|
325
|
+
if (wasCounted !== isCounted) {
|
|
326
|
+
const touched = Array.from(new Set([before?.listingType, after?.listingType].filter((t) => typeof t === "string" && isListingType(t))));
|
|
327
|
+
if (touched.length > 0) {
|
|
328
|
+
try {
|
|
329
|
+
await runSurfaceCountsRollup(ctx, touched);
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
void normalizeError(err);
|
|
333
|
+
ctx.logger.error("Surface-count refresh failed (non-fatal โ the nightly rollup will heal it)", err, { productId, touched });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
303
337
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
2
|
-
import { adminNotificationsRepository
|
|
2
|
+
import { adminNotificationsRepository } from "../../../../features/store-extensions/repository/rbac.repositories.js";
|
|
3
|
+
import { userRepository } from "../../../../features/auth/repository/user.repository.js";
|
|
3
4
|
import { sendNotification } from "../../../../features/admin/actions/notification-actions.js";
|
|
4
5
|
import { SCAM_TYPE_LABELS } from "../../../../features/scams/constants/scam-types.js";
|
|
5
6
|
export async function handleScamReportCreate(input, ctx) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
2
|
-
import { userRepository } from "../../../../
|
|
2
|
+
import { userRepository } from "../../../../features/auth/repository/user.repository.js";
|
|
3
3
|
import { sendNotification } from "../../../../features/admin/actions/notification-actions.js";
|
|
4
4
|
export async function handleScamReportRejected(input, ctx) {
|
|
5
5
|
const { scammerId, report } = input;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
2
|
-
import { userRepository } from "../../../../
|
|
2
|
+
import { userRepository } from "../../../../features/auth/repository/user.repository.js";
|
|
3
3
|
import { sendNotification } from "../../../../features/admin/actions/notification-actions.js";
|
|
4
4
|
export async function handleScamReportVerified(input, ctx) {
|
|
5
5
|
const { scammerId, report } = input;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* single doc instead of scanning the collection.
|
|
11
11
|
*/
|
|
12
12
|
import { orderRepository } from "../../../../repositories/index.js";
|
|
13
|
-
import { analyticsRollupRepository } from "../../../../
|
|
13
|
+
import { analyticsRollupRepository } from "../../../../features/admin/repository/analytics-rollup.repository.js";
|
|
14
14
|
export async function runRevenueRollup(ctx) {
|
|
15
15
|
// No `.catch(() => [])` here on purpose: an empty list is a legitimate
|
|
16
16
|
// outcome that writes `totalRevenue: 0`, so swallowing a query failure would
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import { normalizeError } from "../../../../errors/normalize.js";
|
|
34
34
|
import { mapToHttpError } from "../../../../errors/error-mapping.js";
|
|
35
|
-
import { jobsRepository } from "../../../../
|
|
35
|
+
import { jobsRepository } from "../../../../features/jobs/repository/jobs.repository.js";
|
|
36
36
|
import { paymentCasesRepository } from "../../../../features/payment-cases/repository/payment-cases.repository.js";
|
|
37
37
|
import { getAdminRealtimeDb } from "../../../../providers/db-firebase/index.js";
|
|
38
38
|
import { RTDB_PATHS } from "../../../../providers/db-firebase/rtdb-paths.js";
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* self-bought orders excluded, test data excluded, and the 500-store bound on
|
|
26
26
|
* `findTrustedStoreIds` left in place so saturation is visible.
|
|
27
27
|
*/
|
|
28
|
-
import { storeRepository } from "../../../../
|
|
28
|
+
import { storeRepository } from "../../../../features/stores/repository/store.repository.js";
|
|
29
29
|
import { ORDER_FIELDS, REVIEW_FIELDS } from "../../../../constants/field-names.js";
|
|
30
30
|
import { recordAdminAction } from "../../features/audit-log/actions.js";
|
|
31
31
|
import { AdminAuditActionValues } from "../../../../features/audit-log/schemas/firestore.js";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recompute `surfaceCounts/global` โ "does each public browse surface have
|
|
3
|
+
* anything in it?"
|
|
4
|
+
*
|
|
5
|
+
* ## ๐ It asks `listPublicProducts`, not Firestore
|
|
6
|
+
*
|
|
7
|
+
* The temptation is a `count()` aggregation per listing type. That would be
|
|
8
|
+
* cheaper and it would be WRONG, because "available" is not expressible as a
|
|
9
|
+
* Firestore predicate: it is a negation (`NOT (sold OR ended OR closed OR
|
|
10
|
+
* depleted)`) evaluated per row, which is exactly why `listPublicProducts`
|
|
11
|
+
* runs one bounded query per unavailable-clause and filters in memory.
|
|
12
|
+
*
|
|
13
|
+
* A bespoke count would therefore answer a DIFFERENT question from the page it
|
|
14
|
+
* governs, and the failure mode is the bad one: hiding `/spares` while
|
|
15
|
+
* `/spares` would have rendered rows. Routing through the one function every
|
|
16
|
+
* browse page already uses makes that disagreement impossible by construction
|
|
17
|
+
* โ the same argument CLAUDE.md makes for never calling
|
|
18
|
+
* `productRepository.list()` directly from a listing view.
|
|
19
|
+
*
|
|
20
|
+
* ## Cost
|
|
21
|
+
*
|
|
22
|
+
* `pageSize: 1` โ we need existence, not a figure. Ten listing types plus one
|
|
23
|
+
* review query, each bounded, and only from a job or a boundary-crossing
|
|
24
|
+
* trigger. Never from a request path: the public reader gets the single
|
|
25
|
+
* pre-computed document via `/api/site-settings`.
|
|
26
|
+
*
|
|
27
|
+
* ## ๐ A failed probe writes NOTHING for that type
|
|
28
|
+
*
|
|
29
|
+
* `listPublicProducts` returns `null` on failure. Recording that as `0` would
|
|
30
|
+
* hide a surface because a query timed out, so a failed probe leaves the key
|
|
31
|
+
* ABSENT โ which every reader treats as "show" (Root Cause #72). Partial
|
|
32
|
+
* results are written: a surface we did measure is still worth recording.
|
|
33
|
+
*
|
|
34
|
+
* @tag domain:products
|
|
35
|
+
* @tag layer:job
|
|
36
|
+
* @tag access:server-only
|
|
37
|
+
* @tag sideEffects:firestore-read,firestore-write
|
|
38
|
+
*/
|
|
39
|
+
import type { ListingType } from "../../../../features/products/types/index";
|
|
40
|
+
import type { JobContext } from "../runtime/types";
|
|
41
|
+
export interface SurfaceCountsResult {
|
|
42
|
+
listingTypes: Partial<Record<ListingType, number>>;
|
|
43
|
+
surfaces: Partial<Record<string, number>>;
|
|
44
|
+
/** Types whose probe failed โ recorded so a silent partial is visible. */
|
|
45
|
+
failed: string[];
|
|
46
|
+
}
|
|
47
|
+
export declare function computeSurfaceCounts(ctx: Pick<JobContext, "db">, only?: readonly ListingType[]): Promise<SurfaceCountsResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Recompute and persist.
|
|
50
|
+
*
|
|
51
|
+
* `only` narrows to the types a single product write could have moved, so the
|
|
52
|
+
* trigger path costs one query instead of eleven. A narrowed run MERGES โ it
|
|
53
|
+
* must never clear the keys it did not measure.
|
|
54
|
+
*/
|
|
55
|
+
export declare function runSurfaceCountsRollup(ctx: Pick<JobContext, "db">, only?: readonly ListingType[]): Promise<SurfaceCountsResult>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recompute `surfaceCounts/global` โ "does each public browse surface have
|
|
3
|
+
* anything in it?"
|
|
4
|
+
*
|
|
5
|
+
* ## ๐ It asks `listPublicProducts`, not Firestore
|
|
6
|
+
*
|
|
7
|
+
* The temptation is a `count()` aggregation per listing type. That would be
|
|
8
|
+
* cheaper and it would be WRONG, because "available" is not expressible as a
|
|
9
|
+
* Firestore predicate: it is a negation (`NOT (sold OR ended OR closed OR
|
|
10
|
+
* depleted)`) evaluated per row, which is exactly why `listPublicProducts`
|
|
11
|
+
* runs one bounded query per unavailable-clause and filters in memory.
|
|
12
|
+
*
|
|
13
|
+
* A bespoke count would therefore answer a DIFFERENT question from the page it
|
|
14
|
+
* governs, and the failure mode is the bad one: hiding `/spares` while
|
|
15
|
+
* `/spares` would have rendered rows. Routing through the one function every
|
|
16
|
+
* browse page already uses makes that disagreement impossible by construction
|
|
17
|
+
* โ the same argument CLAUDE.md makes for never calling
|
|
18
|
+
* `productRepository.list()` directly from a listing view.
|
|
19
|
+
*
|
|
20
|
+
* ## Cost
|
|
21
|
+
*
|
|
22
|
+
* `pageSize: 1` โ we need existence, not a figure. Ten listing types plus one
|
|
23
|
+
* review query, each bounded, and only from a job or a boundary-crossing
|
|
24
|
+
* trigger. Never from a request path: the public reader gets the single
|
|
25
|
+
* pre-computed document via `/api/site-settings`.
|
|
26
|
+
*
|
|
27
|
+
* ## ๐ A failed probe writes NOTHING for that type
|
|
28
|
+
*
|
|
29
|
+
* `listPublicProducts` returns `null` on failure. Recording that as `0` would
|
|
30
|
+
* hide a surface because a query timed out, so a failed probe leaves the key
|
|
31
|
+
* ABSENT โ which every reader treats as "show" (Root Cause #72). Partial
|
|
32
|
+
* results are written: a surface we did measure is still worth recording.
|
|
33
|
+
*
|
|
34
|
+
* @tag domain:products
|
|
35
|
+
* @tag layer:job
|
|
36
|
+
* @tag access:server-only
|
|
37
|
+
* @tag sideEffects:firestore-read,firestore-write
|
|
38
|
+
*/
|
|
39
|
+
import { normalizeError } from "../../../../errors/normalize.js";
|
|
40
|
+
import { listPublicProducts } from "../../features/products/list-public.js";
|
|
41
|
+
import { SURFACE_COUNTS_COLLECTION, SURFACE_COUNTS_DOC_ID, } from "../../../../features/products/schemas/surface-counts.js";
|
|
42
|
+
import { ALL_LISTING_TYPES } from "../../../shared/listing-types/feature-flags.js";
|
|
43
|
+
import { REVIEW_COLLECTION, reviewQueryHelpers, } from "../../../../features/reviews/schemas/firestore.js";
|
|
44
|
+
/**
|
|
45
|
+
* Probe one listing type. Returns `undefined` โ not 0 โ when the query failed.
|
|
46
|
+
*
|
|
47
|
+
* `total` is a FLOOR once `truncated` is set, which does not matter here: we
|
|
48
|
+
* only compare against zero, and a floor of N > 0 is still decisively
|
|
49
|
+
* non-empty.
|
|
50
|
+
*/
|
|
51
|
+
async function probeListingType(type) {
|
|
52
|
+
try {
|
|
53
|
+
const res = await listPublicProducts({ listingTypes: [type], pageSize: 1 });
|
|
54
|
+
if (!res)
|
|
55
|
+
return undefined;
|
|
56
|
+
return res.total;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
void normalizeError(err);
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export async function computeSurfaceCounts(ctx, only) {
|
|
64
|
+
const types = only ?? ALL_LISTING_TYPES;
|
|
65
|
+
const listingTypes = {};
|
|
66
|
+
const surfaces = {};
|
|
67
|
+
const failed = [];
|
|
68
|
+
// Parallel: ten bounded queries with no interdependence. Sequential would
|
|
69
|
+
// be ten round-trips for no benefit.
|
|
70
|
+
const probes = await Promise.all(types.map((t) => probeListingType(t)));
|
|
71
|
+
types.forEach((t, i) => {
|
|
72
|
+
const n = probes[i];
|
|
73
|
+
if (n === undefined)
|
|
74
|
+
failed.push(t);
|
|
75
|
+
else
|
|
76
|
+
listingTypes[t] = n;
|
|
77
|
+
});
|
|
78
|
+
// `/reviews` has no listing-type flag, so emptiness is its only signal.
|
|
79
|
+
// A plain `count()` IS correct here: a review has no availability notion โ
|
|
80
|
+
// it is approved and public, or it is not in the collection's public view.
|
|
81
|
+
if (!only) {
|
|
82
|
+
try {
|
|
83
|
+
// `reviewQueryHelpers.approved()` rather than a hand-written
|
|
84
|
+
// `["isApproved", "==", true]` โ which is what this first read, and the
|
|
85
|
+
// field does not exist. Approval is `status == "approved"`, and a filter
|
|
86
|
+
// on an absent field matches NOTHING, so the hand-written version would
|
|
87
|
+
// have reported every site as having zero reviews and hidden /reviews
|
|
88
|
+
// permanently. The helper is the shipped spelling.
|
|
89
|
+
const [field, op, value] = reviewQueryHelpers.approved();
|
|
90
|
+
const snap = await ctx.db
|
|
91
|
+
.collection(REVIEW_COLLECTION)
|
|
92
|
+
.where(field, op, value)
|
|
93
|
+
.limit(1)
|
|
94
|
+
.get();
|
|
95
|
+
surfaces.reviews = snap.size;
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
void normalizeError(err);
|
|
99
|
+
failed.push("reviews");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { listingTypes, surfaces, failed };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Recompute and persist.
|
|
106
|
+
*
|
|
107
|
+
* `only` narrows to the types a single product write could have moved, so the
|
|
108
|
+
* trigger path costs one query instead of eleven. A narrowed run MERGES โ it
|
|
109
|
+
* must never clear the keys it did not measure.
|
|
110
|
+
*/
|
|
111
|
+
export async function runSurfaceCountsRollup(ctx, only) {
|
|
112
|
+
const result = await computeSurfaceCounts(ctx, only);
|
|
113
|
+
const payload = { updatedAt: new Date() };
|
|
114
|
+
// Dot-path merge for a narrowed run: `{ listingTypes: {...} }` with
|
|
115
|
+
// `merge: true` would still replace the whole map on some drivers, and we
|
|
116
|
+
// must not drop a key this run did not probe.
|
|
117
|
+
for (const [k, v] of Object.entries(result.listingTypes)) {
|
|
118
|
+
payload[`listingTypes.${k}`] = v;
|
|
119
|
+
}
|
|
120
|
+
for (const [k, v] of Object.entries(result.surfaces)) {
|
|
121
|
+
payload[`surfaces.${k}`] = v;
|
|
122
|
+
}
|
|
123
|
+
await ctx.db
|
|
124
|
+
.collection(SURFACE_COUNTS_COLLECTION)
|
|
125
|
+
.doc(SURFACE_COUNTS_DOC_ID)
|
|
126
|
+
.set(payload, { merge: true });
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { storeRepository, userRepository, orderRepository, payoutRepository, siteSettingsRepository, } from "../../../../repositories/index.js";
|
|
6
6
|
import { BATCH_LIMIT } from "../handlers/messages.js";
|
|
7
|
-
import { getDefaultCurrency } from "../../../../core/
|
|
7
|
+
import { getDefaultCurrency } from "../../../../core/baseline-resolver.js";
|
|
8
8
|
import { computePayoutDeduction } from "../../../shared/fees/calculator.js";
|
|
9
9
|
import { payoutCutoff } from "../../../shared/fees/payout-hold.js";
|
|
10
10
|
import { PROTECTION_CLAIM_WINDOW_HOURS } from "../../../shared/features/shipping/protections.js";
|
|
@@ -1,2 +1,55 @@
|
|
|
1
|
+
import { normalizeError } from "../../../../errors/normalize.js";
|
|
1
2
|
import { runCountersReconcile } from "../core/countersReconcile.js";
|
|
2
|
-
|
|
3
|
+
import { runSurfaceCountsRollup } from "../core/surfaceCountsRollup.js";
|
|
4
|
+
/*
|
|
5
|
+
* ๐ The surface-count rollup rides THIS job rather than taking a Scheduler
|
|
6
|
+
* slot of its own.
|
|
7
|
+
*
|
|
8
|
+
* Two reasons, and the second is the one that matters:
|
|
9
|
+
*
|
|
10
|
+
* 1. Cost โ every registered Scheduler job is billed (~$0.10/mo beyond the
|
|
11
|
+
* free 3), and the Firebase budget table in CLAUDE.md says to fold new
|
|
12
|
+
* periodic work into an existing cadence when it is a natural fit.
|
|
13
|
+
* 2. Semantics โ `countersReconcile` IS the nightly healer for incrementally
|
|
14
|
+
* maintained counters. `surfaceCounts` is incrementally maintained by
|
|
15
|
+
* `onProductWrite` under exactly the same "non-fatal, the nightly job will
|
|
16
|
+
* heal it" contract. Putting the healer somewhere else would mean two jobs
|
|
17
|
+
* owning one guarantee.
|
|
18
|
+
*
|
|
19
|
+
* Sequential, not `Promise.all`: both walk products, and running them together
|
|
20
|
+
* doubles the peak read rate for no wall-clock benefit on a 540s budget.
|
|
21
|
+
*
|
|
22
|
+
* ๐ Its failure must not fail the reconcile. The counters this job exists for
|
|
23
|
+
* are the ones two Sieve SORTS order by; a surface count is a display decision
|
|
24
|
+
* that degrades to "unknown", i.e. to showing the surface. Never let the
|
|
25
|
+
* cosmetic half take down the load-bearing half.
|
|
26
|
+
*/
|
|
27
|
+
export const countersReconcileHandler = async (ctx) => {
|
|
28
|
+
const result = await runCountersReconcile(ctx);
|
|
29
|
+
try {
|
|
30
|
+
const surfaces = await runSurfaceCountsRollup(ctx);
|
|
31
|
+
/*
|
|
32
|
+
* Serialised to `"type=n"` pairs rather than logged as the maps
|
|
33
|
+
* themselves: the logger's value type is `JsonValue`, and a
|
|
34
|
+
* `Partial<Record<K, number>>` is not assignable to it (an optional
|
|
35
|
+
* property can be `undefined`, which is not JSON). Flattening is also the
|
|
36
|
+
* more readable log line.
|
|
37
|
+
*/
|
|
38
|
+
ctx.logger.info("Surface counts rolled up", {
|
|
39
|
+
listingTypes: Object.entries(surfaces.listingTypes)
|
|
40
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
41
|
+
.join(" "),
|
|
42
|
+
surfaces: Object.entries(surfaces.surfaces)
|
|
43
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
44
|
+
.join(" "),
|
|
45
|
+
// Named rather than counted โ a surface left unmeasured stays visible,
|
|
46
|
+
// and an operator needs to know WHICH, not how many.
|
|
47
|
+
failed: surfaces.failed.join(",") || "none",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
void normalizeError(err);
|
|
52
|
+
ctx.logger.error("Surface-count rollup failed (non-fatal)", err);
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { adminNotificationsRepository } from "../../../../
|
|
1
|
+
import { adminNotificationsRepository } from "../../../../features/store-extensions/repository/rbac.repositories.js";
|
|
2
2
|
export const onCatalogueSubmittedForApprovalHandler = async (event) => {
|
|
3
3
|
const before = event.before?.listingStatus;
|
|
4
4
|
const after = event.after?.listingStatus;
|
|
@@ -1895,6 +1895,34 @@ export const ACTIONS = {
|
|
|
1895
1895
|
kind: "primary",
|
|
1896
1896
|
permissions: ["admin"],
|
|
1897
1897
|
},
|
|
1898
|
+
"invalidate-cache": {
|
|
1899
|
+
// `retry` โ the icon registry has no `refresh`/`reload`/`sync` key, and
|
|
1900
|
+
// inventing one means a new glyph in a catalogued set. `retry` is the
|
|
1901
|
+
// registered "do this again" mark and reads correctly for a re-render.
|
|
1902
|
+
iconKey: "retry",
|
|
1903
|
+
id: "admin.invalidate-cache",
|
|
1904
|
+
label: "Invalidate all cached pages",
|
|
1905
|
+
ariaLabel: "Mark every cached public page stale",
|
|
1906
|
+
description: "Mark every cached public page stale so the next visitor gets a freshly rendered one. Use after a bulk data change the Firestore triggers could not see โ a seed load, a direct Firestore edit, or a catalogue purge.",
|
|
1907
|
+
kind: "secondary",
|
|
1908
|
+
permissions: ["admin"],
|
|
1909
|
+
/*
|
|
1910
|
+
* ๐ A confirmation on a NON-destructive action, because the cost is
|
|
1911
|
+
* real and invisible at the click.
|
|
1912
|
+
*
|
|
1913
|
+
* This marks entries stale; it renders nothing and destroys nothing. But
|
|
1914
|
+
* every marked entry regenerates on its next request, and this project
|
|
1915
|
+
* was SUSPENDED (HTTP 402) for exceeding 200K ISR writes with 3.1M โ
|
|
1916
|
+
* writes outnumbering reads 3:1. Rule #6's whole cache posture exists to
|
|
1917
|
+
* keep that from recurring, so a button that re-renders the public site
|
|
1918
|
+
* on demand must not be reachable by a stray click.
|
|
1919
|
+
*/
|
|
1920
|
+
confirmation: {
|
|
1921
|
+
title: "Invalidate every cached page?",
|
|
1922
|
+
body: "Every public page is marked stale and re-renders on its next visit. Nothing is deleted and no data changes, but the re-render costs function invocations against the plan quota โ so use it after a bulk change, not as a routine refresh.",
|
|
1923
|
+
confirmLabel: "Invalidate all",
|
|
1924
|
+
},
|
|
1925
|
+
},
|
|
1898
1926
|
"update-pricing": {
|
|
1899
1927
|
iconKey: "save",
|
|
1900
1928
|
id: "admin.update-pricing",
|
|
@@ -33,67 +33,86 @@
|
|
|
33
33
|
*/
|
|
34
34
|
/** What the caller knows about the written document, when it knows anything. */
|
|
35
35
|
import { ROUTES } from "../../../next/routing/route-map.js";
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
import { LISTING_TYPE_REGISTRY } from "../listing-types/_registry.js";
|
|
37
|
+
/*
|
|
38
|
+
* ๐ DERIVED from `LISTING_TYPE_REGISTRY`, never hand-written.
|
|
39
|
+
*
|
|
40
|
+
* This file carried its own nine-entry `PRODUCT_DETAIL_BY_TYPE` literal and its
|
|
41
|
+
* own `listingTypeFromId` prefix ladder, and both had already drifted by the
|
|
42
|
+
* time the union reached ten โ exactly the tenth-enumeration failure Root Cause
|
|
43
|
+
* #61 is about. Measured 2026-10-26, while invalidating after a catalogue purge
|
|
44
|
+
* that deleted 7 `spares` and 2 `stickers`:
|
|
45
|
+
*
|
|
46
|
+
* - **`spares` was absent from both.** A `spare-โฆ` id fell through to the
|
|
47
|
+
* "unknown type" branch, which marks every OTHER type's detail route and
|
|
48
|
+
* therefore never marks `/products/spare-โฆ` โ the one page that existed.
|
|
49
|
+
* - **`/art`, `/stickers` and `/spares` were never marked at all.** The browse
|
|
50
|
+
* path was derived by stripping the last segment off the detail route, and
|
|
51
|
+
* all three types detail at `/products/{slug}`, so the strip yielded
|
|
52
|
+
* `/products` and the `!== ROUTES.PUBLIC.PRODUCTS` test discarded it. Their
|
|
53
|
+
* dedicated browse pages are in `MAIN_NAV_ITEMS` and went stale on a clock.
|
|
54
|
+
*
|
|
55
|
+
* `browseRoute` and `slugPrefix` are required plugin fields, so a type cannot
|
|
56
|
+
* join the union without answering both โ which is the property the literal
|
|
57
|
+
* could never have.
|
|
58
|
+
*/
|
|
59
|
+
const PLUGINS = Object.values(LISTING_TYPE_REGISTRY);
|
|
48
60
|
/**
|
|
49
61
|
* Infer the listing type from the id prefix when no hint was supplied.
|
|
50
62
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* `
|
|
63
|
+
* Calls the shipped `slugPrefix` on each plugin rather than re-deriving the
|
|
64
|
+
* prefix map โ the same decision `audit-seed-listing-type`'s R3 makes, and the
|
|
65
|
+
* reason that audit caught five `stickers-` ids against a registered
|
|
66
|
+
* `sticker-` prefix. Returns `undefined` rather than `detectListingTypeFromSlug`'s
|
|
67
|
+
* `"standard"` default: here, "no prefix matched" must widen to every detail
|
|
68
|
+
* route, not silently narrow to one.
|
|
55
69
|
*/
|
|
56
70
|
function listingTypeFromId(id) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (id.startsWith("prizedraw-"))
|
|
62
|
-
return "prize-draw";
|
|
63
|
-
if (id.startsWith("classified-"))
|
|
64
|
-
return "classified";
|
|
65
|
-
if (id.startsWith("digitalcode-"))
|
|
66
|
-
return "digital-code";
|
|
67
|
-
if (id.startsWith("live-"))
|
|
68
|
-
return "live";
|
|
69
|
-
if (id.startsWith("art-"))
|
|
70
|
-
return "art";
|
|
71
|
-
if (id.startsWith("sticker-"))
|
|
72
|
-
return "stickers";
|
|
73
|
-
if (id.startsWith("product-"))
|
|
74
|
-
return "standard";
|
|
71
|
+
for (const p of PLUGINS) {
|
|
72
|
+
if (p.slugPrefix && id.startsWith(p.slugPrefix))
|
|
73
|
+
return p.listingType;
|
|
74
|
+
}
|
|
75
75
|
return undefined;
|
|
76
76
|
}
|
|
77
77
|
function productTargets(id, hints) {
|
|
78
78
|
const out = [ROUTES.HOME, ROUTES.PUBLIC.PRODUCTS];
|
|
79
|
-
if (!id)
|
|
80
|
-
|
|
79
|
+
if (!id) {
|
|
80
|
+
/*
|
|
81
|
+
* Bulk / unknown write โ a seed load, a purge, or the admin "invalidate
|
|
82
|
+
* everything" button. `/products` alone is not "every listing page": five
|
|
83
|
+
* types are deliberately OUT of the general catalogue
|
|
84
|
+
* (`inGeneralCatalogue: false`) and are reachable only at their own browse
|
|
85
|
+
* route, so a bulk invalidation that marks `/products` leaves `/auctions`,
|
|
86
|
+
* `/pre-orders`, `/prize-draws`, `/art`, `/stickers` and `/spares` serving
|
|
87
|
+
* rows that no longer exist.
|
|
88
|
+
*/
|
|
89
|
+
for (const p of PLUGINS)
|
|
90
|
+
if (p.browseRoute)
|
|
91
|
+
out.push(String(p.browseRoute));
|
|
92
|
+
return Array.from(new Set(out));
|
|
93
|
+
}
|
|
81
94
|
const type = hints?.listingType ?? listingTypeFromId(id);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
const plugin = type ? LISTING_TYPE_REGISTRY[type] : undefined;
|
|
96
|
+
if (plugin) {
|
|
97
|
+
out.push(String(plugin.detailRoute(id)));
|
|
98
|
+
// The type's own browse page. Read off the plugin, NOT derived by stripping
|
|
99
|
+
// the detail route's last segment: art/stickers/spares all detail at
|
|
100
|
+
// `/products/{slug}`, so stripping yields `/products` and loses `/art`,
|
|
101
|
+
// `/stickers` and `/spares` entirely.
|
|
102
|
+
if (plugin.browseRoute)
|
|
103
|
+
out.push(String(plugin.browseRoute));
|
|
88
104
|
}
|
|
89
105
|
else {
|
|
90
106
|
/*
|
|
91
|
-
* Unknown type: revalidate EVERY detail route for this id rather
|
|
92
|
-
* guessing one.
|
|
93
|
-
* until requested โ strictly cheaper than leaving the real one live.
|
|
107
|
+
* Unknown type: revalidate EVERY detail and browse route for this id rather
|
|
108
|
+
* than guessing one. A couple of dozen entries marked stale, none of which
|
|
109
|
+
* renders until requested โ strictly cheaper than leaving the real one live.
|
|
94
110
|
*/
|
|
95
|
-
for (const
|
|
96
|
-
out.push(
|
|
111
|
+
for (const p of PLUGINS) {
|
|
112
|
+
out.push(String(p.detailRoute(id)));
|
|
113
|
+
if (p.browseRoute)
|
|
114
|
+
out.push(String(p.browseRoute));
|
|
115
|
+
}
|
|
97
116
|
}
|
|
98
117
|
// A product's price/stock/status is rendered on every taxonomy page that
|
|
99
118
|
// lists it. `categorySlugs` is the full ancestor chain, so this covers the
|