@mohasinac/appkit 4.53.0 → 4.53.2
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/scaffolds/AppShell.js +1 -1
- package/dist/_internal/client/theme/ThemeProvider.js +15 -1
- package/dist/_internal/server/features/auctions/og.d.ts +3 -1
- package/dist/_internal/server/features/auctions/og.js +3 -1
- package/dist/_internal/server/features/bundles/actions.js +1 -1
- package/dist/_internal/server/features/business-documents/download.d.ts +41 -0
- package/dist/_internal/server/features/business-documents/download.js +91 -0
- package/dist/_internal/server/features/categories/adapters.d.ts +1 -1
- package/dist/_internal/server/features/categories/adapters.js +10 -0
- package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
- package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +14 -0
- package/dist/_internal/server/features/checkout/actions.js +106 -12
- package/dist/_internal/server/features/checkout/bundle-expansion.js +17 -0
- package/dist/_internal/server/features/checkout/data.d.ts +22 -0
- package/dist/_internal/server/features/checkout/group-rule-revalidation.d.ts +34 -0
- package/dist/_internal/server/features/checkout/group-rule-revalidation.js +124 -0
- package/dist/_internal/server/features/checkout/supplier-identity.d.ts +55 -0
- package/dist/_internal/server/features/checkout/supplier-identity.js +81 -0
- package/dist/_internal/server/features/classified/metadata.js +1 -1
- package/dist/_internal/server/features/classified/og.d.ts +3 -1
- package/dist/_internal/server/features/classified/og.js +3 -1
- package/dist/_internal/server/features/digital-code/metadata.js +1 -1
- package/dist/_internal/server/features/digital-code/og.d.ts +3 -1
- package/dist/_internal/server/features/digital-code/og.js +3 -1
- package/dist/_internal/server/features/digital-code/pool.d.ts +19 -4
- package/dist/_internal/server/features/digital-code/pool.js +19 -4
- package/dist/_internal/server/features/live/metadata.js +1 -1
- package/dist/_internal/server/features/live/og.d.ts +3 -1
- package/dist/_internal/server/features/live/og.js +3 -1
- package/dist/_internal/server/features/messages/actions.js +1 -1
- package/dist/_internal/server/features/parts/og.js +1 -1
- package/dist/_internal/server/features/pre-orders/og.d.ts +3 -1
- package/dist/_internal/server/features/pre-orders/og.js +3 -1
- package/dist/_internal/server/features/price-index/market.d.ts +57 -0
- package/dist/_internal/server/features/price-index/market.js +120 -0
- package/dist/_internal/server/features/price-index/search.d.ts +18 -0
- package/dist/_internal/server/features/price-index/search.js +47 -7
- package/dist/_internal/server/features/prize-draws/og.d.ts +3 -1
- package/dist/_internal/server/features/prize-draws/og.js +3 -1
- package/dist/_internal/server/features/products/group-members.d.ts +26 -0
- package/dist/_internal/server/features/products/group-members.js +7 -1
- package/dist/_internal/server/features/products/list-public.d.ts +12 -0
- package/dist/_internal/server/features/products/list-public.js +10 -1
- package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
- package/dist/_internal/server/features/products/listing-tab-counts.js +128 -10
- package/dist/_internal/server/features/products/og.d.ts +3 -1
- package/dist/_internal/server/features/products/og.js +3 -1
- package/dist/_internal/server/features/search/scoped-sources.d.ts +26 -0
- package/dist/_internal/server/features/search/scoped-sources.js +252 -0
- package/dist/_internal/server/features/search/search-everything.d.ts +57 -0
- package/dist/_internal/server/features/search/search-everything.js +70 -20
- package/dist/_internal/server/features/seo/sitemap.js +6 -0
- package/dist/_internal/server/features/shared/listing-adapters.js +4 -2
- package/dist/_internal/server/features/sticker-trace/adapters.d.ts +11 -0
- package/dist/_internal/server/features/sticker-trace/adapters.js +1 -0
- package/dist/_internal/server/features/sticker-trace/promote-to-listings.d.ts +26 -0
- package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +264 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +3 -1
- package/dist/_internal/server/features/sticker-trace/sheet-actions.js +32 -0
- package/dist/_internal/server/features/sticker-trace/storage.d.ts +20 -1
- package/dist/_internal/server/features/sticker-trace/storage.js +20 -1
- package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
- package/dist/_internal/server/features/stores/adapters.js +16 -0
- package/dist/_internal/server/features/stores/index.d.ts +1 -0
- package/dist/_internal/server/features/stores/index.js +1 -0
- package/dist/_internal/server/features/stores/tabs.d.ts +30 -0
- package/dist/_internal/server/features/stores/tabs.js +124 -0
- package/dist/_internal/shared/checkout/rules/_defaults.js +0 -2
- package/dist/_internal/shared/checkout/rules/_limits.d.ts +14 -1
- package/dist/_internal/shared/checkout/rules/_limits.js +14 -1
- package/dist/_internal/shared/checkout/rules/_registry.js +2 -0
- package/dist/_internal/shared/checkout/rules/auction.rule.js +9 -1
- package/dist/_internal/shared/checkout/rules/bundle.rule.js +13 -0
- package/dist/_internal/shared/checkout/rules/index.d.ts +2 -0
- package/dist/_internal/shared/checkout/rules/index.js +9 -0
- package/dist/_internal/shared/checkout/rules/offer.rule.js +0 -1
- package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +26 -0
- package/dist/_internal/shared/checkout/rules/payment-gate.js +133 -0
- package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +29 -8
- package/dist/_internal/shared/checkout/rules/spares.rule.d.ts +16 -0
- package/dist/_internal/shared/checkout/rules/spares.rule.js +5 -0
- package/dist/_internal/shared/checkout/rules/types.d.ts +26 -2
- package/dist/_internal/shared/config/schema.d.ts +122 -0
- package/dist/_internal/shared/features/cart/schema.js +3 -2
- package/dist/_internal/shared/features/products/group-rules.d.ts +75 -0
- package/dist/_internal/shared/features/products/group-rules.js +142 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +24 -0
- package/dist/_internal/shared/listing-types/_registry.js +39 -1
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/art/config.js +2 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/config.js +2 -0
- package/dist/_internal/shared/listing-types/availability.js +48 -0
- package/dist/_internal/shared/listing-types/capabilities.js +19 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/classified/config.js +2 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +2 -0
- package/dist/_internal/shared/listing-types/feature-flags.js +1 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/live/config.js +2 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +2 -0
- package/dist/_internal/shared/listing-types/spares/config.d.ts +74 -0
- package/dist/_internal/shared/listing-types/spares/config.js +60 -0
- package/dist/_internal/shared/listing-types/spares/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/spares/ctas.js +4 -0
- package/dist/_internal/shared/listing-types/spares/og.js +1 -0
- package/dist/_internal/shared/listing-types/spares/schema.d.ts +2 -0
- package/dist/_internal/shared/listing-types/spares/schema.js +3 -0
- package/dist/_internal/shared/listing-types/spares/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/spares/seed-factory.js +1 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/config.js +2 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
- package/dist/_internal/shared/search/match.d.ts +11 -0
- package/dist/_internal/shared/search/match.js +30 -3
- package/dist/_internal/shared/search/to-groups.d.ts +52 -0
- package/dist/_internal/shared/search/to-groups.js +141 -0
- package/dist/client.d.ts +8 -2
- package/dist/client.js +4 -1
- package/dist/constants/api-endpoints.d.ts +46 -15
- package/dist/constants/api-endpoints.js +35 -5
- package/dist/constants/cache-invalidation.js +3 -1
- package/dist/constants/field-names.d.ts +6 -0
- package/dist/constants/field-names.js +6 -0
- package/dist/features/about/components/PolicyPageView.d.ts +22 -2
- package/dist/features/about/components/PolicyPageView.js +14 -2
- package/dist/features/about/components/PublicProfileView.js +2 -1
- package/dist/features/about/components/ShippingPolicyView.js +42 -2
- package/dist/features/account/components/NotificationBell.js +1 -1
- package/dist/features/account/hooks/useProfileStats.js +5 -1
- package/dist/features/addresses/repository/addresses.repository.d.ts +16 -0
- package/dist/features/addresses/repository/addresses.repository.js +21 -0
- package/dist/features/admin/actions/admin-actions.js +16 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +19 -2
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminPageHeader.js +1 -1
- package/dist/features/admin/components/AdminProductEditorView.js +17 -2
- package/dist/features/admin/components/AdminSidebar.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +39 -8
- package/dist/features/admin/components/AdminSparesView.d.ts +12 -0
- package/dist/features/admin/components/AdminSparesView.js +30 -0
- package/dist/features/admin/components/AdminUsersView.js +9 -7
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +7 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
- package/dist/features/admin/constants/filter-tabs.js +1 -0
- package/dist/features/admin/schemas/firestore.d.ts +26 -2
- package/dist/features/auctions/components/AuctionDetailPageView.js +12 -18
- package/dist/features/auth/repository/user.repository.d.ts +13 -0
- package/dist/features/auth/repository/user.repository.js +28 -0
- package/dist/features/auth/schemas/firestore.d.ts +2 -0
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/business-documents/repository/business-documents.repository.d.ts +58 -0
- package/dist/features/business-documents/repository/business-documents.repository.js +54 -0
- package/dist/features/business-documents/schemas/firestore.d.ts +105 -0
- package/dist/features/business-documents/schemas/firestore.js +75 -0
- package/dist/features/cart/actions/cart-actions.js +83 -6
- package/dist/features/cart/repository/cart.repository.js +32 -4
- package/dist/features/cart/schemas/firestore.d.ts +20 -0
- package/dist/features/cart/schemas/index.d.ts +2 -2
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +1 -1
- package/dist/features/categories/api/[id]/price-guidance/route.d.ts +42 -0
- package/dist/features/categories/api/[id]/price-guidance/route.js +90 -0
- package/dist/features/categories/components/BrandDetailPageView.js +32 -8
- package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/BrandDetailTabs.js +28 -3
- package/dist/features/categories/components/BundleCollage.js +3 -2
- package/dist/features/categories/components/BundleItemsPicker.js +3 -4
- package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
- package/dist/features/categories/components/CategoryDetailPageView.js +157 -20
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +41 -7
- package/dist/features/categories/components/CategoryGrid.js +10 -1
- package/dist/features/categories/components/PriceGuidanceHint.d.ts +29 -0
- package/dist/features/categories/components/PriceGuidanceHint.js +61 -0
- package/dist/features/categories/components/SubcategoryCardRow.d.ts +27 -0
- package/dist/features/categories/components/SubcategoryCardRow.js +98 -0
- package/dist/features/categories/constants/category-tabs.d.ts +20 -25
- package/dist/features/categories/constants/category-tabs.js +22 -39
- package/dist/features/categories/repository/categories.repository.d.ts +12 -0
- package/dist/features/categories/repository/categories.repository.js +20 -0
- package/dist/features/categories/schemas/firestore.d.ts +22 -1
- package/dist/features/categories/schemas/firestore.js +10 -0
- package/dist/features/categories/schemas/index.d.ts +6 -0
- package/dist/features/categories/schemas/index.js +2 -0
- package/dist/features/categories/types/index.d.ts +8 -0
- package/dist/features/categories/utils/taxonomy-visual.d.ts +16 -3
- package/dist/features/categories/utils/taxonomy-visual.js +26 -10
- package/dist/features/classified/components/ClassifiedDetailPageView.js +14 -10
- package/dist/features/contact/components/ContactPageView.d.ts +33 -1
- package/dist/features/contact/components/ContactPageView.js +58 -28
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +14 -10
- package/dist/features/grouped/components/GroupedListingDetailView.js +9 -1
- package/dist/features/grouped/schemas/firestore.d.ts +5 -0
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +3 -3
- package/dist/features/homepage/components/CollectionCardsSection.d.ts +28 -6
- package/dist/features/homepage/components/CollectionCardsSection.js +43 -8
- package/dist/features/homepage/components/HowItWorksSection.d.ts +23 -6
- package/dist/features/homepage/components/HowItWorksSection.js +4 -4
- package/dist/features/homepage/components/PromoGrid.d.ts +31 -2
- package/dist/features/homepage/components/PromoGrid.js +12 -3
- package/dist/features/homepage/components/TestimonialsCarousel.d.ts +34 -2
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/index.d.ts +0 -20
- package/dist/features/homepage/components/index.js +0 -11
- package/dist/features/homepage/index.d.ts +0 -2
- package/dist/features/homepage/index.js +0 -2
- package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
- package/dist/features/homepage/lib/section-renderer.js +202 -58
- package/dist/features/homepage/repository/homepage-sections.repository.d.ts +35 -3
- package/dist/features/homepage/repository/homepage-sections.repository.js +58 -8
- package/dist/features/homepage/schemas/firestore.d.ts +106 -3
- package/dist/features/homepage/schemas/firestore.js +32 -2
- package/dist/features/homepage/schemas/index.d.ts +36 -7
- package/dist/features/homepage/schemas/index.js +39 -27
- package/dist/features/homepage/server.d.ts +0 -3
- package/dist/features/homepage/server.js +0 -3
- package/dist/features/homepage/types/index.d.ts +0 -47
- package/dist/features/homepage/types/index.js +49 -0
- package/dist/features/layout/AppLayoutShell.js +1 -1
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/TitleBarLayout.js +1 -1
- package/dist/features/live/components/LiveItemDetailPageView.js +14 -10
- package/dist/features/media/hooks/useMedia.js +17 -0
- package/dist/features/media/repository/media-assets.repository.d.ts +46 -0
- package/dist/features/media/repository/media-assets.repository.js +31 -0
- package/dist/features/media/trust-signals.d.ts +85 -0
- package/dist/features/media/trust-signals.js +126 -0
- package/dist/features/parts/components/PartDetailPageView.d.ts +14 -1
- package/dist/features/parts/components/PartDetailPageView.js +2 -2
- package/dist/features/parts/components/PartsIndexPageView.d.ts +11 -2
- package/dist/features/parts/components/PartsIndexPageView.js +2 -2
- package/dist/features/parts/components/PartsSearchBox.d.ts +9 -0
- package/dist/features/parts/components/PartsSearchBox.js +57 -0
- package/dist/features/parts/schemas/firestore.d.ts +149 -3
- package/dist/features/parts/schemas/firestore.js +184 -0
- package/dist/features/payments/repository/payout.repository.d.ts +15 -0
- package/dist/features/payments/repository/payout.repository.js +21 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -18
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +24 -1
- package/dist/features/price-index/components/PriceIndexToolView.js +299 -17
- package/dist/features/price-index/lookup-target.d.ts +48 -0
- package/dist/features/price-index/lookup-target.js +107 -0
- package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
- package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
- package/dist/features/products/components/CompareOverlay.d.ts +20 -2
- package/dist/features/products/components/CompareOverlay.js +23 -3
- package/dist/features/products/components/CustomSectionTabContent.d.ts +31 -0
- package/dist/features/products/components/CustomSectionTabContent.js +29 -3
- package/dist/features/products/components/GroupMemberPicker.d.ts +19 -1
- package/dist/features/products/components/GroupMemberPicker.js +46 -8
- package/dist/features/products/components/GroupSettingsPanel.d.ts +11 -1
- package/dist/features/products/components/GroupSettingsPanel.js +92 -3
- package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
- package/dist/features/products/components/PrizeDrawEntryActions.d.ts +15 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +70 -8
- package/dist/features/products/components/ProductDetailPageView.js +81 -17
- package/dist/features/products/components/ProductForm.d.ts +13 -1
- package/dist/features/products/components/ProductForm.js +16 -2
- package/dist/features/products/components/ProductsIndexListing.d.ts +16 -1
- package/dist/features/products/components/ProductsIndexListing.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +15 -2
- package/dist/features/products/components/SparesListView.d.ts +7 -0
- package/dist/features/products/components/SparesListView.js +39 -0
- package/dist/features/products/components/SublistingCarouselSection.js +2 -1
- package/dist/features/products/constants/action-defs.d.ts +1 -0
- package/dist/features/products/constants/action-defs.js +1 -0
- package/dist/features/products/repository/products.repository.d.ts +99 -0
- package/dist/features/products/repository/products.repository.js +240 -18
- package/dist/features/products/schemas/firestore.d.ts +97 -4
- package/dist/features/products/schemas/firestore.js +104 -0
- package/dist/features/products/schemas/index.d.ts +10 -19
- package/dist/features/products/schemas/index.js +23 -6
- package/dist/features/products/types/index.d.ts +45 -1
- package/dist/features/products/utils/group-member-image.d.ts +46 -0
- package/dist/features/products/utils/group-member-image.js +4 -0
- package/dist/features/products/utils/listing-badge-variant.js +4 -0
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/components/ScamProfileView.js +1 -1
- package/dist/features/search/components/EntityTypeahead.d.ts +44 -0
- package/dist/features/search/components/EntityTypeahead.js +92 -0
- package/dist/features/search/components/Search.d.ts +12 -1
- package/dist/features/search/components/Search.js +47 -3
- package/dist/features/search/components/SearchFacetRail.d.ts +11 -0
- package/dist/features/search/components/SearchFacetRail.js +92 -0
- package/dist/features/search/components/SearchResultsClient.d.ts +33 -0
- package/dist/features/search/components/SearchResultsClient.js +103 -0
- package/dist/features/search/components/SearchResultsPageView.d.ts +15 -1
- package/dist/features/search/components/SearchResultsPageView.js +2 -2
- package/dist/features/search/components/index.d.ts +0 -6
- package/dist/features/search/components/index.js +0 -3
- package/dist/features/search/hooks/useNavSuggestions.d.ts +13 -0
- package/dist/features/search/hooks/useScopedSearch.d.ts +34 -0
- package/dist/features/search/hooks/useScopedSearch.js +114 -0
- package/dist/features/search/hooks/useSiteSearch.d.ts +26 -0
- package/dist/features/search/hooks/useSiteSearch.js +149 -0
- package/dist/features/search/index.d.ts +0 -4
- package/dist/features/search/index.js +0 -4
- package/dist/features/search/manifest.d.ts +12 -0
- package/dist/features/search/manifest.js +17 -2
- package/dist/features/search/server.d.ts +0 -3
- package/dist/features/search/server.js +0 -3
- package/dist/features/seller/components/SellerListingTypeView.d.ts +1 -1
- package/dist/features/seller/components/SellerListingTypeView.js +20 -0
- package/dist/features/seller/components/SellerPayoutSettingsView.js +35 -14
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductShell.js +2 -1
- package/dist/features/seller/components/SellerProductsView.js +3 -2
- package/dist/features/seller/components/SellerSidebar.js +1 -1
- package/dist/features/seller/components/SellerSparesView.d.ts +17 -0
- package/dist/features/seller/components/SellerSparesView.js +6 -0
- package/dist/features/seller/components/index.d.ts +2 -0
- package/dist/features/seller/components/index.js +1 -0
- package/dist/features/shell/CommandPalette.js +1 -1
- package/dist/features/sticker-trace/schemas/firestore.d.ts +19 -0
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -82
- package/dist/features/stores/components/StoreHeader.js +1 -2
- package/dist/features/stores/components/StoreSparesPageView.d.ts +27 -0
- package/dist/features/stores/components/StoreSparesPageView.js +48 -0
- package/dist/features/stores/schemas/firestore.d.ts +19 -0
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +96 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +392 -45
- package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +54 -32
- package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +3 -2
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +73 -0
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +340 -0
- package/dist/features/tester/seed-data/authored/index.js +16 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +1 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +57 -0
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +77 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +58 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +5 -4
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +384 -18
- package/dist/index.d.ts +17 -57
- package/dist/index.js +35 -96
- package/dist/next/routing/route-map.d.ts +42 -1
- package/dist/next/routing/route-map.js +45 -0
- package/dist/providers/db-firebase/base.repository.d.ts +22 -0
- package/dist/providers/db-firebase/base.repository.js +36 -0
- package/dist/schemas/registry.d.ts +15 -6
- package/dist/security/blind-index-tokens.d.ts +54 -0
- package/dist/security/blind-index-tokens.js +152 -0
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/settings-encryption.d.ts +35 -0
- package/dist/security/settings-encryption.js +91 -0
- package/dist/seed/_helpers/brand-rows.js +38 -14
- package/dist/seed/_helpers/category-forest.js +73 -7
- package/dist/seed/_helpers/category-images-generated.d.ts +25 -6
- package/dist/seed/_helpers/category-images-generated.js +81 -6
- package/dist/seed/_helpers/category-models.d.ts +1 -1
- package/dist/seed/_helpers/category-models.js +7 -1
- package/dist/seed/_helpers/category-parts-glossary-map.js +8 -0
- package/dist/seed/_helpers/category-parts.d.ts +1 -1
- package/dist/seed/_helpers/category-parts.js +50 -2
- package/dist/seed/_helpers/character-features.d.ts +1 -1
- package/dist/seed/_helpers/character-features.js +2 -1
- package/dist/seed/_helpers/franchise-rows.js +10 -2
- package/dist/seed/_helpers/media.d.ts +47 -0
- package/dist/seed/_helpers/media.js +34 -0
- package/dist/seed/authenticity-knowledge-seed-data.d.ts +49 -5
- package/dist/seed/authenticity-knowledge-seed-data.js +10001 -549
- package/dist/seed/categories-seed-data.js +124 -20
- package/dist/seed/grouped-listings-seed-data.js +16 -0
- package/dist/seed/homepage-sections-seed-data.js +94 -5
- package/dist/seed/index.d.ts +2 -3
- package/dist/seed/index.js +2 -2
- package/dist/seed/manifest.js +3 -0
- package/dist/seed/media-assets-seed-data.d.ts +1 -1
- package/dist/seed/media-assets-seed-data.js +746 -196
- package/dist/seed/model-composition-seed-data.js +122 -6
- package/dist/seed/part-glossary-seed-data.d.ts +1 -1
- package/dist/seed/part-glossary-seed-data.js +37219 -463
- package/dist/seed/products-art-seed-data.js +7 -18
- package/dist/seed/products-auctions-seed-data.js +56 -47
- package/dist/seed/products-beyblade-x-seed-data.d.ts +2 -0
- package/dist/seed/products-beyblade-x-seed-data.js +476 -0
- package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
- package/dist/seed/products-catalogue-seed-data.js +1500 -1240
- package/dist/seed/products-classifieds-seed-data.js +9 -27
- package/dist/seed/products-digital-codes-seed-data.js +9 -18
- package/dist/seed/products-live-items-seed-data.js +5 -13
- package/dist/seed/products-preorders-seed-data.js +67 -33
- package/dist/seed/products-prize-draws-seed-data.js +8 -17
- package/dist/seed/products-spares-seed-data.d.ts +2 -0
- package/dist/seed/products-spares-seed-data.js +368 -0
- package/dist/seed/products-standard-seed-data.js +39 -126
- package/dist/seed/products-stickers-seed-data.js +59 -15
- package/dist/seed/site-settings-seed-data.js +8 -0
- package/dist/seo/json-ld.d.ts +25 -0
- package/dist/seo/json-ld.js +28 -0
- package/dist/server-entry.d.ts +3 -1
- package/dist/server-entry.js +2 -2
- package/dist/server.d.ts +11 -9
- package/dist/server.js +35 -25
- package/dist/styles.css +202 -1
- package/dist/tailwind-input.css +31 -17
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Accordion.js +1 -1
- package/dist/ui/components/Breadcrumb.js +1 -1
- package/dist/ui/components/DetailPageGallery.js +0 -2
- package/dist/ui/components/DetailPageHero.js +0 -1
- package/dist/ui/components/DetailPageTabs.js +1 -1
- package/dist/ui/components/Divider.js +3 -3
- package/dist/ui/components/GatedPrice.js +5 -1
- package/dist/ui/components/HorizontalScroller.js +1 -1
- package/dist/ui/components/ListingLayout.js +3 -3
- package/dist/ui/components/MediaTabs.style.css +81 -0
- package/dist/ui/components/Pagination.js +1 -1
- package/dist/ui/components/PendingValue.d.ts +45 -0
- package/dist/ui/components/PendingValue.js +7 -0
- package/dist/ui/components/Radio.style.css +119 -0
- package/dist/ui/components/RatingDisplay.js +2 -2
- package/dist/ui/components/SettingsSection.js +0 -2
- package/dist/ui/components/SiteLogo.js +3 -0
- package/dist/ui/components/SiteMark.js +3 -0
- package/dist/ui/components/SortDropdown.js +1 -1
- package/dist/ui/components/SpecTable.d.ts +58 -0
- package/dist/ui/components/SpecTable.js +8 -0
- package/dist/ui/components/StarRating.js +1 -3
- package/dist/ui/components/SummaryCard.js +1 -1
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/icons/icon-registry.d.ts +1 -0
- package/dist/ui/icons/icon-registry.js +9 -1
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +2 -0
- package/dist/utils/search-txt-query.d.ts +12 -0
- package/dist/utils/search-txt-query.js +12 -0
- package/package.json +1 -1
- package/scripts/dedupe-peer-deps.mjs +18 -0
- package/scripts/seed-cli.mjs +250 -35
- package/scripts/verify-css-build.mjs +118 -37
- package/dist/_internal/server/features/search/actions.d.ts +0 -7
- package/dist/_internal/server/features/search/actions.js +0 -21
- package/dist/_internal/server/features/search/data.d.ts +0 -15
- package/dist/_internal/server/features/search/data.js +0 -18
- package/dist/_internal/server/features/search/index.d.ts +0 -3
- package/dist/_internal/server/features/search/index.js +0 -2
- package/dist/features/homepage/api/[id]/route.d.ts +0 -23
- package/dist/features/homepage/api/[id]/route.js +0 -103
- package/dist/features/homepage/api/route.d.ts +0 -14
- package/dist/features/homepage/api/route.js +0 -140
- package/dist/features/homepage/api/sections/[id]/route.d.ts +0 -26
- package/dist/features/homepage/api/sections/[id]/route.js +0 -95
- package/dist/features/homepage/api/sections/route.d.ts +0 -13
- package/dist/features/homepage/api/sections/route.js +0 -82
- package/dist/features/homepage/components/AdvertisementBanner.d.ts +0 -14
- package/dist/features/homepage/components/AdvertisementBanner.js +0 -35
- package/dist/features/homepage/components/BeforeAfterCard.d.ts +0 -9
- package/dist/features/homepage/components/BeforeAfterCard.js +0 -73
- package/dist/features/homepage/components/FeaturedResultsSection.d.ts +0 -17
- package/dist/features/homepage/components/FeaturedResultsSection.js +0 -17
- package/dist/features/homepage/components/HeroBanner.d.ts +0 -7
- package/dist/features/homepage/components/HeroBanner.js +0 -43
- package/dist/features/homepage/components/HeroSection.d.ts +0 -7
- package/dist/features/homepage/components/HeroSection.js +0 -6
- package/dist/features/homepage/components/HomepageSkeleton.d.ts +0 -2
- package/dist/features/homepage/components/HomepageSkeleton.js +0 -21
- package/dist/features/homepage/components/HomepageView.d.ts +0 -25
- package/dist/features/homepage/components/HomepageView.js +0 -5
- package/dist/features/homepage/components/NewsletterBanner.d.ts +0 -23
- package/dist/features/homepage/components/NewsletterBanner.js +0 -37
- package/dist/features/homepage/components/SiteFeaturesSection.d.ts +0 -14
- package/dist/features/homepage/components/SiteFeaturesSection.js +0 -11
- package/dist/features/homepage/components/TrustBadges.d.ts +0 -6
- package/dist/features/homepage/components/TrustBadges.js +0 -46
- package/dist/features/homepage/components/TrustIndicatorsSection.d.ts +0 -12
- package/dist/features/homepage/components/TrustIndicatorsSection.js +0 -11
- package/dist/features/homepage/hooks/useHomepage.d.ts +0 -11
- package/dist/features/homepage/hooks/useHomepage.js +0 -17
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +0 -2
- package/dist/features/homepage/hooks/useHomepageSections.js +0 -10
- package/dist/features/homepage/repository/homepage.repository.d.ts +0 -11
- package/dist/features/homepage/repository/homepage.repository.js +0 -25
- package/dist/features/search/actions/index.d.ts +0 -1
- package/dist/features/search/actions/index.js +0 -1
- package/dist/features/search/actions/search-actions.d.ts +0 -18
- package/dist/features/search/actions/search-actions.js +0 -43
- package/dist/features/search/api/route.d.ts +0 -22
- package/dist/features/search/api/route.js +0 -128
- package/dist/features/search/columns/index.d.ts +0 -17
- package/dist/features/search/columns/index.js +0 -49
- package/dist/features/search/components/SearchFiltersRow.d.ts +0 -22
- package/dist/features/search/components/SearchFiltersRow.js +0 -21
- package/dist/features/search/components/SearchResultsSection.d.ts +0 -53
- package/dist/features/search/components/SearchResultsSection.js +0 -35
- package/dist/features/search/components/SearchView.d.ts +0 -27
- package/dist/features/search/components/SearchView.js +0 -8
- package/dist/features/search/hooks/useSearch.d.ts +0 -21
- package/dist/features/search/hooks/useSearch.js +0 -33
- package/dist/features/search/repository/search.repository.d.ts +0 -14
- package/dist/features/search/repository/search.repository.js +0 -59
- package/dist/features/search/schemas/index.d.ts +0 -70
- package/dist/features/search/schemas/index.js +0 -36
- package/dist/features/search/types/index.d.ts +0 -48
- package/dist/features/stores/components/StoreScopedSearch.d.ts +0 -17
- package/dist/features/stores/components/StoreScopedSearch.js +0 -27
- package/dist/seed/defaults/homepage-sections.d.ts +0 -2
- package/dist/seed/defaults/homepage-sections.js +0 -60
- package/dist/seed/factories/homepage-section.factory.d.ts +0 -10
- package/dist/seed/factories/homepage-section.factory.js +0 -13
- /package/dist/{features/search/types/index.js → _internal/shared/listing-types/spares/og.d.ts} +0 -0
package/dist/.build-stamp.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"stampVersion": 1,
|
|
3
|
-
"version": "4.53.
|
|
4
|
-
"head": "
|
|
3
|
+
"version": "4.53.2",
|
|
4
|
+
"head": "94f4715428f35ab362a11a468072ef933ca8a46d",
|
|
5
5
|
"branch": "main",
|
|
6
6
|
"dirty": false,
|
|
7
|
-
"builtAt": "2026-10-
|
|
7
|
+
"builtAt": "2026-10-19T22:24:09.397Z"
|
|
8
8
|
}
|
|
@@ -6,5 +6,5 @@ export function AppShell({ children, slotHeader, slotFooter, slotSidebar, render
|
|
|
6
6
|
const header = renderHeader ? renderHeader(ctx) : slotHeader;
|
|
7
7
|
const footer = renderFooter ? renderFooter(ctx) : slotFooter;
|
|
8
8
|
const sidebar = renderSidebar ? renderSidebar(ctx) : slotSidebar;
|
|
9
|
-
return (_jsxs(Stack, { className: `
|
|
9
|
+
return (_jsxs(Stack, { className: `min-h-screen ${className ?? ""}`, children: [header ? (_jsx(BlockHeader, { className: "sticky top-0 z-30 w-full", "data-appshell-slot": "header", children: header })) : null, _jsxs(Div, { layout: "flex", className: "flex-1", children: [sidebar ? (_jsx(Aside, { className: "hidden lg:block lg:w-64 lg:shrink-0", "data-appshell-slot": "sidebar", children: sidebar })) : null, _jsx(Main, { className: "min-w-0 flex-1", "data-appshell-slot": "main", children: children })] }), footer ? (_jsx(BlockFooter, { className: "w-full", "data-appshell-slot": "footer", children: footer })) : null] }));
|
|
10
10
|
}
|
|
@@ -20,7 +20,21 @@ function readModePreference() {
|
|
|
20
20
|
catch (_err) {
|
|
21
21
|
void normalizeError(_err); /* localStorage unavailable in privacy/iframe context */
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
/*
|
|
24
|
+
* 🛑 LIGHT, not "auto" — a product decision, not a technical one.
|
|
25
|
+
*
|
|
26
|
+
* "auto" follows `prefers-color-scheme`, and most phones and an increasing
|
|
27
|
+
* share of desktops now report dark. That made dark the de-facto default
|
|
28
|
+
* for a storefront whose product photography is shot on white: every
|
|
29
|
+
* listing tile rendered a bright cut-out against a near-black card, which
|
|
30
|
+
* is the opposite of how the catalogue was designed to read.
|
|
31
|
+
*
|
|
32
|
+
* This changes the DEFAULT only. A visitor who has chosen either mode has
|
|
33
|
+
* "light"/"dark"/"auto" in localStorage and is returned above, untouched —
|
|
34
|
+
* including anyone who deliberately picked "auto". The dark theme itself is
|
|
35
|
+
* unchanged and one click away.
|
|
36
|
+
*/
|
|
37
|
+
return "light";
|
|
24
38
|
}
|
|
25
39
|
function resolveEffectiveMode(preference) {
|
|
26
40
|
if (preference === "light" || preference === "dark")
|
|
@@ -8,7 +8,9 @@ interface AuctionDocLike {
|
|
|
8
8
|
title?: string | null;
|
|
9
9
|
auctionEndDate?: Date | string | null;
|
|
10
10
|
mainImage?: string | null;
|
|
11
|
-
images?: (
|
|
11
|
+
images?: ({
|
|
12
|
+
url: string;
|
|
13
|
+
} | string | null | undefined)[] | null;
|
|
12
14
|
}
|
|
13
15
|
/** High-level OG renderer — accepts the raw auction document from `getAuctionForDetail`. */
|
|
14
16
|
export declare function renderAuctionOg(doc: AuctionDocLike | null | undefined, opts: {
|
|
@@ -14,7 +14,9 @@ export function renderAuctionOg(doc, opts) {
|
|
|
14
14
|
return renderAuctionOgImage({
|
|
15
15
|
title: doc?.title ?? "Live Auction",
|
|
16
16
|
endsLabel,
|
|
17
|
-
imageUrl: resolveOgImageUrl(doc?.mainImage ||
|
|
17
|
+
imageUrl: resolveOgImageUrl(doc?.mainImage ||
|
|
18
|
+
(typeof doc?.images?.[0] === "string" ? doc.images[0] : doc?.images?.[0]?.url) ||
|
|
19
|
+
null, opts.baseUrl),
|
|
18
20
|
}, opts.siteName);
|
|
19
21
|
}
|
|
20
22
|
export function renderAuctionOgImage(data, siteName) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a statutory business document — GST certificate, Udyam registration,
|
|
3
|
+
* bank passbook — and decrypts it for an admin.
|
|
4
|
+
*
|
|
5
|
+
* 🛑 WHY THIS EXISTS rather than a `/media/{slug}` URL. Same two facts that
|
|
6
|
+
* forced `digital-code/download.ts` into the same shape, and either alone is
|
|
7
|
+
* enough:
|
|
8
|
+
*
|
|
9
|
+
* 1. `storage.rules` grants `allow read: if true` on EVERY object in the
|
|
10
|
+
* bucket. All real access goes through the Admin SDK, so that is an
|
|
11
|
+
* acceptable safety net — but it means Storage itself protects nothing.
|
|
12
|
+
* 2. `GET /api/media/[...slug]` performs NO authentication. It is a bare
|
|
13
|
+
* handler with no session read, deliberately, because its job is public
|
|
14
|
+
* product photography.
|
|
15
|
+
*
|
|
16
|
+
* So the bytes live under a private prefix that mints no `mediaAssets` row —
|
|
17
|
+
* and the row IS the public slug, so no row means no public URL — and are read
|
|
18
|
+
* only from here, after the route has checked the caller is an admin.
|
|
19
|
+
*
|
|
20
|
+
* On top of that, and unlike the digital-code case, these objects are stored
|
|
21
|
+
* ENCRYPTED: a bank passbook sitting in plaintext in a bucket whose rules say
|
|
22
|
+
* `read: if true` would depend entirely on nobody ever minting a slug for it.
|
|
23
|
+
*/
|
|
24
|
+
export interface BusinessDocumentResolution {
|
|
25
|
+
ok: boolean;
|
|
26
|
+
status?: number;
|
|
27
|
+
message?: string;
|
|
28
|
+
buffer?: Buffer;
|
|
29
|
+
contentType?: string;
|
|
30
|
+
fileName?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolve, download and decrypt the document with id `documentId`.
|
|
34
|
+
*
|
|
35
|
+
* The caller is responsible for the authorization check — the route wraps this
|
|
36
|
+
* in `createRouteHandler({ roles: ROLES_ADMIN_ONLY, permission: "settings:write" })`.
|
|
37
|
+
* This function deliberately takes no viewer: there is no per-row ownership to
|
|
38
|
+
* evaluate, so inventing a `viewerUid` parameter it never reads would imply a
|
|
39
|
+
* check that is not happening here.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveBusinessDocument(documentId: string): Promise<BusinessDocumentResolution>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a statutory business document — GST certificate, Udyam registration,
|
|
3
|
+
* bank passbook — and decrypts it for an admin.
|
|
4
|
+
*
|
|
5
|
+
* 🛑 WHY THIS EXISTS rather than a `/media/{slug}` URL. Same two facts that
|
|
6
|
+
* forced `digital-code/download.ts` into the same shape, and either alone is
|
|
7
|
+
* enough:
|
|
8
|
+
*
|
|
9
|
+
* 1. `storage.rules` grants `allow read: if true` on EVERY object in the
|
|
10
|
+
* bucket. All real access goes through the Admin SDK, so that is an
|
|
11
|
+
* acceptable safety net — but it means Storage itself protects nothing.
|
|
12
|
+
* 2. `GET /api/media/[...slug]` performs NO authentication. It is a bare
|
|
13
|
+
* handler with no session read, deliberately, because its job is public
|
|
14
|
+
* product photography.
|
|
15
|
+
*
|
|
16
|
+
* So the bytes live under a private prefix that mints no `mediaAssets` row —
|
|
17
|
+
* and the row IS the public slug, so no row means no public URL — and are read
|
|
18
|
+
* only from here, after the route has checked the caller is an admin.
|
|
19
|
+
*
|
|
20
|
+
* On top of that, and unlike the digital-code case, these objects are stored
|
|
21
|
+
* ENCRYPTED: a bank passbook sitting in plaintext in a bucket whose rules say
|
|
22
|
+
* `read: if true` would depend entirely on nobody ever minting a slug for it.
|
|
23
|
+
*/
|
|
24
|
+
import { getAdminStorage } from "../../../../providers/db-firebase/index.js";
|
|
25
|
+
import { normalizeError } from "../../../../errors/normalize.js";
|
|
26
|
+
import { decryptBuffer, isBufferEncrypted } from "../../../../security/settings-encryption.js";
|
|
27
|
+
import { businessDocumentsRepository } from "../../../../features/business-documents/repository/business-documents.repository.js";
|
|
28
|
+
/**
|
|
29
|
+
* Resolve, download and decrypt the document with id `documentId`.
|
|
30
|
+
*
|
|
31
|
+
* The caller is responsible for the authorization check — the route wraps this
|
|
32
|
+
* in `createRouteHandler({ roles: ROLES_ADMIN_ONLY, permission: "settings:write" })`.
|
|
33
|
+
* This function deliberately takes no viewer: there is no per-row ownership to
|
|
34
|
+
* evaluate, so inventing a `viewerUid` parameter it never reads would imply a
|
|
35
|
+
* check that is not happening here.
|
|
36
|
+
*/
|
|
37
|
+
export async function resolveBusinessDocument(documentId) {
|
|
38
|
+
const record = await businessDocumentsRepository.findById(documentId);
|
|
39
|
+
if (!record) {
|
|
40
|
+
return { ok: false, status: 404, message: "Document not found" };
|
|
41
|
+
}
|
|
42
|
+
let stored;
|
|
43
|
+
try {
|
|
44
|
+
const file = getAdminStorage().bucket().file(record.storagePath);
|
|
45
|
+
const [buffer] = await file.download();
|
|
46
|
+
stored = buffer;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
void normalizeError(err);
|
|
50
|
+
return { ok: false, status: 404, message: "Document is no longer available" };
|
|
51
|
+
}
|
|
52
|
+
/*
|
|
53
|
+
* Branch on the RECORDED flag, never on sniffing the buffer.
|
|
54
|
+
*
|
|
55
|
+
* `isBufferEncrypted` is used only to catch disagreement: a row that claims
|
|
56
|
+
* encryption over an object that has none means the upload half-failed or
|
|
57
|
+
* the object was replaced by hand, and handing those bytes back as though
|
|
58
|
+
* nothing were wrong is how a plaintext passbook gets served while every log
|
|
59
|
+
* line says it was encrypted. Refuse and say which way the mismatch runs.
|
|
60
|
+
*/
|
|
61
|
+
if (record.encrypted !== isBufferEncrypted(stored)) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
status: 500,
|
|
65
|
+
message: record.encrypted
|
|
66
|
+
? "Stored document is not encrypted but its record says it is — refusing to serve it."
|
|
67
|
+
: "Stored document is encrypted but its record says it is not — refusing to guess.",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
let plaintext;
|
|
71
|
+
if (record.encrypted) {
|
|
72
|
+
try {
|
|
73
|
+
plaintext = decryptBuffer(stored);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
// A GCM auth failure means the wrong key or a tampered object. Both are
|
|
77
|
+
// worth a 500 and a log; neither is worth telling the caller which.
|
|
78
|
+
void normalizeError(err);
|
|
79
|
+
return { ok: false, status: 500, message: "Document could not be decrypted" };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
plaintext = stored;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
ok: true,
|
|
87
|
+
buffer: plaintext,
|
|
88
|
+
contentType: record.contentType || "application/octet-stream",
|
|
89
|
+
fileName: record.fileName || "document",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -31,7 +31,7 @@ import type { CategoryItem } from "../../../../features/categories/types/index";
|
|
|
31
31
|
* the object literal in `toCategoryListItem` — the audit asserts both
|
|
32
32
|
* directions.
|
|
33
33
|
*/
|
|
34
|
-
export declare const PUBLIC_CATEGORY_FIELDS: readonly ["id", "name", "slug", "description", "rootId", "parentIds", "childrenIds", "tier", "path", "order", "isLeaf", "ancestors", "categoryType", "itemCode", "isFeatured", "featuredPriority", "seo", "display", "isActive", "highlights", "faqs", "brandWebsite", "brandCountry", "brandFounded", "metrics", "createdAt", "updatedAt"];
|
|
34
|
+
export declare const PUBLIC_CATEGORY_FIELDS: readonly ["id", "name", "slug", "description", "rootId", "parentIds", "childrenIds", "tier", "path", "order", "isLeaf", "ancestors", "categoryType", "itemCode", "isFeatured", "featuredPriority", "seo", "display", "isActive", "highlights", "faqs", "brandWebsite", "brandCountry", "brandFounded", "hasbroName", "hasbroCoverImage", "metrics", "createdAt", "updatedAt"];
|
|
35
35
|
/**
|
|
36
36
|
* Fields withheld, each with the reason. Never remove one without replacing
|
|
37
37
|
* the reason — "it seemed unused" is how a field ends up public by accident.
|
|
@@ -37,6 +37,14 @@ export const PUBLIC_CATEGORY_FIELDS = [
|
|
|
37
37
|
"brandWebsite",
|
|
38
38
|
"brandCountry",
|
|
39
39
|
"brandFounded",
|
|
40
|
+
/*
|
|
41
|
+
* The Hasbro alternate name and its cover, rendered as "Also known as" by
|
|
42
|
+
* `CategoryDetailPageView`. Public because the whole point of the field is
|
|
43
|
+
* that a buyer who only knows the Hasbro season name can SEE the
|
|
44
|
+
* correspondence — a name on a toy box is not sensitive.
|
|
45
|
+
*/
|
|
46
|
+
"hasbroName",
|
|
47
|
+
"hasbroCoverImage",
|
|
40
48
|
// Rollup counts only — see `metrics` in the private list.
|
|
41
49
|
"metrics",
|
|
42
50
|
"createdAt",
|
|
@@ -217,6 +225,8 @@ export function toCategoryListItem(doc) {
|
|
|
217
225
|
brandWebsite: doc.brandWebsite,
|
|
218
226
|
brandCountry: doc.brandCountry,
|
|
219
227
|
brandFounded: doc.brandFounded,
|
|
228
|
+
hasbroName: doc.hasbroName,
|
|
229
|
+
hasbroCoverImage: doc.hasbroCoverImage,
|
|
220
230
|
metrics: toPublicMetrics(doc.metrics),
|
|
221
231
|
// 🛑 `CategoryDocument` stores Dates; `CategoryItem` declares strings —
|
|
222
232
|
// this projection is also the serialisation boundary. Converting here
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CategoryPriceGuidance } from "../../../../features/categories/schemas/category-content";
|
|
2
|
+
/**
|
|
3
|
+
* How far up the chain to look.
|
|
4
|
+
*
|
|
5
|
+
* `parentIds` holds the FULL ancestor chain (CLAUDE.md § "Category Tree"), and
|
|
6
|
+
* the forest is four tiers, so eight is slack rather than a limit. It exists so
|
|
7
|
+
* a malformed chain cannot turn one lookup into an unbounded read.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAX_GUIDANCE_ANCESTORS = 8;
|
|
10
|
+
/** The fields of a category document this resolution reads. */
|
|
11
|
+
export interface GuidanceLeafDoc {
|
|
12
|
+
id?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
parentIds?: string[];
|
|
15
|
+
productDefaults?: {
|
|
16
|
+
priceGuidance?: CategoryPriceGuidance;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A resolved band together with WHERE it came from.
|
|
21
|
+
*
|
|
22
|
+
* 🛑 The provenance is not decoration, and a caller that drops it will
|
|
23
|
+
* misattribute. `MARKET_BANDS` is keyed on era and part leaves, never on the
|
|
24
|
+
* ~216 named-model leaves, so a model lookup almost always resolves an
|
|
25
|
+
* ancestor's band — "typical for Burst DB" is a true statement about the data
|
|
26
|
+
* and "typical for Rage Longinus" is not. A renderer needs to be able to say
|
|
27
|
+
* which one it is showing.
|
|
28
|
+
*/
|
|
29
|
+
export interface ResolvedGuidance {
|
|
30
|
+
guidance: CategoryPriceGuidance;
|
|
31
|
+
/** The node the band was read off — the leaf itself, or an ancestor. */
|
|
32
|
+
fromCategoryId: string;
|
|
33
|
+
fromName?: string;
|
|
34
|
+
/** `false` when the leaf carried its own band. */
|
|
35
|
+
inherited: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Nearest-first ancestor walk for one leaf.
|
|
39
|
+
*
|
|
40
|
+
* The leaf's own band wins; only a leaf with none falls back to the nearest
|
|
41
|
+
* ancestor that has one.
|
|
42
|
+
*
|
|
43
|
+
* 🛑 ONE bounded `findByIds`, never a sequential walk. A seller form hits this
|
|
44
|
+
* on every category change, and paying up to eight round trips for a hint is
|
|
45
|
+
* how a hint becomes the slowest thing on the page.
|
|
46
|
+
*
|
|
47
|
+
* 🛑 `parentIds` is stored ROOT-FIRST, so it is reversed to walk nearest-first.
|
|
48
|
+
* Walking it as stored would hand a model leaf the ROOT's band — and since the
|
|
49
|
+
* root carries a tax default but no market band, that would usually resolve to
|
|
50
|
+
* nothing and read as "no data" for a leaf whose era has a measured band.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveInheritedGuidance(leaf: GuidanceLeafDoc): Promise<CategoryPriceGuidance | undefined>;
|
|
53
|
+
/**
|
|
54
|
+
* The same resolution for MANY leaves, in two batched reads total.
|
|
55
|
+
*
|
|
56
|
+
* Read 1 fetches the leaves; read 2 fetches the UNION of every ancestor id
|
|
57
|
+
* none of them resolved locally. A per-leaf `resolveInheritedGuidance` would be
|
|
58
|
+
* N+1 reads against Rule #6's ~3-round-trip budget, and the tool resolves up to
|
|
59
|
+
* `PRICE_INDEX_SEARCH_LIMIT` leaves at once.
|
|
60
|
+
*
|
|
61
|
+
* Leaves that resolve to nothing are ABSENT from the returned map rather than
|
|
62
|
+
* present with `undefined` — the caller distinguishes "no band applies here"
|
|
63
|
+
* from "this id does not exist", and both are legitimate answers it must be
|
|
64
|
+
* able to tell apart.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveInheritedGuidanceMany(ids: readonly string[]): Promise<Map<string, ResolvedGuidance>>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Two surfaces now need "the price guidance that applies to this leaf":
|
|
3
|
+
* the seller form's hint (`/api/categories/[id]/price-guidance`) and the
|
|
4
|
+
* public realised-price tool's gated market half
|
|
5
|
+
* (`/api/tools/price-index/market`). The ancestor walk was written
|
|
6
|
+
* privately inside the first of those, which is exactly the shape Root
|
|
7
|
+
* Cause #75 describes — a rule reachable by copy-paste gets copied, and
|
|
8
|
+
* the copy never learns about the branch added later.
|
|
9
|
+
* WHAT: The nearest-first inherited `priceGuidance` resolution, for one leaf
|
|
10
|
+
* and for many, in one place.
|
|
11
|
+
*
|
|
12
|
+
* EXPORTS:
|
|
13
|
+
* MAX_GUIDANCE_ANCESTORS — the walk bound
|
|
14
|
+
* ResolvedGuidance — a band PLUS which node it came from
|
|
15
|
+
* resolveInheritedGuidance — one leaf document -> its applicable guidance
|
|
16
|
+
* resolveInheritedGuidanceMany — N leaf ids -> a Map, two batched reads
|
|
17
|
+
*
|
|
18
|
+
* 🛑 Why a leaf's OWN band wins. `MARKET_BANDS` is keyed on era / part /
|
|
19
|
+
* launcher / stadium leaves (`category-burst-db`, `category-metal-energy-rings`),
|
|
20
|
+
* never on the ~216 named-model leaves — the crawl measured a generation,
|
|
21
|
+
* not a bey. So a model leaf has no band of its own and inherits its era's,
|
|
22
|
+
* which is the whole reason this walk exists rather than a direct read.
|
|
23
|
+
*
|
|
24
|
+
* @tag domain:categories
|
|
25
|
+
* @tag layer:server
|
|
26
|
+
* @tag pattern:resolver
|
|
27
|
+
* @tag access:server-only
|
|
28
|
+
* @tag consumers:categories/api/[id]/price-guidance,price-index/market
|
|
29
|
+
* @tag sideEffects:none
|
|
30
|
+
*/
|
|
31
|
+
import { categoriesRepository } from "../../../../features/categories/repository/categories.repository.js";
|
|
32
|
+
/**
|
|
33
|
+
* How far up the chain to look.
|
|
34
|
+
*
|
|
35
|
+
* `parentIds` holds the FULL ancestor chain (CLAUDE.md § "Category Tree"), and
|
|
36
|
+
* the forest is four tiers, so eight is slack rather than a limit. It exists so
|
|
37
|
+
* a malformed chain cannot turn one lookup into an unbounded read.
|
|
38
|
+
*/
|
|
39
|
+
export const MAX_GUIDANCE_ANCESTORS = 8;
|
|
40
|
+
/**
|
|
41
|
+
* Nearest-first ancestor walk for one leaf.
|
|
42
|
+
*
|
|
43
|
+
* The leaf's own band wins; only a leaf with none falls back to the nearest
|
|
44
|
+
* ancestor that has one.
|
|
45
|
+
*
|
|
46
|
+
* 🛑 ONE bounded `findByIds`, never a sequential walk. A seller form hits this
|
|
47
|
+
* on every category change, and paying up to eight round trips for a hint is
|
|
48
|
+
* how a hint becomes the slowest thing on the page.
|
|
49
|
+
*
|
|
50
|
+
* 🛑 `parentIds` is stored ROOT-FIRST, so it is reversed to walk nearest-first.
|
|
51
|
+
* Walking it as stored would hand a model leaf the ROOT's band — and since the
|
|
52
|
+
* root carries a tax default but no market band, that would usually resolve to
|
|
53
|
+
* nothing and read as "no data" for a leaf whose era has a measured band.
|
|
54
|
+
*/
|
|
55
|
+
export async function resolveInheritedGuidance(leaf) {
|
|
56
|
+
if (leaf.productDefaults?.priceGuidance)
|
|
57
|
+
return leaf.productDefaults.priceGuidance;
|
|
58
|
+
const parentIds = (leaf.parentIds ?? []).slice(0, MAX_GUIDANCE_ANCESTORS);
|
|
59
|
+
if (parentIds.length === 0)
|
|
60
|
+
return undefined;
|
|
61
|
+
const nearestFirst = [...parentIds].reverse();
|
|
62
|
+
const ancestors = await categoriesRepository.findByIds(nearestFirst);
|
|
63
|
+
const byId = new Map(ancestors.map((a) => [a.id, a]));
|
|
64
|
+
for (const pid of nearestFirst) {
|
|
65
|
+
const guidance = byId.get(pid)?.productDefaults?.priceGuidance;
|
|
66
|
+
if (guidance)
|
|
67
|
+
return guidance;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The same resolution for MANY leaves, in two batched reads total.
|
|
73
|
+
*
|
|
74
|
+
* Read 1 fetches the leaves; read 2 fetches the UNION of every ancestor id
|
|
75
|
+
* none of them resolved locally. A per-leaf `resolveInheritedGuidance` would be
|
|
76
|
+
* N+1 reads against Rule #6's ~3-round-trip budget, and the tool resolves up to
|
|
77
|
+
* `PRICE_INDEX_SEARCH_LIMIT` leaves at once.
|
|
78
|
+
*
|
|
79
|
+
* Leaves that resolve to nothing are ABSENT from the returned map rather than
|
|
80
|
+
* present with `undefined` — the caller distinguishes "no band applies here"
|
|
81
|
+
* from "this id does not exist", and both are legitimate answers it must be
|
|
82
|
+
* able to tell apart.
|
|
83
|
+
*/
|
|
84
|
+
export async function resolveInheritedGuidanceMany(ids) {
|
|
85
|
+
const out = new Map();
|
|
86
|
+
const unique = [...new Set(ids.filter((id) => typeof id === "string" && id.length > 0))];
|
|
87
|
+
if (unique.length === 0)
|
|
88
|
+
return out;
|
|
89
|
+
const leaves = (await categoriesRepository.getManyByIds(unique));
|
|
90
|
+
/*
|
|
91
|
+
* Everything still unanswered after the leaves' own bands, paired with the
|
|
92
|
+
* nearest-first chain it needs — collected before the second read so that
|
|
93
|
+
* read is one call for every leaf at once.
|
|
94
|
+
*/
|
|
95
|
+
const pending = [];
|
|
96
|
+
const wanted = new Set();
|
|
97
|
+
for (const leaf of leaves) {
|
|
98
|
+
const id = leaf.id;
|
|
99
|
+
if (!id)
|
|
100
|
+
continue;
|
|
101
|
+
const own = leaf.productDefaults?.priceGuidance;
|
|
102
|
+
if (own) {
|
|
103
|
+
out.set(id, {
|
|
104
|
+
guidance: own,
|
|
105
|
+
fromCategoryId: id,
|
|
106
|
+
...(leaf.name ? { fromName: leaf.name } : {}),
|
|
107
|
+
inherited: false,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const chain = [...(leaf.parentIds ?? []).slice(0, MAX_GUIDANCE_ANCESTORS)].reverse();
|
|
112
|
+
if (chain.length === 0)
|
|
113
|
+
continue;
|
|
114
|
+
pending.push({ id, chain });
|
|
115
|
+
for (const pid of chain)
|
|
116
|
+
wanted.add(pid);
|
|
117
|
+
}
|
|
118
|
+
if (pending.length === 0)
|
|
119
|
+
return out;
|
|
120
|
+
const ancestors = (await categoriesRepository.findByIds([...wanted]));
|
|
121
|
+
const byId = new Map(ancestors.filter((a) => a.id).map((a) => [a.id, a]));
|
|
122
|
+
for (const { id, chain } of pending) {
|
|
123
|
+
for (const pid of chain) {
|
|
124
|
+
const ancestor = byId.get(pid);
|
|
125
|
+
const guidance = ancestor?.productDefaults?.priceGuidance;
|
|
126
|
+
if (guidance) {
|
|
127
|
+
out.set(id, {
|
|
128
|
+
guidance,
|
|
129
|
+
fromCategoryId: pid,
|
|
130
|
+
...(ancestor?.name ? { fromName: ancestor.name } : {}),
|
|
131
|
+
inherited: true,
|
|
132
|
+
});
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
@@ -39,6 +39,20 @@ export declare function resolveShippingCost(storeId: string | undefined): Promis
|
|
|
39
39
|
storeState: string | undefined;
|
|
40
40
|
/** C5b — the resolved policy, so a caller can quote with the cart in hand. */
|
|
41
41
|
shippingPolicy: StoreShippingPolicy;
|
|
42
|
+
/**
|
|
43
|
+
* The seller's own tax registration, from the store read this function
|
|
44
|
+
* already performs.
|
|
45
|
+
*
|
|
46
|
+
* Returned here rather than re-fetched in `createOrderForGroup` so the
|
|
47
|
+
* checkout path pays no extra Firestore read for data already in scope
|
|
48
|
+
* (Rule #6). Raw fields, not a resolved identity — the seller-vs-platform
|
|
49
|
+
* decision belongs to `resolveSupplierIdentity` alone.
|
|
50
|
+
*/
|
|
51
|
+
storeTaxIdentity: {
|
|
52
|
+
gstin?: string;
|
|
53
|
+
legalName?: string;
|
|
54
|
+
registeredAddress?: string;
|
|
55
|
+
} | undefined;
|
|
42
56
|
/**
|
|
43
57
|
* 🛑 True when the mode is `estimate` and no carrier rate was supplied.
|
|
44
58
|
*
|