@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
package/dist/ui/index.js CHANGED
@@ -30,6 +30,7 @@ export { FormErrorSummary } from "./forms/index.js";
30
30
  export { buildColumns, createColumnBuilder, renderBoolean, renderCurrency, renderCurrencyCompact, renderCount, renderNullable, renderRating, getStatusTone, getResourceIcon, } from "./columns/index.js";
31
31
  export { Section, sectionBackgroundStyle, Article, Main, Aside, Nav, BlockHeader, BlockFooter, Ul, Ol, Li, Table, Thead, Tbody, Tr, Th, Td, Code, Pre, Blockquote, Figure, Figcaption, Dl, Dt, Dd, } from "./components/Semantic.js";
32
32
  export { Div } from "./components/Div.js";
33
+ export { SpecTable } from "./components/SpecTable.js";
33
34
  export { Heading, Text, Label, Caption, Span } from "./components/Typography.js";
34
35
  // --- Filter chip group (SB10-C completion, S8 2026-05-13) --------------------
35
36
  export { FilterChipGroup } from "./components/FilterChipGroup.js";
@@ -156,6 +157,7 @@ export { HorizontalRule } from "./components/HorizontalRule.js";
156
157
  export { Anchor } from "./components/Anchor.js";
157
158
  export { Scrim } from "./components/Scrim.js";
158
159
  export { Kbd } from "./components/Kbd.js";
160
+ export { PendingValue } from "./components/PendingValue.js";
159
161
  export { StickyToolbar } from "./components/StickyToolbar.js";
160
162
  export { Show, Hide } from "./components/Responsive.js";
161
163
  export { CollapsibleSection } from "./components/CollapsibleSection.js";
@@ -87,6 +87,18 @@ export interface SearchWindowModel {
87
87
  *
88
88
  * `refineSearchTxt` grew a real-pagination mode, and `products` was the only
89
89
  * caller converted — deliberately, so the other eleven stayed byte-identical.
90
+ *
91
+ * 🛑 That sentence is now HISTORY, not status. Measured 2026-10-19: ELEVEN
92
+ * repositories use `beginSearchWindow`, and `audit-listing-search-intact`
93
+ * (C6) enforces all three parts of the conversion on each of them — doing
94
+ * parts 1 and 3 without 2 "reads exactly like a working conversion and is
95
+ * the half that no-ops", which is why the audit checks the triple rather
96
+ * than the presence of the call.
97
+ *
98
+ * `faqs` is the deliberate holdout: it hand-rolls the refine and returns the
99
+ * legacy page-only shape, which this file's own docstring describes as
100
+ * "preserved verbatim for unconverted callers". That is a known limitation,
101
+ * not a defect — do not "fix" it as a bug (Rule #4).
90
102
  * The conversion is mechanical and has THREE parts that must all happen:
91
103
  *
92
104
  * 1. fetch a bounded WINDOW instead of the requested page;
@@ -56,6 +56,18 @@ export const SEARCH_REFINE_WINDOW = 250;
56
56
  *
57
57
  * `refineSearchTxt` grew a real-pagination mode, and `products` was the only
58
58
  * caller converted — deliberately, so the other eleven stayed byte-identical.
59
+ *
60
+ * 🛑 That sentence is now HISTORY, not status. Measured 2026-10-19: ELEVEN
61
+ * repositories use `beginSearchWindow`, and `audit-listing-search-intact`
62
+ * (C6) enforces all three parts of the conversion on each of them — doing
63
+ * parts 1 and 3 without 2 "reads exactly like a working conversion and is
64
+ * the half that no-ops", which is why the audit checks the triple rather
65
+ * than the presence of the call.
66
+ *
67
+ * `faqs` is the deliberate holdout: it hand-rolls the refine and returns the
68
+ * legacy page-only shape, which this file's own docstring describes as
69
+ * "preserved verbatim for unconverted callers". That is a known limitation,
70
+ * not a defect — do not "fix" it as a bug (Rule #4).
59
71
  * The conversion is mechanical and has THREE parts that must all happen:
60
72
  *
61
73
  * 1. fetch a bounded WINDOW instead of the requested page;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.53.0",
3
+ "version": "4.53.2",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -44,6 +44,24 @@ const TRANSITIVE_RUNTIME_DUPS = [
44
44
  // query-core and a parallel QueryClientContext instance ships in the SSR
45
45
  // bundle, producing the "No QueryClient set" crash on every page (2026-06-11).
46
46
  "@tanstack/query-core",
47
+ /*
48
+ * firebase-admin (peer) bundles @google-cloud/storage, which does NOT own a
49
+ * React context — so the 2026-06-11 runtime crash class does not apply here.
50
+ * It still has to be pruned, for a different reason: TYPE IDENTITY.
51
+ *
52
+ * `Bucket` carries a private member, so TypeScript compares the two copies
53
+ * nominally and refuses to pass a root-resolved Bucket into a function typed
54
+ * against appkit's copy. Any appkit module that accepts a Bucket from a
55
+ * caller is then uncompilable from the consumer, which includes appkit/src
56
+ * under the file: pin.
57
+ *
58
+ * MEASURED rather than assumed: removing the directory fixes it and
59
+ * restoring it brings the error straight back, with the tsbuildinfo cleared
60
+ * both times — the first attempt cleared a stale cache in the same step and
61
+ * could not tell which change was responsible.
62
+ */
63
+ "@google-cloud/storage",
64
+ "@google-cloud/firestore",
47
65
  ];
48
66
 
49
67
  // Peer deps that have NO React context / module-scope singleton and that the
@@ -181,7 +181,8 @@ const appkit = await import("@mohasinac/appkit");
181
181
  // client-safe barrel, only from "@mohasinac/appkit/server". The *_PII_FIELDS
182
182
  // / *_PII_INDEX_MAP constants are plain data and stay in the main barrel.
183
183
  const appkitServer = await import("@mohasinac/appkit/server");
184
- const { encryptPiiFields, piiIndicesFor, encryptPayoutDetails, encryptPayoutBankAccount, encryptShippingConfig } = appkitServer;
184
+ const { encryptPiiFields, piiIndicesFor, encryptPayoutDetails, encryptPayoutBankAccount, encryptShippingConfig,
185
+ buildTokensIndex, BLIND_INDEX_KEY_VERSION_FIELD, CURRENT_BLIND_INDEX_KEY_VERSION } = appkitServer;
185
186
 
186
187
  const {
187
188
  // seed data
@@ -191,9 +192,9 @@ const {
191
192
  storeCategoriesSeedData, listingTemplatesSeedData, moderationQueueSeedData, reportsSeedData,
192
193
  itemRequestsSeedData, storeGoogleConfigSeedData,
193
194
  categoriesSeedData, storesSeedData, sessionsSeedData,
194
- productsStandardSeedData, productsAuctionsSeedData, productsPreordersSeedData,
195
+ productsStandardSeedData, productsBeybladeXSeedData, productsAuctionsSeedData, productsPreordersSeedData,
195
196
  productsPrizeDrawsSeedData, productsClassifiedsSeedData, productsDigitalCodesSeedData, productsLiveItemsSeedData,
196
- productsArtSeedData, productsStickersSeedData,
197
+ productsArtSeedData, productsStickersSeedData, productsSparesSeedData,
197
198
  productsCatalogueSeedData,
198
199
  FRANCHISE_BY_CATEGORY_ROOT,
199
200
  ordersSeedData, reviewsSeedData, cartsSeedData, bidsSeedData,
@@ -386,6 +387,104 @@ const COLLECTION_MAP = {
386
387
  * A root with no mapping yields NO franchise (living collectibles are not an
387
388
  * IP) — see `FRANCHISE_BY_CATEGORY_ROOT`.
388
389
  */
390
+ /**
391
+ * The real, sellable catalogue — everything else in the product seed is demo
392
+ * furniture and is DROPPED HERE, before anything is written.
393
+ *
394
+ * ── 🛑 WHY A FILTER AND NOT A DELETION ────────────────────────────────────
395
+ *
396
+ * The fixtures stay in their files on purpose: they are the only coverage
397
+ * several features have (every `preOrderProductionStatus` value, a sold-out
398
+ * reservation, a depleted digital-code pool, an ended-unsold auction), and
399
+ * the tester checklist deep-links to them by id. Deleting them would silently
400
+ * remove that coverage. Not LOADING them is the part that was wanted.
401
+ *
402
+ * ── 🛑 WHY THIS HAD TO EXIST ──────────────────────────────────────────────
403
+ *
404
+ * `appkit-seed load` writes every registered row and `purge` deletes
405
+ * `seedPurpose: "test"` afterwards — so the demo listings came BACK on every
406
+ * reseed, and anyone who ran `load` to fix imagery silently republished 76
407
+ * fake products to the live storefront. That happened twice in one session.
408
+ * The owner's instruction was "delete them from the seed itself and make sure
409
+ * they do not return"; this is the point where that can be guaranteed, since
410
+ * every write path funnels through here.
411
+ *
412
+ * ── The discriminator is the STORE, not the listing type ──────────────────
413
+ *
414
+ * `store-beyblade-arena` is the fictional demo seller; `store-letitrip-
415
+ * official` is the real one. Keying on the store rather than on a per-file
416
+ * allow-list means a fixture added to ANY product seed file later is excluded
417
+ * automatically, which is the failure mode this is replacing — a list that
418
+ * has to be remembered is a list that drifts.
419
+ *
420
+ * Set `SEED_INCLUDE_DEMO=1` to load them anyway, for local demo work.
421
+ */
422
+ const REAL_STORE_IDS = new Set(["store-letitrip-official"]);
423
+
424
+ function realListingsOnly(products) {
425
+ if (process.env.SEED_INCLUDE_DEMO === "1") {
426
+ console.log("▌ SEED_INCLUDE_DEMO=1 — demo listings INCLUDED");
427
+ return products;
428
+ }
429
+ /*
430
+ * 🛑 TWO rules, because the store alone is not enough. Six prize-draw
431
+ * fixtures live under the REAL store and are still demo furniture — their
432
+ * imagery is a 460-byte generated colour tile from /images/seed-tiles/,
433
+ * which is the giveaway: a listing nobody photographed is a listing nobody
434
+ * intends to sell. Measured before writing this: every one of the six, and
435
+ * nothing real, matches.
436
+ */
437
+ const isPlaceholder = (p) => {
438
+ const urls = [p?.mainImage, ...(Array.isArray(p?.images) ? p.images : [])]
439
+ .map((v) => (typeof v === "string" ? v : v?.url))
440
+ .filter(Boolean);
441
+ return urls.length > 0 && urls.every((u) => String(u).includes("/images/seed-tiles/"));
442
+ };
443
+ const kept = products.filter((p) => REAL_STORE_IDS.has(p?.storeId) && !isPlaceholder(p));
444
+ const dropped = products.length - kept.length;
445
+ if (dropped > 0) {
446
+ console.log(` • ${dropped} demo listing(s) not loaded (set SEED_INCLUDE_DEMO=1 to include)`);
447
+ }
448
+ return kept;
449
+ }
450
+
451
+ /**
452
+ * Drop bundle categories whose members are not in the loaded catalogue.
453
+ *
454
+ * 🛑 A bundle is ALL-OR-NOTHING — `canAddToCart` buys every member together —
455
+ * so a bundle missing even one member is unsellable, and one missing ALL of
456
+ * them is a card that opens an empty page. Measured right after the demo
457
+ * listings stopped loading: of the five seeded bundles, three had zero
458
+ * surviving members and the other two had 1-of-4 and 2-of-3. All five were
459
+ * still `isActive: true`, and all five rendered on the HOMEPAGE as collage
460
+ * cards built from `display.mosaicImages` — which are baked at seed time from
461
+ * the members' own imagery, so they kept showing pictures of products that no
462
+ * longer exist. That is 92 placeholder-tile references on the homepage.
463
+ *
464
+ * Derived rather than hand-maintained for the same reason as the product
465
+ * filter: a bundle that becomes valid later starts loading again on its own,
466
+ * and one that breaks stops, with nobody having to remember either.
467
+ *
468
+ * Only `categoryType: "bundle"` rows are considered. Every other category is
469
+ * taxonomy and is never touched — rebuilding the tree is expensive and is
470
+ * explicitly not what this is for.
471
+ */
472
+ function loadableBundlesOnly(categories, loadedProducts) {
473
+ const live = new Set(loadedProducts.map((p) => p?.id).filter(Boolean));
474
+ let dropped = 0;
475
+ const kept = categories.filter((c) => {
476
+ if (c?.categoryType !== "bundle") return true;
477
+ const ids = Array.isArray(c.bundleProductIds) ? c.bundleProductIds : [];
478
+ const ok = ids.length > 0 && ids.every((id) => live.has(id));
479
+ if (!ok) dropped++;
480
+ return ok;
481
+ });
482
+ if (dropped > 0) {
483
+ console.log(` • ${dropped} bundle(s) not loaded — members missing from the catalogue`);
484
+ }
485
+ return kept;
486
+ }
487
+
389
488
  function withFranchise(products) {
390
489
  let stamped = 0;
391
490
  const out = products.map((p) => {
@@ -468,6 +567,56 @@ function withDerivedCategoryFields(products) {
468
567
  return out;
469
568
  }
470
569
 
570
+ /**
571
+ * The real catalogue, computed ONCE so the bundle filter and the product
572
+ * loader cannot disagree about what "loaded" means. Deriving it twice is
573
+ * Root Cause #75's shape — two copies of one rule, one of which learns about
574
+ * a change and the other does not.
575
+ */
576
+ const REAL_PRODUCTS = realListingsOnly([
577
+ ...(productsStandardSeedData || []),
578
+ // Real, wiki-verified Beyblade X listings under store-letitrip-official —
579
+ // added 2026-10-19 for PhonePe merchant registration, which requires at
580
+ // least one genuinely purchasable product. See the file's own header.
581
+ ...(productsBeybladeXSeedData || []),
582
+ ...(productsAuctionsSeedData || []), ...(productsPreordersSeedData || []),
583
+ ...(productsPrizeDrawsSeedData || []), ...(productsClassifiedsSeedData || []), ...(productsDigitalCodesSeedData || []), ...(productsLiveItemsSeedData || []),
584
+ // art + stickers were written, exported from the seed barrel, and then never
585
+ // spread here — so 13 fixtures had NEVER reached the database, /art and
586
+ // /stickers were permanently empty, and listingType=art|stickers returned 0.
587
+ // Root Cause #58's family one layer down: added everywhere except the runner.
588
+ ...(productsArtSeedData || []), ...(productsStickersSeedData || []),
589
+ // 🛑 BOTH sites, every time. This file's own header records 13 art/sticker
590
+ // fixtures that never reached the database because only the import was
591
+ // edited and this spread was not — the loader then wrote every OTHER
592
+ // product and reported success.
593
+ ...(productsSparesSeedData || []),
594
+ /*
595
+ * 🛑 DEREGISTERED 2026-10-19 — productsCatalogueSeedData (1,237 rows, one
596
+ * per taxonomy leaf) is NOT spread here, on purpose.
597
+ *
598
+ * This is a reversal of the comment that used to be here, which said the
599
+ * opposite: that this spread was "what makes `products` reproducible
600
+ * after a full wipe." That was true when the catalogue was the only
601
+ * content under its leaf categories. It stopped being true the moment
602
+ * real curated listings exist for the SAME leaves — four of them,
603
+ * confirmed by grep: `category-aeropegasus-3-70a`, `category-
604
+ * valkyrievolt-s4-70v`, `category-wizardarrow-4-80b`, `category-
605
+ * knightshield-3-80n` each already carry one generated row. Re-enabling
606
+ * this spread would not just add filler back — it would put a
607
+ * hash-priced synthetic duplicate (one measured as a NEGATIVE price,
608
+ * `-61`) into the exact categories the real BX-53 fixture now occupies,
609
+ * silently resurrecting the thing a full `appkit-seed purge` was just run
610
+ * to remove.
611
+ *
612
+ * The generator (`scripts/gen-catalogue-listings.mjs`) and the committed
613
+ * file itself are both left untouched — this is deliberately a one-line
614
+ * "stop loading it" change, not a deletion. Re-enable only after deciding
615
+ * what should happen to a leaf that now has BOTH a real listing and a
616
+ * generated one.
617
+ */
618
+ ]);
619
+
471
620
  const SEED_DATA_MAP = {
472
621
  users: usersSeedData,
473
622
  /*
@@ -491,22 +640,9 @@ const SEED_DATA_MAP = {
491
640
  storeAddresses: storeAddressesSeedData,
492
641
  // SB-UNI-C: brands were merged into categories (categoryType:"brand") — no
493
642
  // standalone brands collection/seed exists anymore.
494
- categories: categoriesSeedData,
643
+ categories: loadableBundlesOnly(categoriesSeedData, REAL_PRODUCTS),
495
644
  stores: storesSeedData,
496
- products: withFranchise(withDerivedCategoryFields([
497
- ...(productsStandardSeedData || []), ...(productsAuctionsSeedData || []), ...(productsPreordersSeedData || []),
498
- ...(productsPrizeDrawsSeedData || []), ...(productsClassifiedsSeedData || []), ...(productsDigitalCodesSeedData || []), ...(productsLiveItemsSeedData || []),
499
- // art + stickers were written, exported from the seed barrel, and then never
500
- // spread here — so 13 fixtures had NEVER reached the database, /art and
501
- // /stickers were permanently empty, and listingType=art|stickers returned 0.
502
- // Root Cause #58's family one layer down: added everywhere except the runner.
503
- ...(productsArtSeedData || []), ...(productsStickersSeedData || []),
504
- // The 972 generated catalogue-filler listings (one per taxonomy leaf) —
505
- // see scripts/gen-catalogue-listings.mjs. This is what makes `products`
506
- // reproducible after a full wipe; without it the collection drops from
507
- // 1,039 to 71 the moment someone purges it.
508
- ...(productsCatalogueSeedData || []),
509
- ])),
645
+ products: withFranchise(withDerivedCategoryFields(REAL_PRODUCTS)),
510
646
  orders: ordersSeedData,
511
647
  reviews: reviewsSeedData,
512
648
  bids: bidsSeedData,
@@ -596,6 +732,33 @@ async function purgeCollection(path) {
596
732
  return removed;
597
733
  }
598
734
 
735
+ /*
736
+ * 🛑 `TOKENS_INDEX_MAP` holds ONLY `payouts`, and that is a measured fact
737
+ * about this file, not an oversight.
738
+ *
739
+ * `encryptSeedPii` is called from exactly one place — `loadGeneric`'s
740
+ * per-doc loop. `users` and `addresses` are seeded by their OWN dedicated
741
+ * loaders (`loadUsers`, the addresses block near line 1029) that write
742
+ * straight to Firestore and never call this function — so a `users`/
743
+ * `addresses` entry here would be dead code, silently unreachable, which is
744
+ * worse than no entry: it would read as "handled" to the next person who
745
+ * greps for it.
746
+ *
747
+ * It is also the right scope rather than a gap, because `users` and
748
+ * `addresses` are PRESERVE-tier in the tester harness — never wiped, never
749
+ * reseeded — so the only two things that can write their `*TokensIndex`
750
+ * are a REAL write (covered by `UserRepository`/`AddressesRepository`'s
751
+ * `buildTokensIndexFor`, wired separately) and the one-time bootstrap seed
752
+ * load `appkit-seed load --collections users` documented in CLAUDE.md's
753
+ * § "Claude Tester" — which `backfill-blind-index.mjs` exists to catch up
754
+ * after. `payouts` has no such safety net: it is SEED_TRANSACTIONAL, so it
755
+ * cascades and RESEEDS on every tester run that touches its store, through
756
+ * exactly this function — which is why it is the one entry that matters.
757
+ */
758
+ const TOKENS_INDEX_MAP = {
759
+ payouts: { field: "sellerTokensIndex", from: ["sellerName", "sellerEmail"] },
760
+ };
761
+
599
762
  function encryptSeedPii(collection, data) {
600
763
  const PII_MAP = {
601
764
  orders: ORDER_PII_FIELDS,
@@ -607,11 +770,28 @@ function encryptSeedPii(collection, data) {
607
770
  eventEntries: EVENT_ENTRY_PII_FIELDS,
608
771
  };
609
772
  const fields = PII_MAP[collection];
610
- if (!fields) return data;
611
- let result = encryptPiiFields(data, [...fields]);
773
+ let result = fields ? encryptPiiFields(data, [...fields]) : { ...data };
612
774
  if (collection === "payouts" && result.bankAccount) {
613
775
  result.bankAccount = encryptPayoutBankAccount(result.bankAccount);
614
776
  }
777
+
778
+ /*
779
+ * 🛑 THIS IS WHAT MAKES `payouts` SURVIVE A TESTER WIPE WITH A WORKING
780
+ * SEARCH INDEX. `payouts` is SEED_TRANSACTIONAL in the tester harness —
781
+ * it cascades on `storeId` whenever its store is wiped, then gets
782
+ * RE-SEEDED by exactly this function. Without this block, the reseeded
783
+ * documents would carry ciphertext and no `sellerTokensIndex` at all,
784
+ * silently undoing a one-shot backfill on the very next tester run.
785
+ */
786
+ const tokensIndex = TOKENS_INDEX_MAP[collection];
787
+ if (tokensIndex) {
788
+ const values = tokensIndex.from.map((f) => data[f]).filter((v) => typeof v === "string");
789
+ if (values.length > 0) {
790
+ result[tokensIndex.field] = buildTokensIndex(...values);
791
+ result[BLIND_INDEX_KEY_VERSION_FIELD] = CURRENT_BLIND_INDEX_KEY_VERSION;
792
+ }
793
+ }
794
+
615
795
  return result;
616
796
  }
617
797
 
@@ -1229,9 +1409,23 @@ async function cmdPurge() {
1229
1409
  const sub = SUBCOLLECTIONS.find((s) => s.key === colName);
1230
1410
  try {
1231
1411
  if (sub) {
1232
- /* A collection-group query reaches every parent at once. */
1233
- const snap = await db.collectionGroup(sub.name).where("seedPurpose", "==", "test").get();
1234
- if (snap.size > 0) plan.push({ colName, docs: snap.docs, isSub: true });
1412
+ /*
1413
+ * 🛑 Unfiltered collection-group read, filtered in memory — NOT
1414
+ * `.where("seedPurpose", "==", "test")` on the group.
1415
+ *
1416
+ * A single-field equality is auto-indexed per COLLECTION, but a
1417
+ * COLLECTION-GROUP query needs an explicit composite/group index that
1418
+ * this project has never deployed, and `purge` must not require a
1419
+ * Firebase deploy just to run (it is a read-then-delete script, not an
1420
+ * infra change). Measured live: `3 FAILED_PRECONDITION: ... requires a
1421
+ * COLLECTION_GROUP_ASC index`. `couponUsage` is small (single digits
1422
+ * per store), so reading the whole group and filtering client-side
1423
+ * costs nothing here — this is not a pattern to reuse on a large
1424
+ * subcollection.
1425
+ */
1426
+ const snap = await db.collectionGroup(sub.name).get();
1427
+ const docs = snap.docs.filter((d) => d.data()?.seedPurpose === "test");
1428
+ if (docs.length > 0) plan.push({ colName, docs, isSub: true });
1235
1429
  } else {
1236
1430
  const snap = await db.collection(path).where("seedPurpose", "==", "test").get();
1237
1431
  if (snap.size > 0) plan.push({ colName, docs: snap.docs, isSub: false });
@@ -1286,19 +1480,40 @@ async function cmdPurge() {
1286
1480
  }
1287
1481
  }
1288
1482
  }
1289
- for (let i = 0; i < p.docs.length; i += 450) {
1290
- const chunk = p.docs.slice(i, i + 450);
1291
- const batch = db.batch();
1292
- for (const d of chunk) batch.delete(d.ref);
1293
- try {
1294
- await batch.commit();
1295
- stats.deleted += chunk.length;
1296
- if (VERBOSE) for (const d of chunk) console.log(` - ${p.colName}/${d.id}`);
1297
- } catch (err) {
1298
- console.error(`✗ ${p.colName}: ${err.message}`);
1299
- stats.errors++;
1300
- }
1483
+ /*
1484
+ * 🛑 BulkWriter, never a manually-chunked `db.batch()`.
1485
+ *
1486
+ * A 450-document chunk stays under Firestore's 500-OPERATION limit but
1487
+ * says nothing about the 10 MiB per-request PAYLOAD limit — and a rich
1488
+ * document (a product's `searchTxt` array, `customFields`,
1489
+ * `customSections`, `images[]`) can blow that well before 450 count.
1490
+ * Measured live purging this exact `products` collection: `3
1491
+ * INVALID_ARGUMENT: Transaction too big` partway through, which aborted
1492
+ * the whole chunk's commit and silently left every doc in it undeleted —
1493
+ * `stats.deleted` kept counting the chunk as done regardless, so the
1494
+ * printed total was wrong by exactly the size of the failed chunk.
1495
+ *
1496
+ * `db.bulkWriter()` sizes and retries its own requests, so it is correct
1497
+ * regardless of document size — CLAUDE.md documents the identical failure
1498
+ * for a `categories` wipe (1,177 rows, ~100-entry `searchTxt` each) dying
1499
+ * at a 400-doc batch for the same reason.
1500
+ */
1501
+ const writer = db.bulkWriter();
1502
+ let chunkErrors = 0;
1503
+ writer.onWriteError((err) => {
1504
+ chunkErrors += 1;
1505
+ console.error(`✗ ${p.colName}/${err.documentRef.id}: ${err.message}`);
1506
+ // Retry up to the default limit; beyond that, give up on this one doc
1507
+ // rather than retrying forever.
1508
+ return err.failedAttempts < 3;
1509
+ });
1510
+ for (const d of p.docs) {
1511
+ writer.delete(d.ref);
1512
+ if (VERBOSE) console.log(` - ${p.colName}/${d.id}`);
1301
1513
  }
1514
+ await writer.close();
1515
+ stats.deleted += p.docs.length - chunkErrors;
1516
+ stats.errors += chunkErrors;
1302
1517
  }
1303
1518
 
1304
1519
  console.log(
@@ -1,53 +1,134 @@
1
1
  /**
2
- * Post-build guard: verifies that critical responsive Tailwind classes are present
3
- * in the compiled dist/tailwind-utilities.css. Fails the build if any are missing,
4
- * catching cases where a stale or incomplete CSS bundle was published.
2
+ * verify-css-build — the BUILD-TIME guard on appkit's compiled stylesheets.
5
3
  *
6
- * Run via: node scripts/verify-css-build.mjs
7
- * Called automatically at the end of `npm run build`.
4
+ * Runs at the end of `npm run build`, before `npm publish` can ship the tarball.
5
+ *
6
+ * ── What this is for, and what it is NOT ───────────────────────────────────
7
+ * This answers "did the build produce a plausible, complete stylesheet?" — a
8
+ * question about the ARTEFACT. It deliberately does not try to answer "does
9
+ * every authored class resolve to a rule?", which is a question about the
10
+ * CODE: `scripts/audit-dead-css-classes.mjs` owns that, reads all three
11
+ * stylesheets, and runs in `npm run check` and the Stop hook.
12
+ *
13
+ * 🛑 It used to be a list of EIGHT hardcoded strings — `{md,lg}:{block,flex,
14
+ * hidden}` plus two breakpoints — chosen in 2026-08 for one specific nav bug.
15
+ * That is what it could see, and nothing added since was covered: not a hover,
16
+ * not a dropdown, not one of the ~980 hand-written `appkit-*` classes. Asked
17
+ * in 2026-10 whether the CSS was checked "or just a few", the honest answer
18
+ * was: just those eight.
19
+ *
20
+ * The replacement checks properties that hold for ANY correct build, so it
21
+ * cannot go stale as the class surface grows:
22
+ *
23
+ * 1. Each artefact EXISTS and is non-trivially large.
24
+ * 2. Each carries a floor of rules — catching a half-written `dist/`.
25
+ * 3. `styles.css` has no unresolved `@import` left in it.
26
+ * 4. The responsive machinery is present (media queries at the real
27
+ * breakpoints), without naming individual classes.
28
+ *
29
+ * ── Why (2) exists: the half-written dist is a REAL failure here ───────────
30
+ * CLAUDE.md records a publish that died inside its own build step and left
31
+ * `dist/` with `client-entry.js` present and `tailwind-utilities.css` gone.
32
+ * A guard that only checked for a few class names in a file that existed
33
+ * would have passed a stylesheet missing most of itself. The floors are set
34
+ * well below current size so ordinary authoring never trips them; they exist
35
+ * to catch an order-of-magnitude loss, not a diff.
8
36
  */
9
- import { readFileSync } from "fs";
37
+ import { readFileSync, statSync, existsSync } from "fs";
10
38
  import { resolve, dirname } from "path";
11
39
  import { fileURLToPath } from "url";
12
40
 
13
41
  const __dirname = dirname(fileURLToPath(import.meta.url));
14
- const CSS_PATH = resolve(__dirname, "../dist/tailwind-utilities.css");
15
-
16
- const REQUIRED_CLASSES = [
17
- // Responsive display utilities used by MainNavbar (NavbarLayout) and TitleBar
18
- "lg\\:block",
19
- "lg\\:flex",
20
- "lg\\:hidden",
21
- "md\\:block",
22
- "md\\:flex",
23
- "md\\:hidden",
24
- // Responsive breakpoints must exist as @media rules.
25
- // Tailwind v4 (2026-08-16 migration) uses rem-based default breakpoints —
26
- // 64rem/48rem are the exact same viewport widths as v3's 1024px/768px at the
27
- // browser default 16px root font-size (this project does not override
28
- // html { font-size }), just expressed in the new unit.
29
- "min-width:64rem",
30
- "min-width:48rem",
42
+ const DIST = resolve(__dirname, "../dist");
43
+
44
+ /**
45
+ * Floors, not targets. Measured 2026-10-19 at 205 KB / 2,400 rules for the
46
+ * utilities and 495 KB / 7,900 rules for the components; these sit at roughly
47
+ * a third of that, so deleting a feature is fine and losing the file is not.
48
+ */
49
+ const ARTEFACTS = [
50
+ {
51
+ file: "tailwind-utilities.css",
52
+ minBytes: 60_000,
53
+ minRules: 800,
54
+ what: "Tailwind utilities generated from appkit/src",
55
+ },
56
+ {
57
+ file: "styles.css",
58
+ minBytes: 150_000,
59
+ minRules: 2_500,
60
+ what: "hand-written appkit-* component CSS, flattened from *.style.css",
61
+ },
31
62
  ];
32
63
 
33
- let css;
34
- try {
35
- css = readFileSync(CSS_PATH, "utf8");
36
- } catch {
37
- console.error(`[verify-css-build] ERROR: Could not read ${CSS_PATH}`);
38
- console.error(" Run 'npm run build' in appkit/ before publishing.");
39
- process.exit(1);
64
+ /**
65
+ * The breakpoints the layout primitives actually switch on. Expressed as
66
+ * MEDIA QUERIES rather than class names: a class list has to be maintained
67
+ * and silently narrows over time, while "the build emitted rules at these
68
+ * widths" stays true however the classes are spelled.
69
+ *
70
+ * rem, not px — Tailwind v4 emits `min-width: 64rem`, the same viewport width
71
+ * v3's `1024px` meant at the browser default root font-size (this project does
72
+ * not override `html { font-size }`).
73
+ */
74
+ const BREAKPOINTS = ["40rem", "48rem", "64rem", "80rem"];
75
+
76
+ const problems = [];
77
+
78
+ for (const { file, minBytes, minRules, what } of ARTEFACTS) {
79
+ const p = resolve(DIST, file);
80
+ if (!existsSync(p)) {
81
+ problems.push(`${file} — MISSING (${what})`);
82
+ continue;
83
+ }
84
+ const bytes = statSync(p).size;
85
+ const css = readFileSync(p, "utf8");
86
+ // Rule count ≈ declaration blocks. Minified output is one line, so counting
87
+ // `{` is the only size-independent measure available.
88
+ const rules = (css.match(/\{/g) ?? []).length;
89
+
90
+ if (bytes < minBytes) {
91
+ problems.push(`${file} — ${bytes} bytes, below the ${minBytes} floor (${what})`);
92
+ }
93
+ if (rules < minRules) {
94
+ problems.push(`${file} — ${rules} rules, below the ${minRules} floor (${what})`);
95
+ }
96
+ // An unresolved @import means bundle-css.mjs did not run, or ran against an
97
+ // already-flattened file. Turbopack does not reliably resolve nested CSS
98
+ // imports, so one left here ships as missing styles.
99
+ if (file === "styles.css" && /@import\s+["']\./.test(css)) {
100
+ problems.push(`${file} — contains an unresolved relative @import; run bundle-css.mjs`);
101
+ }
40
102
  }
41
103
 
42
- const missing = REQUIRED_CLASSES.filter((cls) => !css.includes(cls));
104
+ const utilitiesPath = resolve(DIST, "tailwind-utilities.css");
105
+ if (existsSync(utilitiesPath)) {
106
+ const css = readFileSync(utilitiesPath, "utf8");
107
+ const missingBps = BREAKPOINTS.filter((bp) => !css.includes(`min-width:${bp}`) && !css.includes(`min-width: ${bp}`));
108
+ if (missingBps.length) {
109
+ problems.push(
110
+ `tailwind-utilities.css — no @media rule at ${missingBps.join(", ")}; ` +
111
+ `the responsive layer did not build`,
112
+ );
113
+ }
114
+ }
43
115
 
44
- if (missing.length > 0) {
45
- console.error("[verify-css-build] FAIL: Missing critical CSS classes in dist/tailwind-utilities.css:");
46
- missing.forEach((cls) => console.error(` - ${cls}`));
116
+ if (problems.length) {
117
+ console.error("[verify-css-build] FAIL:");
118
+ for (const p of problems) console.error(` - ${p}`);
119
+ console.error("");
120
+ console.error(" The build did not produce a complete stylesheet. Most likely causes:");
121
+ console.error(" - a concurrent `npm run build` wrote dist/ at the same time");
122
+ console.error(" (never run two builds at once — see CLAUDE.md's publish rules)");
123
+ console.error(" - copy-assets.mjs or bundle-css.mjs did not run");
124
+ console.error(" - the tailwindcss CLI failed without a non-zero exit");
47
125
  console.error("");
48
- console.error(" This usually means the Tailwind build ran on stale source files.");
49
- console.error(" Fix: rebuild appkit with 'npm run build' and re-verify.");
126
+ console.error(" For per-class completeness run `npm run audit dead-css-classes`,");
127
+ console.error(" which compares every authored class against the compiled CSS.");
50
128
  process.exit(1);
51
129
  }
52
130
 
53
- console.log(`[verify-css-build] OK: all ${REQUIRED_CLASSES.length} required classes/breakpoints present.`);
131
+ console.log(
132
+ `[verify-css-build] OK — ${ARTEFACTS.length} artefact(s) present, above their size/rule floors, ` +
133
+ `responsive layer built at ${BREAKPOINTS.join(" / ")}.`,
134
+ );
@@ -1,7 +0,0 @@
1
- import { type ActionResult } from "@mohasinac/appkit/server";
2
- import type { SearchQuery } from "../../../../features/search/types";
3
- /**
4
- * Server action for client-initiated search (debounced as-you-type).
5
- * Bypasses React.cache() so each call returns fresh results.
6
- */
7
- export declare function searchAction(query: SearchQuery): Promise<ActionResult<unknown>>;
@@ -1,21 +0,0 @@
1
- "use server";
2
- import { wrapAction } from "@mohasinac/appkit/server";
3
- import { searchProducts } from "../../../../features/search/actions/search-actions.js";
4
- /**
5
- * Server action for client-initiated search (debounced as-you-type).
6
- * Bypasses React.cache() so each call returns fresh results.
7
- */
8
- export async function searchAction(query) {
9
- return wrapAction(async () => {
10
- return searchProducts(query).catch(() => ({
11
- items: [],
12
- q: query.q ?? "",
13
- total: 0,
14
- page: 1,
15
- pageSize: query.pageSize ?? 20,
16
- totalPages: 0,
17
- hasMore: false,
18
- backend: "in-memory",
19
- }));
20
- });
21
- }