@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.
Files changed (520) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/scaffolds/AppShell.js +1 -1
  3. package/dist/_internal/client/theme/ThemeProvider.js +15 -1
  4. package/dist/_internal/server/features/auctions/og.d.ts +3 -1
  5. package/dist/_internal/server/features/auctions/og.js +3 -1
  6. package/dist/_internal/server/features/bundles/actions.js +1 -1
  7. package/dist/_internal/server/features/business-documents/download.d.ts +41 -0
  8. package/dist/_internal/server/features/business-documents/download.js +91 -0
  9. package/dist/_internal/server/features/categories/adapters.d.ts +1 -1
  10. package/dist/_internal/server/features/categories/adapters.js +10 -0
  11. package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
  12. package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
  13. package/dist/_internal/server/features/checkout/actions.d.ts +14 -0
  14. package/dist/_internal/server/features/checkout/actions.js +106 -12
  15. package/dist/_internal/server/features/checkout/bundle-expansion.js +17 -0
  16. package/dist/_internal/server/features/checkout/data.d.ts +22 -0
  17. package/dist/_internal/server/features/checkout/group-rule-revalidation.d.ts +34 -0
  18. package/dist/_internal/server/features/checkout/group-rule-revalidation.js +124 -0
  19. package/dist/_internal/server/features/checkout/supplier-identity.d.ts +55 -0
  20. package/dist/_internal/server/features/checkout/supplier-identity.js +81 -0
  21. package/dist/_internal/server/features/classified/metadata.js +1 -1
  22. package/dist/_internal/server/features/classified/og.d.ts +3 -1
  23. package/dist/_internal/server/features/classified/og.js +3 -1
  24. package/dist/_internal/server/features/digital-code/metadata.js +1 -1
  25. package/dist/_internal/server/features/digital-code/og.d.ts +3 -1
  26. package/dist/_internal/server/features/digital-code/og.js +3 -1
  27. package/dist/_internal/server/features/digital-code/pool.d.ts +19 -4
  28. package/dist/_internal/server/features/digital-code/pool.js +19 -4
  29. package/dist/_internal/server/features/live/metadata.js +1 -1
  30. package/dist/_internal/server/features/live/og.d.ts +3 -1
  31. package/dist/_internal/server/features/live/og.js +3 -1
  32. package/dist/_internal/server/features/messages/actions.js +1 -1
  33. package/dist/_internal/server/features/parts/og.js +1 -1
  34. package/dist/_internal/server/features/pre-orders/og.d.ts +3 -1
  35. package/dist/_internal/server/features/pre-orders/og.js +3 -1
  36. package/dist/_internal/server/features/price-index/market.d.ts +57 -0
  37. package/dist/_internal/server/features/price-index/market.js +120 -0
  38. package/dist/_internal/server/features/price-index/search.d.ts +18 -0
  39. package/dist/_internal/server/features/price-index/search.js +47 -7
  40. package/dist/_internal/server/features/prize-draws/og.d.ts +3 -1
  41. package/dist/_internal/server/features/prize-draws/og.js +3 -1
  42. package/dist/_internal/server/features/products/group-members.d.ts +26 -0
  43. package/dist/_internal/server/features/products/group-members.js +7 -1
  44. package/dist/_internal/server/features/products/list-public.d.ts +12 -0
  45. package/dist/_internal/server/features/products/list-public.js +10 -1
  46. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
  47. package/dist/_internal/server/features/products/listing-tab-counts.js +128 -10
  48. package/dist/_internal/server/features/products/og.d.ts +3 -1
  49. package/dist/_internal/server/features/products/og.js +3 -1
  50. package/dist/_internal/server/features/search/scoped-sources.d.ts +26 -0
  51. package/dist/_internal/server/features/search/scoped-sources.js +252 -0
  52. package/dist/_internal/server/features/search/search-everything.d.ts +57 -0
  53. package/dist/_internal/server/features/search/search-everything.js +70 -20
  54. package/dist/_internal/server/features/seo/sitemap.js +6 -0
  55. package/dist/_internal/server/features/shared/listing-adapters.js +4 -2
  56. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +11 -0
  57. package/dist/_internal/server/features/sticker-trace/adapters.js +1 -0
  58. package/dist/_internal/server/features/sticker-trace/promote-to-listings.d.ts +26 -0
  59. package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +264 -0
  60. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +3 -1
  61. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +32 -0
  62. package/dist/_internal/server/features/sticker-trace/storage.d.ts +20 -1
  63. package/dist/_internal/server/features/sticker-trace/storage.js +20 -1
  64. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  65. package/dist/_internal/server/features/stores/adapters.js +16 -0
  66. package/dist/_internal/server/features/stores/index.d.ts +1 -0
  67. package/dist/_internal/server/features/stores/index.js +1 -0
  68. package/dist/_internal/server/features/stores/tabs.d.ts +30 -0
  69. package/dist/_internal/server/features/stores/tabs.js +124 -0
  70. package/dist/_internal/shared/checkout/rules/_defaults.js +0 -2
  71. package/dist/_internal/shared/checkout/rules/_limits.d.ts +14 -1
  72. package/dist/_internal/shared/checkout/rules/_limits.js +14 -1
  73. package/dist/_internal/shared/checkout/rules/_registry.js +2 -0
  74. package/dist/_internal/shared/checkout/rules/auction.rule.js +9 -1
  75. package/dist/_internal/shared/checkout/rules/bundle.rule.js +13 -0
  76. package/dist/_internal/shared/checkout/rules/index.d.ts +2 -0
  77. package/dist/_internal/shared/checkout/rules/index.js +9 -0
  78. package/dist/_internal/shared/checkout/rules/offer.rule.js +0 -1
  79. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +26 -0
  80. package/dist/_internal/shared/checkout/rules/payment-gate.js +133 -0
  81. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +29 -8
  82. package/dist/_internal/shared/checkout/rules/spares.rule.d.ts +16 -0
  83. package/dist/_internal/shared/checkout/rules/spares.rule.js +5 -0
  84. package/dist/_internal/shared/checkout/rules/types.d.ts +26 -2
  85. package/dist/_internal/shared/config/schema.d.ts +122 -0
  86. package/dist/_internal/shared/features/cart/schema.js +3 -2
  87. package/dist/_internal/shared/features/products/group-rules.d.ts +75 -0
  88. package/dist/_internal/shared/features/products/group-rules.js +142 -0
  89. package/dist/_internal/shared/listing-types/_registry.d.ts +24 -0
  90. package/dist/_internal/shared/listing-types/_registry.js +39 -1
  91. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  92. package/dist/_internal/shared/listing-types/art/config.js +2 -0
  93. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  94. package/dist/_internal/shared/listing-types/auction/config.js +2 -0
  95. package/dist/_internal/shared/listing-types/availability.js +48 -0
  96. package/dist/_internal/shared/listing-types/capabilities.js +19 -0
  97. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  98. package/dist/_internal/shared/listing-types/classified/config.js +2 -0
  99. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  100. package/dist/_internal/shared/listing-types/digital-code/config.js +2 -0
  101. package/dist/_internal/shared/listing-types/feature-flags.js +1 -0
  102. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  103. package/dist/_internal/shared/listing-types/live/config.js +2 -0
  104. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  105. package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
  106. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  107. package/dist/_internal/shared/listing-types/prize-draw/config.js +2 -0
  108. package/dist/_internal/shared/listing-types/spares/config.d.ts +74 -0
  109. package/dist/_internal/shared/listing-types/spares/config.js +60 -0
  110. package/dist/_internal/shared/listing-types/spares/ctas.d.ts +1 -0
  111. package/dist/_internal/shared/listing-types/spares/ctas.js +4 -0
  112. package/dist/_internal/shared/listing-types/spares/og.js +1 -0
  113. package/dist/_internal/shared/listing-types/spares/schema.d.ts +2 -0
  114. package/dist/_internal/shared/listing-types/spares/schema.js +3 -0
  115. package/dist/_internal/shared/listing-types/spares/seed-factory.d.ts +1 -0
  116. package/dist/_internal/shared/listing-types/spares/seed-factory.js +1 -0
  117. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  118. package/dist/_internal/shared/listing-types/standard/config.js +2 -0
  119. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  120. package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
  121. package/dist/_internal/shared/search/match.d.ts +11 -0
  122. package/dist/_internal/shared/search/match.js +30 -3
  123. package/dist/_internal/shared/search/to-groups.d.ts +52 -0
  124. package/dist/_internal/shared/search/to-groups.js +141 -0
  125. package/dist/client.d.ts +8 -2
  126. package/dist/client.js +4 -1
  127. package/dist/constants/api-endpoints.d.ts +46 -15
  128. package/dist/constants/api-endpoints.js +35 -5
  129. package/dist/constants/cache-invalidation.js +3 -1
  130. package/dist/constants/field-names.d.ts +6 -0
  131. package/dist/constants/field-names.js +6 -0
  132. package/dist/features/about/components/PolicyPageView.d.ts +22 -2
  133. package/dist/features/about/components/PolicyPageView.js +14 -2
  134. package/dist/features/about/components/PublicProfileView.js +2 -1
  135. package/dist/features/about/components/ShippingPolicyView.js +42 -2
  136. package/dist/features/account/components/NotificationBell.js +1 -1
  137. package/dist/features/account/hooks/useProfileStats.js +5 -1
  138. package/dist/features/addresses/repository/addresses.repository.d.ts +16 -0
  139. package/dist/features/addresses/repository/addresses.repository.js +21 -0
  140. package/dist/features/admin/actions/admin-actions.js +16 -1
  141. package/dist/features/admin/components/AdminCategoryEditorView.js +19 -2
  142. package/dist/features/admin/components/AdminNavigationView.js +1 -1
  143. package/dist/features/admin/components/AdminPageHeader.js +1 -1
  144. package/dist/features/admin/components/AdminProductEditorView.js +17 -2
  145. package/dist/features/admin/components/AdminSidebar.js +1 -1
  146. package/dist/features/admin/components/AdminSiteSettingsView.js +39 -8
  147. package/dist/features/admin/components/AdminSparesView.d.ts +12 -0
  148. package/dist/features/admin/components/AdminSparesView.js +30 -0
  149. package/dist/features/admin/components/AdminUsersView.js +9 -7
  150. package/dist/features/admin/components/index.d.ts +2 -0
  151. package/dist/features/admin/components/index.js +1 -0
  152. package/dist/features/admin/components/sections/adminSectionsTypes.js +7 -0
  153. package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
  154. package/dist/features/admin/constants/filter-tabs.js +1 -0
  155. package/dist/features/admin/schemas/firestore.d.ts +26 -2
  156. package/dist/features/auctions/components/AuctionDetailPageView.js +12 -18
  157. package/dist/features/auth/repository/user.repository.d.ts +13 -0
  158. package/dist/features/auth/repository/user.repository.js +28 -0
  159. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  160. package/dist/features/auth/schemas/firestore.js +2 -0
  161. package/dist/features/business-documents/repository/business-documents.repository.d.ts +58 -0
  162. package/dist/features/business-documents/repository/business-documents.repository.js +54 -0
  163. package/dist/features/business-documents/schemas/firestore.d.ts +105 -0
  164. package/dist/features/business-documents/schemas/firestore.js +75 -0
  165. package/dist/features/cart/actions/cart-actions.js +83 -6
  166. package/dist/features/cart/repository/cart.repository.js +32 -4
  167. package/dist/features/cart/schemas/firestore.d.ts +20 -0
  168. package/dist/features/cart/schemas/index.d.ts +2 -2
  169. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +1 -1
  170. package/dist/features/categories/api/[id]/price-guidance/route.d.ts +42 -0
  171. package/dist/features/categories/api/[id]/price-guidance/route.js +90 -0
  172. package/dist/features/categories/components/BrandDetailPageView.js +32 -8
  173. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
  174. package/dist/features/categories/components/BrandDetailTabs.js +28 -3
  175. package/dist/features/categories/components/BundleCollage.js +3 -2
  176. package/dist/features/categories/components/BundleItemsPicker.js +3 -4
  177. package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
  178. package/dist/features/categories/components/CategoryDetailPageView.js +157 -20
  179. package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
  180. package/dist/features/categories/components/CategoryDetailTabs.js +41 -7
  181. package/dist/features/categories/components/CategoryGrid.js +10 -1
  182. package/dist/features/categories/components/PriceGuidanceHint.d.ts +29 -0
  183. package/dist/features/categories/components/PriceGuidanceHint.js +61 -0
  184. package/dist/features/categories/components/SubcategoryCardRow.d.ts +27 -0
  185. package/dist/features/categories/components/SubcategoryCardRow.js +98 -0
  186. package/dist/features/categories/constants/category-tabs.d.ts +20 -25
  187. package/dist/features/categories/constants/category-tabs.js +22 -39
  188. package/dist/features/categories/repository/categories.repository.d.ts +12 -0
  189. package/dist/features/categories/repository/categories.repository.js +20 -0
  190. package/dist/features/categories/schemas/firestore.d.ts +22 -1
  191. package/dist/features/categories/schemas/firestore.js +10 -0
  192. package/dist/features/categories/schemas/index.d.ts +6 -0
  193. package/dist/features/categories/schemas/index.js +2 -0
  194. package/dist/features/categories/types/index.d.ts +8 -0
  195. package/dist/features/categories/utils/taxonomy-visual.d.ts +16 -3
  196. package/dist/features/categories/utils/taxonomy-visual.js +26 -10
  197. package/dist/features/classified/components/ClassifiedDetailPageView.js +14 -10
  198. package/dist/features/contact/components/ContactPageView.d.ts +33 -1
  199. package/dist/features/contact/components/ContactPageView.js +58 -28
  200. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +14 -10
  201. package/dist/features/grouped/components/GroupedListingDetailView.js +9 -1
  202. package/dist/features/grouped/schemas/firestore.d.ts +5 -0
  203. package/dist/features/homepage/actions/homepage-section-actions.d.ts +3 -3
  204. package/dist/features/homepage/components/CollectionCardsSection.d.ts +28 -6
  205. package/dist/features/homepage/components/CollectionCardsSection.js +43 -8
  206. package/dist/features/homepage/components/HowItWorksSection.d.ts +23 -6
  207. package/dist/features/homepage/components/HowItWorksSection.js +4 -4
  208. package/dist/features/homepage/components/PromoGrid.d.ts +31 -2
  209. package/dist/features/homepage/components/PromoGrid.js +12 -3
  210. package/dist/features/homepage/components/TestimonialsCarousel.d.ts +34 -2
  211. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  212. package/dist/features/homepage/components/index.d.ts +0 -20
  213. package/dist/features/homepage/components/index.js +0 -11
  214. package/dist/features/homepage/index.d.ts +0 -2
  215. package/dist/features/homepage/index.js +0 -2
  216. package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
  217. package/dist/features/homepage/lib/section-renderer.js +202 -58
  218. package/dist/features/homepage/repository/homepage-sections.repository.d.ts +35 -3
  219. package/dist/features/homepage/repository/homepage-sections.repository.js +58 -8
  220. package/dist/features/homepage/schemas/firestore.d.ts +106 -3
  221. package/dist/features/homepage/schemas/firestore.js +32 -2
  222. package/dist/features/homepage/schemas/index.d.ts +36 -7
  223. package/dist/features/homepage/schemas/index.js +39 -27
  224. package/dist/features/homepage/server.d.ts +0 -3
  225. package/dist/features/homepage/server.js +0 -3
  226. package/dist/features/homepage/types/index.d.ts +0 -47
  227. package/dist/features/homepage/types/index.js +49 -0
  228. package/dist/features/layout/AppLayoutShell.js +1 -1
  229. package/dist/features/layout/BottomNavItem.js +1 -1
  230. package/dist/features/layout/BottomSheet.js +1 -1
  231. package/dist/features/layout/TitleBarLayout.js +1 -1
  232. package/dist/features/live/components/LiveItemDetailPageView.js +14 -10
  233. package/dist/features/media/hooks/useMedia.js +17 -0
  234. package/dist/features/media/repository/media-assets.repository.d.ts +46 -0
  235. package/dist/features/media/repository/media-assets.repository.js +31 -0
  236. package/dist/features/media/trust-signals.d.ts +85 -0
  237. package/dist/features/media/trust-signals.js +126 -0
  238. package/dist/features/parts/components/PartDetailPageView.d.ts +14 -1
  239. package/dist/features/parts/components/PartDetailPageView.js +2 -2
  240. package/dist/features/parts/components/PartsIndexPageView.d.ts +11 -2
  241. package/dist/features/parts/components/PartsIndexPageView.js +2 -2
  242. package/dist/features/parts/components/PartsSearchBox.d.ts +9 -0
  243. package/dist/features/parts/components/PartsSearchBox.js +57 -0
  244. package/dist/features/parts/schemas/firestore.d.ts +149 -3
  245. package/dist/features/parts/schemas/firestore.js +184 -0
  246. package/dist/features/payments/repository/payout.repository.d.ts +15 -0
  247. package/dist/features/payments/repository/payout.repository.js +21 -0
  248. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -18
  249. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
  250. package/dist/features/price-index/components/PriceIndexToolView.d.ts +24 -1
  251. package/dist/features/price-index/components/PriceIndexToolView.js +299 -17
  252. package/dist/features/price-index/lookup-target.d.ts +48 -0
  253. package/dist/features/price-index/lookup-target.js +107 -0
  254. package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
  255. package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
  256. package/dist/features/products/components/CompareOverlay.d.ts +20 -2
  257. package/dist/features/products/components/CompareOverlay.js +23 -3
  258. package/dist/features/products/components/CustomSectionTabContent.d.ts +31 -0
  259. package/dist/features/products/components/CustomSectionTabContent.js +29 -3
  260. package/dist/features/products/components/GroupMemberPicker.d.ts +19 -1
  261. package/dist/features/products/components/GroupMemberPicker.js +46 -8
  262. package/dist/features/products/components/GroupSettingsPanel.d.ts +11 -1
  263. package/dist/features/products/components/GroupSettingsPanel.js +92 -3
  264. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  265. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +15 -1
  266. package/dist/features/products/components/PrizeDrawEntryActions.js +70 -8
  267. package/dist/features/products/components/ProductDetailPageView.js +81 -17
  268. package/dist/features/products/components/ProductForm.d.ts +13 -1
  269. package/dist/features/products/components/ProductForm.js +16 -2
  270. package/dist/features/products/components/ProductsIndexListing.d.ts +16 -1
  271. package/dist/features/products/components/ProductsIndexListing.js +3 -3
  272. package/dist/features/products/components/ShowGroupSection.js +15 -2
  273. package/dist/features/products/components/SparesListView.d.ts +7 -0
  274. package/dist/features/products/components/SparesListView.js +39 -0
  275. package/dist/features/products/components/SublistingCarouselSection.js +2 -1
  276. package/dist/features/products/constants/action-defs.d.ts +1 -0
  277. package/dist/features/products/constants/action-defs.js +1 -0
  278. package/dist/features/products/repository/products.repository.d.ts +99 -0
  279. package/dist/features/products/repository/products.repository.js +240 -18
  280. package/dist/features/products/schemas/firestore.d.ts +97 -4
  281. package/dist/features/products/schemas/firestore.js +104 -0
  282. package/dist/features/products/schemas/index.d.ts +10 -19
  283. package/dist/features/products/schemas/index.js +23 -6
  284. package/dist/features/products/types/index.d.ts +45 -1
  285. package/dist/features/products/utils/group-member-image.d.ts +46 -0
  286. package/dist/features/products/utils/group-member-image.js +4 -0
  287. package/dist/features/products/utils/listing-badge-variant.js +4 -0
  288. package/dist/features/reviews/components/ReviewsList.js +1 -1
  289. package/dist/features/scams/components/ScamProfileView.js +1 -1
  290. package/dist/features/search/components/EntityTypeahead.d.ts +44 -0
  291. package/dist/features/search/components/EntityTypeahead.js +92 -0
  292. package/dist/features/search/components/Search.d.ts +12 -1
  293. package/dist/features/search/components/Search.js +47 -3
  294. package/dist/features/search/components/SearchFacetRail.d.ts +11 -0
  295. package/dist/features/search/components/SearchFacetRail.js +92 -0
  296. package/dist/features/search/components/SearchResultsClient.d.ts +33 -0
  297. package/dist/features/search/components/SearchResultsClient.js +103 -0
  298. package/dist/features/search/components/SearchResultsPageView.d.ts +15 -1
  299. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  300. package/dist/features/search/components/index.d.ts +0 -6
  301. package/dist/features/search/components/index.js +0 -3
  302. package/dist/features/search/hooks/useNavSuggestions.d.ts +13 -0
  303. package/dist/features/search/hooks/useScopedSearch.d.ts +34 -0
  304. package/dist/features/search/hooks/useScopedSearch.js +114 -0
  305. package/dist/features/search/hooks/useSiteSearch.d.ts +26 -0
  306. package/dist/features/search/hooks/useSiteSearch.js +149 -0
  307. package/dist/features/search/index.d.ts +0 -4
  308. package/dist/features/search/index.js +0 -4
  309. package/dist/features/search/manifest.d.ts +12 -0
  310. package/dist/features/search/manifest.js +17 -2
  311. package/dist/features/search/server.d.ts +0 -3
  312. package/dist/features/search/server.js +0 -3
  313. package/dist/features/seller/components/SellerListingTypeView.d.ts +1 -1
  314. package/dist/features/seller/components/SellerListingTypeView.js +20 -0
  315. package/dist/features/seller/components/SellerPayoutSettingsView.js +35 -14
  316. package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
  317. package/dist/features/seller/components/SellerProductShell.js +2 -1
  318. package/dist/features/seller/components/SellerProductsView.js +3 -2
  319. package/dist/features/seller/components/SellerSidebar.js +1 -1
  320. package/dist/features/seller/components/SellerSparesView.d.ts +17 -0
  321. package/dist/features/seller/components/SellerSparesView.js +6 -0
  322. package/dist/features/seller/components/index.d.ts +2 -0
  323. package/dist/features/seller/components/index.js +1 -0
  324. package/dist/features/shell/CommandPalette.js +1 -1
  325. package/dist/features/sticker-trace/schemas/firestore.d.ts +19 -0
  326. package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
  327. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  328. package/dist/features/stores/components/StoreDetailLayoutView.js +7 -82
  329. package/dist/features/stores/components/StoreHeader.js +1 -2
  330. package/dist/features/stores/components/StoreSparesPageView.d.ts +27 -0
  331. package/dist/features/stores/components/StoreSparesPageView.js +48 -0
  332. package/dist/features/stores/schemas/firestore.d.ts +19 -0
  333. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +2 -0
  334. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +96 -0
  335. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  336. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +392 -45
  337. package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +54 -32
  338. package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +3 -2
  339. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +2 -0
  340. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +73 -0
  341. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +2 -0
  342. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +340 -0
  343. package/dist/features/tester/seed-data/authored/index.js +16 -0
  344. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +1 -0
  345. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +57 -0
  346. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +2 -0
  347. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +77 -0
  348. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +2 -0
  349. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +58 -0
  350. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +5 -4
  351. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +384 -18
  352. package/dist/index.d.ts +17 -57
  353. package/dist/index.js +35 -96
  354. package/dist/next/routing/route-map.d.ts +42 -1
  355. package/dist/next/routing/route-map.js +45 -0
  356. package/dist/providers/db-firebase/base.repository.d.ts +22 -0
  357. package/dist/providers/db-firebase/base.repository.js +36 -0
  358. package/dist/schemas/registry.d.ts +15 -6
  359. package/dist/security/blind-index-tokens.d.ts +54 -0
  360. package/dist/security/blind-index-tokens.js +152 -0
  361. package/dist/security/index.d.ts +1 -1
  362. package/dist/security/index.js +1 -1
  363. package/dist/security/settings-encryption.d.ts +35 -0
  364. package/dist/security/settings-encryption.js +91 -0
  365. package/dist/seed/_helpers/brand-rows.js +38 -14
  366. package/dist/seed/_helpers/category-forest.js +73 -7
  367. package/dist/seed/_helpers/category-images-generated.d.ts +25 -6
  368. package/dist/seed/_helpers/category-images-generated.js +81 -6
  369. package/dist/seed/_helpers/category-models.d.ts +1 -1
  370. package/dist/seed/_helpers/category-models.js +7 -1
  371. package/dist/seed/_helpers/category-parts-glossary-map.js +8 -0
  372. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  373. package/dist/seed/_helpers/category-parts.js +50 -2
  374. package/dist/seed/_helpers/character-features.d.ts +1 -1
  375. package/dist/seed/_helpers/character-features.js +2 -1
  376. package/dist/seed/_helpers/franchise-rows.js +10 -2
  377. package/dist/seed/_helpers/media.d.ts +47 -0
  378. package/dist/seed/_helpers/media.js +34 -0
  379. package/dist/seed/authenticity-knowledge-seed-data.d.ts +49 -5
  380. package/dist/seed/authenticity-knowledge-seed-data.js +10001 -549
  381. package/dist/seed/categories-seed-data.js +124 -20
  382. package/dist/seed/grouped-listings-seed-data.js +16 -0
  383. package/dist/seed/homepage-sections-seed-data.js +94 -5
  384. package/dist/seed/index.d.ts +2 -3
  385. package/dist/seed/index.js +2 -2
  386. package/dist/seed/manifest.js +3 -0
  387. package/dist/seed/media-assets-seed-data.d.ts +1 -1
  388. package/dist/seed/media-assets-seed-data.js +746 -196
  389. package/dist/seed/model-composition-seed-data.js +122 -6
  390. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  391. package/dist/seed/part-glossary-seed-data.js +37219 -463
  392. package/dist/seed/products-art-seed-data.js +7 -18
  393. package/dist/seed/products-auctions-seed-data.js +56 -47
  394. package/dist/seed/products-beyblade-x-seed-data.d.ts +2 -0
  395. package/dist/seed/products-beyblade-x-seed-data.js +476 -0
  396. package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
  397. package/dist/seed/products-catalogue-seed-data.js +1500 -1240
  398. package/dist/seed/products-classifieds-seed-data.js +9 -27
  399. package/dist/seed/products-digital-codes-seed-data.js +9 -18
  400. package/dist/seed/products-live-items-seed-data.js +5 -13
  401. package/dist/seed/products-preorders-seed-data.js +67 -33
  402. package/dist/seed/products-prize-draws-seed-data.js +8 -17
  403. package/dist/seed/products-spares-seed-data.d.ts +2 -0
  404. package/dist/seed/products-spares-seed-data.js +368 -0
  405. package/dist/seed/products-standard-seed-data.js +39 -126
  406. package/dist/seed/products-stickers-seed-data.js +59 -15
  407. package/dist/seed/site-settings-seed-data.js +8 -0
  408. package/dist/seo/json-ld.d.ts +25 -0
  409. package/dist/seo/json-ld.js +28 -0
  410. package/dist/server-entry.d.ts +3 -1
  411. package/dist/server-entry.js +2 -2
  412. package/dist/server.d.ts +11 -9
  413. package/dist/server.js +35 -25
  414. package/dist/styles.css +202 -1
  415. package/dist/tailwind-input.css +31 -17
  416. package/dist/tailwind-utilities.css +1 -1
  417. package/dist/ui/components/Accordion.js +1 -1
  418. package/dist/ui/components/Breadcrumb.js +1 -1
  419. package/dist/ui/components/DetailPageGallery.js +0 -2
  420. package/dist/ui/components/DetailPageHero.js +0 -1
  421. package/dist/ui/components/DetailPageTabs.js +1 -1
  422. package/dist/ui/components/Divider.js +3 -3
  423. package/dist/ui/components/GatedPrice.js +5 -1
  424. package/dist/ui/components/HorizontalScroller.js +1 -1
  425. package/dist/ui/components/ListingLayout.js +3 -3
  426. package/dist/ui/components/MediaTabs.style.css +81 -0
  427. package/dist/ui/components/Pagination.js +1 -1
  428. package/dist/ui/components/PendingValue.d.ts +45 -0
  429. package/dist/ui/components/PendingValue.js +7 -0
  430. package/dist/ui/components/Radio.style.css +119 -0
  431. package/dist/ui/components/RatingDisplay.js +2 -2
  432. package/dist/ui/components/SettingsSection.js +0 -2
  433. package/dist/ui/components/SiteLogo.js +3 -0
  434. package/dist/ui/components/SiteMark.js +3 -0
  435. package/dist/ui/components/SortDropdown.js +1 -1
  436. package/dist/ui/components/SpecTable.d.ts +58 -0
  437. package/dist/ui/components/SpecTable.js +8 -0
  438. package/dist/ui/components/StarRating.js +1 -3
  439. package/dist/ui/components/SummaryCard.js +1 -1
  440. package/dist/ui/components/index.style.css +1 -0
  441. package/dist/ui/icons/icon-registry.d.ts +1 -0
  442. package/dist/ui/icons/icon-registry.js +9 -1
  443. package/dist/ui/index.d.ts +4 -0
  444. package/dist/ui/index.js +2 -0
  445. package/dist/utils/search-txt-query.d.ts +12 -0
  446. package/dist/utils/search-txt-query.js +12 -0
  447. package/package.json +1 -1
  448. package/scripts/dedupe-peer-deps.mjs +18 -0
  449. package/scripts/seed-cli.mjs +250 -35
  450. package/scripts/verify-css-build.mjs +118 -37
  451. package/dist/_internal/server/features/search/actions.d.ts +0 -7
  452. package/dist/_internal/server/features/search/actions.js +0 -21
  453. package/dist/_internal/server/features/search/data.d.ts +0 -15
  454. package/dist/_internal/server/features/search/data.js +0 -18
  455. package/dist/_internal/server/features/search/index.d.ts +0 -3
  456. package/dist/_internal/server/features/search/index.js +0 -2
  457. package/dist/features/homepage/api/[id]/route.d.ts +0 -23
  458. package/dist/features/homepage/api/[id]/route.js +0 -103
  459. package/dist/features/homepage/api/route.d.ts +0 -14
  460. package/dist/features/homepage/api/route.js +0 -140
  461. package/dist/features/homepage/api/sections/[id]/route.d.ts +0 -26
  462. package/dist/features/homepage/api/sections/[id]/route.js +0 -95
  463. package/dist/features/homepage/api/sections/route.d.ts +0 -13
  464. package/dist/features/homepage/api/sections/route.js +0 -82
  465. package/dist/features/homepage/components/AdvertisementBanner.d.ts +0 -14
  466. package/dist/features/homepage/components/AdvertisementBanner.js +0 -35
  467. package/dist/features/homepage/components/BeforeAfterCard.d.ts +0 -9
  468. package/dist/features/homepage/components/BeforeAfterCard.js +0 -73
  469. package/dist/features/homepage/components/FeaturedResultsSection.d.ts +0 -17
  470. package/dist/features/homepage/components/FeaturedResultsSection.js +0 -17
  471. package/dist/features/homepage/components/HeroBanner.d.ts +0 -7
  472. package/dist/features/homepage/components/HeroBanner.js +0 -43
  473. package/dist/features/homepage/components/HeroSection.d.ts +0 -7
  474. package/dist/features/homepage/components/HeroSection.js +0 -6
  475. package/dist/features/homepage/components/HomepageSkeleton.d.ts +0 -2
  476. package/dist/features/homepage/components/HomepageSkeleton.js +0 -21
  477. package/dist/features/homepage/components/HomepageView.d.ts +0 -25
  478. package/dist/features/homepage/components/HomepageView.js +0 -5
  479. package/dist/features/homepage/components/NewsletterBanner.d.ts +0 -23
  480. package/dist/features/homepage/components/NewsletterBanner.js +0 -37
  481. package/dist/features/homepage/components/SiteFeaturesSection.d.ts +0 -14
  482. package/dist/features/homepage/components/SiteFeaturesSection.js +0 -11
  483. package/dist/features/homepage/components/TrustBadges.d.ts +0 -6
  484. package/dist/features/homepage/components/TrustBadges.js +0 -46
  485. package/dist/features/homepage/components/TrustIndicatorsSection.d.ts +0 -12
  486. package/dist/features/homepage/components/TrustIndicatorsSection.js +0 -11
  487. package/dist/features/homepage/hooks/useHomepage.d.ts +0 -11
  488. package/dist/features/homepage/hooks/useHomepage.js +0 -17
  489. package/dist/features/homepage/hooks/useHomepageSections.d.ts +0 -2
  490. package/dist/features/homepage/hooks/useHomepageSections.js +0 -10
  491. package/dist/features/homepage/repository/homepage.repository.d.ts +0 -11
  492. package/dist/features/homepage/repository/homepage.repository.js +0 -25
  493. package/dist/features/search/actions/index.d.ts +0 -1
  494. package/dist/features/search/actions/index.js +0 -1
  495. package/dist/features/search/actions/search-actions.d.ts +0 -18
  496. package/dist/features/search/actions/search-actions.js +0 -43
  497. package/dist/features/search/api/route.d.ts +0 -22
  498. package/dist/features/search/api/route.js +0 -128
  499. package/dist/features/search/columns/index.d.ts +0 -17
  500. package/dist/features/search/columns/index.js +0 -49
  501. package/dist/features/search/components/SearchFiltersRow.d.ts +0 -22
  502. package/dist/features/search/components/SearchFiltersRow.js +0 -21
  503. package/dist/features/search/components/SearchResultsSection.d.ts +0 -53
  504. package/dist/features/search/components/SearchResultsSection.js +0 -35
  505. package/dist/features/search/components/SearchView.d.ts +0 -27
  506. package/dist/features/search/components/SearchView.js +0 -8
  507. package/dist/features/search/hooks/useSearch.d.ts +0 -21
  508. package/dist/features/search/hooks/useSearch.js +0 -33
  509. package/dist/features/search/repository/search.repository.d.ts +0 -14
  510. package/dist/features/search/repository/search.repository.js +0 -59
  511. package/dist/features/search/schemas/index.d.ts +0 -70
  512. package/dist/features/search/schemas/index.js +0 -36
  513. package/dist/features/search/types/index.d.ts +0 -48
  514. package/dist/features/stores/components/StoreScopedSearch.d.ts +0 -17
  515. package/dist/features/stores/components/StoreScopedSearch.js +0 -27
  516. package/dist/seed/defaults/homepage-sections.d.ts +0 -2
  517. package/dist/seed/defaults/homepage-sections.js +0 -60
  518. package/dist/seed/factories/homepage-section.factory.d.ts +0 -10
  519. package/dist/seed/factories/homepage-section.factory.js +0 -13
  520. /package/dist/{features/search/types/index.js → _internal/shared/listing-types/spares/og.d.ts} +0 -0
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "stampVersion": 1,
3
- "version": "4.53.0",
4
- "head": "78e72eb24243b0ee3afea21614fbbadee45d2b51",
3
+ "version": "4.53.2",
4
+ "head": "94f4715428f35ab362a11a468072ef933ca8a46d",
5
5
  "branch": "main",
6
6
  "dirty": false,
7
- "builtAt": "2026-10-19T12:44:44.499Z"
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: `appkit-app-shell 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] }));
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
- return "auto";
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?: (string | null | undefined)[] | null;
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 || doc?.images?.[0] || null, opts.baseUrl),
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) {
@@ -68,7 +68,7 @@ quantity = 1) {
68
68
  quantity: 1,
69
69
  unitPrice: p.price,
70
70
  title: p.title,
71
- image: p.images?.[0] ?? p.mainImage,
71
+ image: p.images?.[0]?.url ?? p.mainImage,
72
72
  gstRate: p.gstRate,
73
73
  hsnCode: p.hsnCode,
74
74
  listingType: normalizeListingType(p),
@@ -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
  *