@mohasinac/appkit 4.53.0 → 4.53.1
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/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/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/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/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 +25 -0
- package/dist/_internal/server/features/stores/tabs.js +122 -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 +2 -1
- 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 +39 -15
- package/dist/constants/api-endpoints.js +28 -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 +4 -11
- 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 +113 -0
- package/dist/features/categories/components/BrandDetailPageView.js +19 -3
- package/dist/features/categories/components/BrandDetailTabs.js +10 -0
- package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
- package/dist/features/categories/components/CategoryDetailPageView.js +141 -14
- package/dist/features/categories/components/CategoryDetailTabs.js +12 -0
- 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 +4 -9
- 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 +4 -9
- 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 +4 -9
- 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 +4 -11
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +3 -1
- package/dist/features/price-index/components/PriceIndexToolView.js +92 -13
- package/dist/features/products/components/CompareOverlay.d.ts +18 -1
- package/dist/features/products/components/CompareOverlay.js +21 -2
- 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 +91 -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 +74 -15
- 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/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 +98 -0
- package/dist/features/products/repository/products.repository.js +235 -17
- 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 +39 -0
- package/dist/features/products/utils/group-member-image.js +3 -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/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/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 +280 -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 +372 -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 +441 -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 +9 -9
- package/dist/server.js +27 -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 +135 -26
- 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
|
@@ -4,7 +4,15 @@ export const auctionRule = {
|
|
|
4
4
|
orderType: "auction",
|
|
5
5
|
cartEligible: false, // bid-only; add-to-cart is blocked at the action layer
|
|
6
6
|
cartIneligibleHint: "Place a bid on the auction page instead.",
|
|
7
|
-
|
|
7
|
+
/*
|
|
8
|
+
* 🛑 cod + cash, NOT emi. An auction win is a committed sale of a unique lot:
|
|
9
|
+
* a buyer who never pays on delivery costs the seller the item and the
|
|
10
|
+
* auction both, and there is no second-highest bidder to fall back to once
|
|
11
|
+
* it has been marked sold. EMI is confirmed-at-order financing rather than a
|
|
12
|
+
* deferred payment, so it carries none of that risk and stays available.
|
|
13
|
+
*/
|
|
14
|
+
blockedPaymentMethods: ["cod", "cash"],
|
|
15
|
+
blockedPaymentMessage: "An auction win cannot be paid for on delivery or in cash — the lot is one of a kind and is held for you from the moment the auction closes.",
|
|
8
16
|
canMergeWithSameProduct: false,
|
|
9
17
|
refundPolicy: { full: true, partial: false, partialGranularity: "none" },
|
|
10
18
|
splitKey: (item) => `auction:${item.itemId}`,
|
|
@@ -3,4 +3,17 @@ export const bundleRule = {
|
|
|
3
3
|
cartEligible: false, // direct-checkout-only; addBundleToCart has been removed
|
|
4
4
|
orderType: "standard", // bundle orders resolve to standard orderType
|
|
5
5
|
requiresShippingAddress: true,
|
|
6
|
+
/*
|
|
7
|
+
* 🛑 cod + cash, NOT emi. A bundle is priced BELOW the sum of its members —
|
|
8
|
+
* that discount is the whole product — so a no-show on delivery costs the
|
|
9
|
+
* seller several items at once, and the bundle has meanwhile been held out of
|
|
10
|
+
* every member's own availability. EMI is confirmed-at-order financing rather
|
|
11
|
+
* than a deferred payment, so it carries none of that and stays available.
|
|
12
|
+
*
|
|
13
|
+
* 🛑 Honoured by `assertPaymentMethodAllowed`, NOT by `runSyncPreflight` —
|
|
14
|
+
* which skips multi-member lines, and a bundle line is always one. A value
|
|
15
|
+
* here relying on preflight would be a silent no-op.
|
|
16
|
+
*/
|
|
17
|
+
blockedPaymentMethods: ["cod", "cash"],
|
|
18
|
+
blockedPaymentMessage: "Bundles cannot be paid for on delivery or in cash — a bundle is priced below the sum of its parts and is reserved when you order.",
|
|
6
19
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { ListingCheckoutRule, CategoryCheckoutRule, CartItemProductPair, OrderItemInput, RefundPolicy, } from "./types";
|
|
2
2
|
export { CHECKOUT_RULES, CATEGORY_CHECKOUT_RULES, getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPreflight, } from "./_registry";
|
|
3
|
+
export { assertPaymentMethodAllowed, blockedMethodsForCart, type BlockedMethod, } from "./payment-gate";
|
|
3
4
|
export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, PRIZE_DRAW_DURATION_DAYS_MIN, PRIZE_DRAW_DURATION_DAYS_MAX, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits";
|
|
4
5
|
export { standardRule } from "./standard.rule";
|
|
5
6
|
export { auctionRule } from "./auction.rule";
|
|
@@ -12,3 +13,4 @@ export { digitalCodeRule } from "./digital-code.rule";
|
|
|
12
13
|
export { liveRule } from "./live.rule";
|
|
13
14
|
export { artRule } from "./art.rule";
|
|
14
15
|
export { stickersRule } from "./stickers.rule";
|
|
16
|
+
export { sparesRule } from "./spares.rule";
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export { CHECKOUT_RULES, CATEGORY_CHECKOUT_RULES, getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPreflight, } from "./_registry.js";
|
|
2
|
+
/*
|
|
3
|
+
* The payment gate is a SEPARATE module from `_registry`, on purpose: it is the
|
|
4
|
+
* one rule check that cannot be expressed as a per-listing-type pass over
|
|
5
|
+
* single-member lines, which is all `runSyncPreflight` can see. Keeping them
|
|
6
|
+
* apart is what stops someone folding it back into preflight, where it would
|
|
7
|
+
* silently stop covering bundles and grouped lines.
|
|
8
|
+
*/
|
|
9
|
+
export { assertPaymentMethodAllowed, blockedMethodsForCart, } from "./payment-gate.js";
|
|
2
10
|
export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, PRIZE_DRAW_DURATION_DAYS_MIN, PRIZE_DRAW_DURATION_DAYS_MAX, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits.js";
|
|
3
11
|
// Individual rules — exported for tests and direct access.
|
|
4
12
|
export { standardRule } from "./standard.rule.js";
|
|
@@ -12,3 +20,4 @@ export { digitalCodeRule } from "./digital-code.rule.js";
|
|
|
12
20
|
export { liveRule } from "./live.rule.js";
|
|
13
21
|
export { artRule } from "./art.rule.js";
|
|
14
22
|
export { stickersRule } from "./stickers.rule.js";
|
|
23
|
+
export { sparesRule } from "./spares.rule.js";
|
|
@@ -2,7 +2,6 @@ import { DEFAULT_LISTING_RULE } from "./_defaults.js";
|
|
|
2
2
|
export const offerRule = {
|
|
3
3
|
...DEFAULT_LISTING_RULE,
|
|
4
4
|
orderType: "offer",
|
|
5
|
-
maxQuantityPerLine: 1,
|
|
6
5
|
canMergeWithSameProduct: false,
|
|
7
6
|
refundPolicy: { full: true, partial: false, partialGranularity: "none" },
|
|
8
7
|
splitKey: (item) => `offer:${item.itemId}`,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CartItemDocument } from "../../../../features/cart/schemas/firestore";
|
|
2
|
+
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
|
+
import { type CheckoutPaymentMethod } from "../../features/checkout/config";
|
|
4
|
+
/** Why one method is unavailable, and which listing said so. */
|
|
5
|
+
export interface BlockedMethod {
|
|
6
|
+
/** The listing's own wording when it has one, else a generated sentence. */
|
|
7
|
+
message: string;
|
|
8
|
+
/** For logs and for the generated wording. */
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Which methods this cart forbids.
|
|
13
|
+
*
|
|
14
|
+
* Returned rather than thrown so the same answer can also DISABLE a payment
|
|
15
|
+
* control — one source for the refusal and the affordance, instead of a
|
|
16
|
+
* client-side guess that drifts from the server.
|
|
17
|
+
*/
|
|
18
|
+
export declare function blockedMethodsForCart(items: readonly CartItemDocument[], productById: ReadonlyMap<string, ProductDocument>): Map<CheckoutPaymentMethod, BlockedMethod>;
|
|
19
|
+
/**
|
|
20
|
+
* Throw when the chosen method is forbidden by anything in the cart.
|
|
21
|
+
*
|
|
22
|
+
* One error, not one per offending line: a buyer changes the payment method
|
|
23
|
+
* once, and listing every blocked item would be a wall of text about a single
|
|
24
|
+
* decision.
|
|
25
|
+
*/
|
|
26
|
+
export declare function assertPaymentMethodAllowed(items: readonly CartItemDocument[], productById: ReadonlyMap<string, ProductDocument>, paymentMethod: CheckoutPaymentMethod | undefined): void;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Some listings must not be bought with a pay-later method. An auction win
|
|
3
|
+
* or a bundle is a committed sale — a buyer who never pays on delivery
|
|
4
|
+
* costs the seller the lot, and for a unique auction lot there is no
|
|
5
|
+
* second-highest bidder to fall back on once it is marked sold. The rule
|
|
6
|
+
* registry has a field for this (`blockedPaymentMethods`) and nothing
|
|
7
|
+
* reachable enforced it for every line.
|
|
8
|
+
* WHAT: One cart-wide payment check, run BEFORE the transaction.
|
|
9
|
+
*
|
|
10
|
+
* 🛑 `runSyncPreflight` STRUCTURALLY CANNOT DO THIS, and that is not a bug in
|
|
11
|
+
* preflight. It does `if (isMultiMemberLine(pair.item)) continue;` for a good
|
|
12
|
+
* reason: a bundle or grouped line's own `listingType` describes the WRAPPER,
|
|
13
|
+
* not its members, so a per-type rule applied there would be applied to the
|
|
14
|
+
* wrong thing. Both of its call sites repeat the skip independently, and the
|
|
15
|
+
* online path additionally reduces each line to `getCartItemMemberIds(item)[0]`
|
|
16
|
+
* — its FIRST member only. So a `blockedPaymentMethods` set on `bundleRule` and
|
|
17
|
+
* left to preflight would be a silent no-op: the field would be set, reviewed,
|
|
18
|
+
* and never read.
|
|
19
|
+
*
|
|
20
|
+
* This resolves every line to ALL its members, so a grouped line containing one
|
|
21
|
+
* blocked listing is caught.
|
|
22
|
+
*
|
|
23
|
+
* 🛑 IT RUNS OUTSIDE THE TRANSACTION. Preflight is invoked inside the
|
|
24
|
+
* transaction callback, so a payment-method rejection there spends a full
|
|
25
|
+
* transaction attempt to produce an answer that depends on nothing the
|
|
26
|
+
* transaction reads.
|
|
27
|
+
*
|
|
28
|
+
* EXPORTS: assertPaymentMethodAllowed, blockedMethodsForCart
|
|
29
|
+
*
|
|
30
|
+
* @tag domain:checkout
|
|
31
|
+
* @tag layer:shared
|
|
32
|
+
* @tag pattern:none
|
|
33
|
+
* @tag access:isomorphic
|
|
34
|
+
* @tag consumers:server/features/checkout
|
|
35
|
+
* @tag sideEffects:none
|
|
36
|
+
*/
|
|
37
|
+
import { ValidationError } from "../../../../errors/index.js";
|
|
38
|
+
import { CHECKOUT_PAYMENT_METHODS, } from "../../features/checkout/config.js";
|
|
39
|
+
import { getCartItemMemberIds } from "../line-members.js";
|
|
40
|
+
import { getCategoryRule, getListingRule } from "./_registry.js";
|
|
41
|
+
/**
|
|
42
|
+
* Which methods this cart forbids.
|
|
43
|
+
*
|
|
44
|
+
* Returned rather than thrown so the same answer can also DISABLE a payment
|
|
45
|
+
* control — one source for the refusal and the affordance, instead of a
|
|
46
|
+
* client-side guess that drifts from the server.
|
|
47
|
+
*/
|
|
48
|
+
export function blockedMethodsForCart(items, productById) {
|
|
49
|
+
const blocked = new Map();
|
|
50
|
+
const claim = (methods, label, message) => {
|
|
51
|
+
for (const m of methods ?? []) {
|
|
52
|
+
// First claimant wins, so the message names a real listing rather than
|
|
53
|
+
// whichever happened to be last in the cart.
|
|
54
|
+
if (blocked.has(m))
|
|
55
|
+
continue;
|
|
56
|
+
blocked.set(m, {
|
|
57
|
+
label,
|
|
58
|
+
message: message ??
|
|
59
|
+
`"${label}" cannot be paid for with ${PAYMENT_METHOD_LABEL[m] ?? m}.`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
for (const item of items) {
|
|
64
|
+
/*
|
|
65
|
+
* A bundle's restriction lives on its CategoryCheckoutRule, not on any
|
|
66
|
+
* listing type — its members are ordinary products whose own types would
|
|
67
|
+
* otherwise answer for it. Checked first for that reason.
|
|
68
|
+
*/
|
|
69
|
+
if (item.bundleCategorySlug) {
|
|
70
|
+
const rule = getCategoryRule("bundle");
|
|
71
|
+
claim(rule?.blockedPaymentMethods, item.groupTitle ?? item.productTitle ?? "this bundle", rule?.blockedPaymentMessage);
|
|
72
|
+
}
|
|
73
|
+
/*
|
|
74
|
+
* EVERY member, not the first. `getCartItemMemberIds` returns the line's
|
|
75
|
+
* own product for a plain line and all members for a bundle or group, so
|
|
76
|
+
* one blocked member blocks the line.
|
|
77
|
+
*/
|
|
78
|
+
for (const productId of getCartItemMemberIds(item)) {
|
|
79
|
+
const product = productById.get(productId);
|
|
80
|
+
/*
|
|
81
|
+
* An unresolved member is NOT treated as unrestricted here. It is left to
|
|
82
|
+
* the stock and existence checks that already run on the same cart and
|
|
83
|
+
* fail loudly — inventing a payment refusal for a missing product would
|
|
84
|
+
* report the wrong problem.
|
|
85
|
+
*/
|
|
86
|
+
if (!product)
|
|
87
|
+
continue;
|
|
88
|
+
const type = (product.listingType ?? "standard");
|
|
89
|
+
const rule = getListingRule(type);
|
|
90
|
+
claim(rule.blockedPaymentMethods, product.title ?? type, rule.blockedPaymentMessage);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return blocked;
|
|
94
|
+
}
|
|
95
|
+
/** Human wording for the generated message. */
|
|
96
|
+
const PAYMENT_METHOD_LABEL = {
|
|
97
|
+
cod: "cash on delivery",
|
|
98
|
+
cash: "cash on pickup",
|
|
99
|
+
emi: "EMI",
|
|
100
|
+
online: "online payment",
|
|
101
|
+
upi_manual: "manual bank/UPI transfer",
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Throw when the chosen method is forbidden by anything in the cart.
|
|
105
|
+
*
|
|
106
|
+
* One error, not one per offending line: a buyer changes the payment method
|
|
107
|
+
* once, and listing every blocked item would be a wall of text about a single
|
|
108
|
+
* decision.
|
|
109
|
+
*/
|
|
110
|
+
export function assertPaymentMethodAllowed(items, productById, paymentMethod) {
|
|
111
|
+
if (!paymentMethod)
|
|
112
|
+
return;
|
|
113
|
+
/*
|
|
114
|
+
* 🛑 `admin_bypass` is exempt, deliberately. It exists so an admin can reach
|
|
115
|
+
* an order state without a real payment, is gated by a site-settings flag
|
|
116
|
+
* plus an admin role, and logs every use. Blocking it would make the one tool
|
|
117
|
+
* for testing these flows unable to test them.
|
|
118
|
+
*/
|
|
119
|
+
if (paymentMethod === "admin_bypass")
|
|
120
|
+
return;
|
|
121
|
+
const blocked = blockedMethodsForCart(items, productById);
|
|
122
|
+
const offender = blocked.get(paymentMethod);
|
|
123
|
+
if (!offender)
|
|
124
|
+
return;
|
|
125
|
+
/*
|
|
126
|
+
* The methods that remain, derived from the union rather than a second list —
|
|
127
|
+
* a seventh payment method must not quietly go unmentioned here.
|
|
128
|
+
*/
|
|
129
|
+
const allowed = CHECKOUT_PAYMENT_METHODS.filter((m) => m !== "admin_bypass" && !blocked.has(m)).map((m) => PAYMENT_METHOD_LABEL[m] ?? m);
|
|
130
|
+
throw Object.assign(new ValidationError(allowed.length > 0
|
|
131
|
+
? `${offender.message} Available instead: ${allowed.join(", ")}.`
|
|
132
|
+
: `${offender.message} Nothing in this cart's combination can be paid for — remove the item and buy it on its own.`), { code: "PAYMENT_METHOD_BLOCKED" });
|
|
133
|
+
}
|
|
@@ -10,15 +10,26 @@ import { PRIZE_DRAW_MAX_REVEALS_PER_ORDER } from "./_limits.js";
|
|
|
10
10
|
* "admin_bypass" stays usable for QA regardless.
|
|
11
11
|
*/
|
|
12
12
|
const PRIZE_DRAW_BLOCKED_PAYMENT_METHODS = ["cod", "cash", "emi"];
|
|
13
|
+
/**
|
|
14
|
+
* The refusal, kept VERBATIM when this check moved out of `preflightChecks`
|
|
15
|
+
* into `assertPaymentMethodAllowed`.
|
|
16
|
+
*
|
|
17
|
+
* 🛑 The gate can generate a correct sentence on its own, and a generated one
|
|
18
|
+
* would have been a regression here: this wording names the REASON (winner
|
|
19
|
+
* assignment waits on confirmed payment) rather than just the refusal, and the
|
|
20
|
+
* reason is the thing a buyer needs in order to pick a different method rather
|
|
21
|
+
* than abandon the entry.
|
|
22
|
+
*/
|
|
23
|
+
const PRIZE_DRAW_BLOCKED_PAYMENT_MESSAGE = "Prize-draw entries can only be paid by manual bank/UPI transfer or PhonePe — cash on delivery and EMI are not available for this listing type.";
|
|
13
24
|
export const prizeDrawRule = {
|
|
14
25
|
...DEFAULT_LISTING_RULE,
|
|
15
26
|
orderType: "prize-draw",
|
|
16
27
|
nonRefundable: true,
|
|
17
|
-
maxQuantityPerLine: 1,
|
|
18
28
|
canMergeWithSameProduct: false,
|
|
19
29
|
maxLinesPerOrder: PRIZE_DRAW_MAX_REVEALS_PER_ORDER,
|
|
20
30
|
refundPolicy: { full: false, partial: false, partialGranularity: "none" },
|
|
21
31
|
blockedPaymentMethods: PRIZE_DRAW_BLOCKED_PAYMENT_METHODS,
|
|
32
|
+
blockedPaymentMessage: PRIZE_DRAW_BLOCKED_PAYMENT_MESSAGE,
|
|
22
33
|
splitKey: (item) => `prize-draw:${item.itemId}`,
|
|
23
34
|
/**
|
|
24
35
|
* Slice a high-quantity prize-draw entry into chunks of
|
|
@@ -43,13 +54,23 @@ export const prizeDrawRule = {
|
|
|
43
54
|
}
|
|
44
55
|
return chunks;
|
|
45
56
|
},
|
|
46
|
-
preflightChecks: (pairs
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
preflightChecks: (pairs) => {
|
|
58
|
+
/*
|
|
59
|
+
* The payment-method check USED to live here and is now in
|
|
60
|
+
* `assertPaymentMethodAllowed`, which runs cart-wide before the
|
|
61
|
+
* transaction.
|
|
62
|
+
*
|
|
63
|
+
* 🛑 This is not a tidy-up. The copy here could only ever see
|
|
64
|
+
* single-member lines — `runSyncPreflight` skips a bundle or grouped line,
|
|
65
|
+
* and its online call site reduces each line to its FIRST member — so a
|
|
66
|
+
* prize-draw entry reachable through a grouped selection was never
|
|
67
|
+
* checked. Re-adding a copy here would be a second answer to one question
|
|
68
|
+
* (Root Cause #75), and the one that is easier to find is the one that
|
|
69
|
+
* cannot see every line.
|
|
70
|
+
*
|
|
71
|
+
* `blockedPaymentMethods` + `blockedPaymentMessage` on this rule are what
|
|
72
|
+
* the gate reads, so the wording is unchanged.
|
|
73
|
+
*/
|
|
53
74
|
for (const { item, product } of pairs) {
|
|
54
75
|
if (product.listingType !== "prize-draw")
|
|
55
76
|
continue;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spares listing rule — one component off a disassembled item, standard-like
|
|
3
|
+
* checkout.
|
|
4
|
+
*
|
|
5
|
+
* No bespoke behaviour: cart/order grouping, stock decrement and refund policy
|
|
6
|
+
* all follow the standard defaults, and `pluginFor()` carries everything that
|
|
7
|
+
* differs (badge, browse route, seller form fields).
|
|
8
|
+
*
|
|
9
|
+
* 🛑 `orderType: "standard"` is deliberate rather than lazy. A new `OrderType`
|
|
10
|
+
* member fans out into the order-status tabs, the order filters and the
|
|
11
|
+
* splitter's own keys — and buys nothing here, because a spare is fulfilled,
|
|
12
|
+
* refunded and reported exactly like any other physical item. A buyer looking
|
|
13
|
+
* at their orders wants "the attack ring I bought", not a separate tab for it.
|
|
14
|
+
*/
|
|
15
|
+
import type { ListingCheckoutRule } from "./types";
|
|
16
|
+
export declare const sparesRule: ListingCheckoutRule;
|
|
@@ -62,8 +62,6 @@ export interface ListingCheckoutRule {
|
|
|
62
62
|
* Set true for prize-draw entries.
|
|
63
63
|
*/
|
|
64
64
|
nonRefundable: boolean;
|
|
65
|
-
/** Hard qty cap per single cart line. Auction/offer/prize-draw-per-line = 1. */
|
|
66
|
-
maxQuantityPerLine: number;
|
|
67
65
|
/**
|
|
68
66
|
* When false the checkout pipeline issues one order per cart line (even when
|
|
69
67
|
* multiple lines share the same product). Auctions and offers set this to
|
|
@@ -83,8 +81,20 @@ export interface ListingCheckoutRule {
|
|
|
83
81
|
* all methods allowed. Prize-draw blocks cod/cash/emi — winner assignment
|
|
84
82
|
* depends on the order's payment actually being confirmed, which those
|
|
85
83
|
* deferred-payment methods don't guarantee.
|
|
84
|
+
*
|
|
85
|
+
* 🛑 Enforced by `assertPaymentMethodAllowed`, NOT by `runSyncPreflight`. A
|
|
86
|
+
* rule may only trust preflight for a single-member line; a type that can
|
|
87
|
+
* appear inside a bundle or a grouped selection is skipped there entirely.
|
|
88
|
+
* The gate runs over every member of every line, once, before the
|
|
89
|
+
* transaction.
|
|
86
90
|
*/
|
|
87
91
|
blockedPaymentMethods?: CheckoutPaymentMethod[];
|
|
92
|
+
/**
|
|
93
|
+
* The refusal, in this type's own words. Optional — the gate generates a
|
|
94
|
+
* correct sentence without it. Supply one when the REASON is worth saying,
|
|
95
|
+
* as prize-draw's does.
|
|
96
|
+
*/
|
|
97
|
+
blockedPaymentMessage?: string;
|
|
88
98
|
/**
|
|
89
99
|
* Return the grouping key used by the order splitter. Items with the same
|
|
90
100
|
* key land in the same OrderGroup and produce one order document.
|
|
@@ -150,4 +160,18 @@ export interface CategoryCheckoutRule {
|
|
|
150
160
|
cartEligible: boolean;
|
|
151
161
|
orderType: OrderType;
|
|
152
162
|
requiresShippingAddress: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Payment methods this category cannot be paid with.
|
|
165
|
+
*
|
|
166
|
+
* 🛑 NOT enforced by `runSyncPreflight`. That function skips multi-member
|
|
167
|
+
* lines by design, and a bundle is always one — so a value here would be set,
|
|
168
|
+
* reviewed, and never read. `assertPaymentMethodAllowed` is what honours it,
|
|
169
|
+
* and it runs cart-wide before the transaction.
|
|
170
|
+
*/
|
|
171
|
+
blockedPaymentMethods?: CheckoutPaymentMethod[];
|
|
172
|
+
/**
|
|
173
|
+
* The refusal, in this category's own words. Optional — the gate generates a
|
|
174
|
+
* correct sentence without it. Supply one when the REASON is worth saying.
|
|
175
|
+
*/
|
|
176
|
+
blockedPaymentMessage?: string;
|
|
153
177
|
}
|
|
@@ -119,6 +119,120 @@ export interface AppkitSeoConfig {
|
|
|
119
119
|
/** BCP 47 locale tag for OG/schema.org, e.g. "en-IN" */
|
|
120
120
|
locale?: string;
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* A value the business has not decided yet.
|
|
124
|
+
*
|
|
125
|
+
* 🛑 `null`, deliberately, rather than `undefined` or an empty string. All
|
|
126
|
+
* three would render the same blank space, and only this one is distinguishable
|
|
127
|
+
* from "the key is missing" at a glance in the config file — which matters
|
|
128
|
+
* because every field typed this way appears on a page whose purpose is legal
|
|
129
|
+
* disclosure. A renderer is expected to show a visible `[to be confirmed]`
|
|
130
|
+
* marker (`<PendingValue>`), never an empty gap, so that an unfilled statutory
|
|
131
|
+
* field is obvious to whoever looks at the page rather than reading as absent.
|
|
132
|
+
*/
|
|
133
|
+
export type PendingString = string | null;
|
|
134
|
+
/** Registered postal address of the legal entity. */
|
|
135
|
+
export interface AppkitBusinessAddress {
|
|
136
|
+
line1: string;
|
|
137
|
+
line2?: string;
|
|
138
|
+
city: string;
|
|
139
|
+
state: string;
|
|
140
|
+
/**
|
|
141
|
+
* GST state code, e.g. "27" for Maharashtra.
|
|
142
|
+
*
|
|
143
|
+
* 🛑 Must match the first two digits of `AppkitBusinessConfig.gstin`, and is
|
|
144
|
+
* an INPUT to the intra- vs inter-state supply decision that picks CGST+SGST
|
|
145
|
+
* over IGST. Wrong here means wrong tax on every invoice.
|
|
146
|
+
*/
|
|
147
|
+
stateCode: string;
|
|
148
|
+
postalCode: string;
|
|
149
|
+
country: string;
|
|
150
|
+
}
|
|
151
|
+
export interface AppkitBusinessSupport {
|
|
152
|
+
email?: PendingString;
|
|
153
|
+
phone?: PendingString;
|
|
154
|
+
/** WhatsApp number with country code, digits only, e.g. "918919665811". */
|
|
155
|
+
whatsapp?: PendingString;
|
|
156
|
+
/** Human-readable, e.g. "Mon-Sat, 10:00-19:00 IST". */
|
|
157
|
+
hours?: PendingString;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Grievance officer. A mandatory published disclosure for an Indian
|
|
161
|
+
* e-commerce platform under the Consumer Protection (E-Commerce) Rules 2020
|
|
162
|
+
* and the IT Rules 2021 — name, designation and a working contact.
|
|
163
|
+
*/
|
|
164
|
+
export interface AppkitBusinessGrievance {
|
|
165
|
+
name?: PendingString;
|
|
166
|
+
designation?: PendingString;
|
|
167
|
+
email?: PendingString;
|
|
168
|
+
phone?: PendingString;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Published policy terms, as PROSE rather than numbers.
|
|
172
|
+
*
|
|
173
|
+
* "2-3 business days" carries its own unit; a bare `3` forces every renderer
|
|
174
|
+
* to re-invent one, and they will not agree.
|
|
175
|
+
*/
|
|
176
|
+
export interface AppkitBusinessPolicy {
|
|
177
|
+
processingTime?: PendingString;
|
|
178
|
+
deliveryEstimate?: PendingString;
|
|
179
|
+
shippingCharges?: PendingString;
|
|
180
|
+
cancellationWindow?: PendingString;
|
|
181
|
+
returnWindow?: PendingString;
|
|
182
|
+
refundTimeline?: PendingString;
|
|
183
|
+
}
|
|
184
|
+
/** Where buyers paying by bank transfer or UPI send money. */
|
|
185
|
+
export interface AppkitBusinessBank {
|
|
186
|
+
name?: PendingString;
|
|
187
|
+
accountName?: PendingString;
|
|
188
|
+
/**
|
|
189
|
+
* Home branch, e.g. "Koramangala, Bangalore". Buyer-facing and NOT private:
|
|
190
|
+
* it identifies a public bank location, carries no account identifier, and
|
|
191
|
+
* some transfer forms still ask for it. Contrast `accountNumber`/`ifsc`
|
|
192
|
+
* below, which do identify the account and are withheld.
|
|
193
|
+
*/
|
|
194
|
+
branchName?: PendingString;
|
|
195
|
+
/** 🛑 PRIVATE. Never on the public GET /api/site-settings. */
|
|
196
|
+
accountNumber?: PendingString;
|
|
197
|
+
/** 🛑 PRIVATE. Never on the public GET /api/site-settings. */
|
|
198
|
+
ifsc?: PendingString;
|
|
199
|
+
/** UPI Virtual Payment Address, e.g. "name@bank". Buyer-facing. */
|
|
200
|
+
upiVpa?: PendingString;
|
|
201
|
+
/**
|
|
202
|
+
* Root-relative path to the payment QR image.
|
|
203
|
+
*
|
|
204
|
+
* 🛑 A STATIC asset under public/, never a `/media/<slug>`. The media proxy
|
|
205
|
+
* composites a watermark onto every image it serves and has no skip
|
|
206
|
+
* mechanism, and a mark over a QR can corrupt enough modules to break the
|
|
207
|
+
* scan. `resolveMediaUrl` returns a relative path untouched, which is what
|
|
208
|
+
* makes a static path safe here.
|
|
209
|
+
*/
|
|
210
|
+
qrImagePath?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Statutory identity of the legal entity behind the site.
|
|
214
|
+
*
|
|
215
|
+
* This is the ONE owner of these facts. They are published by law, so none of
|
|
216
|
+
* it is secret and all of it belongs in a committed, reviewable file; the
|
|
217
|
+
* corresponding `BUSINESS_*` env vars exist to override per deployment.
|
|
218
|
+
*/
|
|
219
|
+
export interface AppkitBusinessConfig {
|
|
220
|
+
/** Registered legal name, e.g. "Let It Rip India". */
|
|
221
|
+
legalName: string;
|
|
222
|
+
/** Proprietor / authorised signatory. */
|
|
223
|
+
proprietor?: string;
|
|
224
|
+
/** e.g. "Sole proprietorship", "Private limited company". */
|
|
225
|
+
structure?: string;
|
|
226
|
+
/** 15-character GSTIN. Validate with `isValidGstin` — shape AND checksum. */
|
|
227
|
+
gstin?: PendingString;
|
|
228
|
+
/** Udyam (MSME) registration number. */
|
|
229
|
+
udyamNumber?: PendingString;
|
|
230
|
+
registeredAddress?: AppkitBusinessAddress;
|
|
231
|
+
support?: AppkitBusinessSupport;
|
|
232
|
+
grievance?: AppkitBusinessGrievance;
|
|
233
|
+
policy?: AppkitBusinessPolicy;
|
|
234
|
+
bank?: AppkitBusinessBank;
|
|
235
|
+
}
|
|
122
236
|
export interface AppkitI18nConfig {
|
|
123
237
|
/** next-intl localePrefix strategy (default: "never") */
|
|
124
238
|
localePrefix?: "never" | "always" | "as-needed";
|
|
@@ -146,6 +260,14 @@ export interface AppkitConfig {
|
|
|
146
260
|
locales?: string[];
|
|
147
261
|
/** Brand identity — name, social URLs, taglines */
|
|
148
262
|
brand?: AppkitBrandConfig;
|
|
263
|
+
/**
|
|
264
|
+
* Statutory identity of the legal entity — legal name, GSTIN, registered
|
|
265
|
+
* address, support channels, grievance officer, published policy terms.
|
|
266
|
+
*
|
|
267
|
+
* Distinct from `brand`, which is how the site PRESENTS itself. "LetItRip"
|
|
268
|
+
* is the brand; "Let It Rip India" is the entity that issues the invoice.
|
|
269
|
+
*/
|
|
270
|
+
business?: AppkitBusinessConfig;
|
|
149
271
|
/** SEO defaults — siteUrl, defaultTitle, OG image, Twitter handle */
|
|
150
272
|
seo?: AppkitSeoConfig;
|
|
151
273
|
/** i18n / next-intl routing options */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { STANDARD_MAX_QTY_PER_LINE } from "../../checkout/rules/_limits.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
const cartItemBaseSchema = z.object({
|
|
3
4
|
productId: z.string().min(1),
|
|
@@ -7,7 +8,7 @@ const cartItemBaseSchema = z.object({
|
|
|
7
8
|
currency: z.string().default("INR"),
|
|
8
9
|
storeId: z.string(),
|
|
9
10
|
storeName: z.string().default(""),
|
|
10
|
-
quantity: z.number().int().min(1).max(
|
|
11
|
+
quantity: z.number().int().min(1).max(STANDARD_MAX_QTY_PER_LINE).default(1),
|
|
11
12
|
// SB1-G Phase 4 — canonical listing-kind snapshot.
|
|
12
13
|
// SB-UNI-D — "bundle" removed from the listing-kind enum.
|
|
13
14
|
/*
|
|
@@ -41,7 +42,7 @@ const cartItemBaseSchema = z.object({
|
|
|
41
42
|
export const addToCartSchema = cartItemBaseSchema;
|
|
42
43
|
export const updateCartItemSchema = z.object({
|
|
43
44
|
productId: z.string().min(1),
|
|
44
|
-
quantity: z.number().int().min(1).max(
|
|
45
|
+
quantity: z.number().int().min(1).max(STANDARD_MAX_QTY_PER_LINE),
|
|
45
46
|
});
|
|
46
47
|
export const removeFromCartSchema = z.object({
|
|
47
48
|
productId: z.string().min(1),
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a seller or admin may constrain about a self-assembled selection.
|
|
3
|
+
*
|
|
4
|
+
* 🛑 These are limits on the SELECTION, never on stock. Stock is independent
|
|
5
|
+
* per listing (there is no pool and no bill of materials) — a spare attack ring
|
|
6
|
+
* is one object the seller happens to have. These answer "what counts as a
|
|
7
|
+
* valid mix", which is a merchandising decision.
|
|
8
|
+
*/
|
|
9
|
+
export interface GroupRules {
|
|
10
|
+
/** Fewest DISTINCT members a valid selection may contain. */
|
|
11
|
+
groupMinMembers?: number;
|
|
12
|
+
/** Most distinct members. */
|
|
13
|
+
groupMaxMembers?: number;
|
|
14
|
+
/** Ceiling on units of any ONE member, independent of the line total. */
|
|
15
|
+
groupMaxUnitsPerMember?: number;
|
|
16
|
+
/** Product ids that must be present for the selection to be valid. */
|
|
17
|
+
groupRequiredMemberIds?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Percentage off the selection's subtotal, 0–100.
|
|
20
|
+
*
|
|
21
|
+
* 🛑 Carried here but NOT applied here, and that separation is deliberate.
|
|
22
|
+
* The discount has to land inside the repository's private `deriveLinePrice`,
|
|
23
|
+
* which runs on every `groupMembers` write and feeds
|
|
24
|
+
* `expandCartLineToOrderRows`' per-member GST proration via
|
|
25
|
+
* `allocateAcrossMembers`. Applying it in a second place is how the cart
|
|
26
|
+
* total comes to disagree with the invoice (Root Cause #75), so this module
|
|
27
|
+
* only ever REPORTS the figure.
|
|
28
|
+
*/
|
|
29
|
+
groupDiscountPercent?: number;
|
|
30
|
+
}
|
|
31
|
+
export declare const EMPTY_GROUP_RULES: GroupRules;
|
|
32
|
+
/** Whichever document the rules were read off. */
|
|
33
|
+
export type GroupRuleSource = "product-group" | "grouped-listing";
|
|
34
|
+
/**
|
|
35
|
+
* Read the rules off either home.
|
|
36
|
+
*
|
|
37
|
+
* Structurally typed on purpose: a product group's rules live on the PARENT
|
|
38
|
+
* product document and a grouped listing's on its own, and both are just
|
|
39
|
+
* objects carrying these optional keys. Taking `ProductDocument |
|
|
40
|
+
* GroupedListingDocument` here would drag two feature schemas into a shared
|
|
41
|
+
* module for no gain — and this module is imported by a client component.
|
|
42
|
+
*/
|
|
43
|
+
export declare function readGroupRules(doc: Partial<GroupRules> | null | undefined): GroupRules;
|
|
44
|
+
export interface GroupRuleViolation {
|
|
45
|
+
code: "GROUP_TOO_FEW_MEMBERS" | "GROUP_TOO_MANY_MEMBERS" | "GROUP_MEMBER_QTY_EXCEEDED" | "GROUP_REQUIRED_MEMBER_MISSING";
|
|
46
|
+
/** Buyer-facing, already specific. Never a raw field name. */
|
|
47
|
+
message: string;
|
|
48
|
+
}
|
|
49
|
+
/** One chosen member: which product, and how many of it. */
|
|
50
|
+
export interface GroupSelectionEntry {
|
|
51
|
+
productId: string;
|
|
52
|
+
quantity: number;
|
|
53
|
+
/** For the message. Falls back to the id when the caller has no title. */
|
|
54
|
+
title?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check a selection against the rules.
|
|
58
|
+
*
|
|
59
|
+
* Returns ALL violations rather than the first, because a picker shows them
|
|
60
|
+
* together and fixing one at a time is a worse experience than seeing the set.
|
|
61
|
+
* The server throws on the first; that is the caller's choice, not this
|
|
62
|
+
* function's.
|
|
63
|
+
*
|
|
64
|
+
* Entries at quantity 0 are ignored — the picker's stepper has `min={0}` and
|
|
65
|
+
* zero means "not chosen", so counting them would make an untouched member
|
|
66
|
+
* count toward `groupMinMembers`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function checkGroupRules(rules: GroupRules, selection: readonly GroupSelectionEntry[]): GroupRuleViolation[];
|
|
69
|
+
/**
|
|
70
|
+
* The rules in words, for the picker's header.
|
|
71
|
+
*
|
|
72
|
+
* Returns an empty array when nothing is restricted, so the caller renders
|
|
73
|
+
* nothing rather than an empty box saying "Rules:".
|
|
74
|
+
*/
|
|
75
|
+
export declare function describeGroupRules(rules: GroupRules): string[];
|