@mohasinac/appkit 4.58.0 → 4.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/jobs/handlers/messages.d.ts +1 -1
  3. package/dist/_internal/server/jobs/handlers/messages.js +1 -1
  4. package/dist/_internal/shared/types/base-document.d.ts +1 -1
  5. package/dist/constants/seed-meta.d.ts +113 -0
  6. package/dist/constants/seed-meta.js +91 -0
  7. package/dist/index.d.ts +0 -131
  8. package/dist/index.js +50 -294
  9. package/dist/server.d.ts +0 -69
  10. package/dist/server.js +0 -69
  11. package/package.json +4 -2
  12. package/scripts/seed-cli.mjs +69 -1
  13. package/dist/features/tester/seed-data/_happy-path.d.ts +0 -23
  14. package/dist/features/tester/seed-data/_happy-path.js +0 -710
  15. package/dist/features/tester/seed-data/_money-flows.d.ts +0 -23
  16. package/dist/features/tester/seed-data/_money-flows.js +0 -610
  17. package/dist/features/tester/seed-data/authored/_types.d.ts +0 -57
  18. package/dist/features/tester/seed-data/authored/_types.js +0 -35
  19. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +0 -2
  20. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +0 -226
  21. package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +0 -2
  22. package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +0 -329
  23. package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +0 -2
  24. package/dist/features/tester/seed-data/authored/addresses__address-filters.js +0 -41
  25. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +0 -2
  26. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +0 -76
  27. package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +0 -2
  28. package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +0 -78
  29. package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +0 -2
  30. package/dist/features/tester/seed-data/authored/addresses__state-picker.js +0 -59
  31. package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +0 -2
  32. package/dist/features/tester/seed-data/authored/addresses__unban-request.js +0 -77
  33. package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.d.ts +0 -2
  34. package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.js +0 -151
  35. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +0 -2
  36. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +0 -265
  37. package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +0 -2
  38. package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +0 -131
  39. package/dist/features/tester/seed-data/authored/admin__bug-hunter-rewards.d.ts +0 -2
  40. package/dist/features/tester/seed-data/authored/admin__bug-hunter-rewards.js +0 -143
  41. package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +0 -2
  42. package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +0 -207
  43. package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +0 -2
  44. package/dist/features/tester/seed-data/authored/admin__bundles.js +0 -144
  45. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +0 -2
  46. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +0 -265
  47. package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +0 -2
  48. package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +0 -318
  49. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +0 -2
  50. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +0 -177
  51. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +0 -2
  52. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +0 -165
  53. package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +0 -2
  54. package/dist/features/tester/seed-data/authored/admin__content-deletes.js +0 -267
  55. package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +0 -2
  56. package/dist/features/tester/seed-data/authored/admin__content-marketing.js +0 -188
  57. package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +0 -2
  58. package/dist/features/tester/seed-data/authored/admin__coupons.js +0 -215
  59. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +0 -2
  60. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +0 -202
  61. package/dist/features/tester/seed-data/authored/admin__firebase-function-effects.d.ts +0 -2
  62. package/dist/features/tester/seed-data/authored/admin__firebase-function-effects.js +0 -249
  63. package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +0 -2
  64. package/dist/features/tester/seed-data/authored/admin__media-watermark.js +0 -148
  65. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +0 -2
  66. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +0 -350
  67. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +0 -2
  68. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +0 -129
  69. package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +0 -2
  70. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -586
  71. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +0 -2
  72. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +0 -260
  73. package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +0 -2
  74. package/dist/features/tester/seed-data/authored/admin__users-trust.js +0 -569
  75. package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +0 -2
  76. package/dist/features/tester/seed-data/authored/buying__bidding.js +0 -449
  77. package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +0 -2
  78. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +0 -684
  79. package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +0 -2
  80. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -546
  81. package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +0 -2
  82. package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +0 -379
  83. package/dist/features/tester/seed-data/authored/buying__cart.d.ts +0 -2
  84. package/dist/features/tester/seed-data/authored/buying__cart.js +0 -1264
  85. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +0 -2
  86. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +0 -122
  87. package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +0 -2
  88. package/dist/features/tester/seed-data/authored/buying__my-orders.js +0 -279
  89. package/dist/features/tester/seed-data/authored/buying__offers.d.ts +0 -2
  90. package/dist/features/tester/seed-data/authored/buying__offers.js +0 -1127
  91. package/dist/features/tester/seed-data/authored/buying__order-detail-actions.d.ts +0 -2
  92. package/dist/features/tester/seed-data/authored/buying__order-detail-actions.js +0 -153
  93. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +0 -2
  94. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +0 -252
  95. package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +0 -2
  96. package/dist/features/tester/seed-data/authored/buying__product-detail.js +0 -474
  97. package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +0 -2
  98. package/dist/features/tester/seed-data/authored/buying__return-request.js +0 -165
  99. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +0 -2
  100. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +0 -260
  101. package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +0 -2
  102. package/dist/features/tester/seed-data/authored/buying__reviews.js +0 -128
  103. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +0 -2
  104. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +0 -96
  105. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +0 -2
  106. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +0 -283
  107. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +0 -2
  108. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +0 -169
  109. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +0 -2
  110. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +0 -105
  111. package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +0 -2
  112. package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +0 -374
  113. package/dist/features/tester/seed-data/authored/community-support__messages.d.ts +0 -2
  114. package/dist/features/tester/seed-data/authored/community-support__messages.js +0 -200
  115. package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +0 -2
  116. package/dist/features/tester/seed-data/authored/community-support__public-profile.js +0 -54
  117. package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +0 -2
  118. package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +0 -76
  119. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +0 -4
  120. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +0 -590
  121. package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +0 -2
  122. package/dist/features/tester/seed-data/authored/content-discovery__blog.js +0 -110
  123. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +0 -2
  124. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +0 -149
  125. package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.d.ts +0 -2
  126. package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.js +0 -145
  127. package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.d.ts +0 -2
  128. package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +0 -174
  129. package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +0 -2
  130. package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +0 -169
  131. package/dist/features/tester/seed-data/authored/content-discovery__event-detail-subroutes.d.ts +0 -2
  132. package/dist/features/tester/seed-data/authored/content-discovery__event-detail-subroutes.js +0 -209
  133. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +0 -2
  134. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +0 -207
  135. package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +0 -2
  136. package/dist/features/tester/seed-data/authored/content-discovery__events.js +0 -377
  137. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +0 -2
  138. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +0 -87
  139. package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +0 -2
  140. package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +0 -147
  141. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +0 -2
  142. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +0 -209
  143. package/dist/features/tester/seed-data/authored/content-discovery__parts-database.d.ts +0 -2
  144. package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +0 -167
  145. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +0 -2
  146. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +0 -73
  147. package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +0 -2
  148. package/dist/features/tester/seed-data/authored/content-discovery__search.js +0 -363
  149. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +0 -2
  150. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +0 -340
  151. package/dist/features/tester/seed-data/authored/content-discovery__store-reviews-aggregate.d.ts +0 -2
  152. package/dist/features/tester/seed-data/authored/content-discovery__store-reviews-aggregate.js +0 -88
  153. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +0 -2
  154. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +0 -78
  155. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +0 -2
  156. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +0 -76
  157. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +0 -2
  158. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +0 -62
  159. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +0 -2
  160. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +0 -163
  161. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +0 -2
  162. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +0 -61
  163. package/dist/features/tester/seed-data/authored/design-ux__action-bar-placement.d.ts +0 -2
  164. package/dist/features/tester/seed-data/authored/design-ux__action-bar-placement.js +0 -89
  165. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +0 -2
  166. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +0 -95
  167. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +0 -2
  168. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +0 -191
  169. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +0 -2
  170. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +0 -158
  171. package/dist/features/tester/seed-data/authored/design-ux__feature-badge-picker.d.ts +0 -2
  172. package/dist/features/tester/seed-data/authored/design-ux__feature-badge-picker.js +0 -82
  173. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +0 -2
  174. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +0 -106
  175. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +0 -2
  176. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +0 -88
  177. package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +0 -2
  178. package/dist/features/tester/seed-data/authored/design-ux__general-design.js +0 -204
  179. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +0 -2
  180. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +0 -301
  181. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +0 -2
  182. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +0 -90
  183. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.d.ts +0 -2
  184. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.js +0 -85
  185. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +0 -2
  186. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +0 -407
  187. package/dist/features/tester/seed-data/authored/design-ux__nav-reachability.d.ts +0 -2
  188. package/dist/features/tester/seed-data/authored/design-ux__nav-reachability.js +0 -88
  189. package/dist/features/tester/seed-data/authored/design-ux__rich-text-readability.d.ts +0 -2
  190. package/dist/features/tester/seed-data/authored/design-ux__rich-text-readability.js +0 -84
  191. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +0 -2
  192. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +0 -214
  193. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +0 -2
  194. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +0 -275
  195. package/dist/features/tester/seed-data/authored/index.d.ts +0 -2
  196. package/dist/features/tester/seed-data/authored/index.js +0 -301
  197. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +0 -2
  198. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +0 -125
  199. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +0 -2
  200. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +0 -85
  201. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +0 -2
  202. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +0 -92
  203. package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +0 -2
  204. package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +0 -115
  205. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +0 -2
  206. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +0 -137
  207. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +0 -2
  208. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +0 -263
  209. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +0 -2
  210. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +0 -229
  211. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +0 -2
  212. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +0 -325
  213. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +0 -2
  214. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +0 -126
  215. package/dist/features/tester/seed-data/authored/public-pages__newly-wired-browse-indexes.d.ts +0 -2
  216. package/dist/features/tester/seed-data/authored/public-pages__newly-wired-browse-indexes.js +0 -141
  217. package/dist/features/tester/seed-data/authored/public-pages__store-tabs.d.ts +0 -2
  218. package/dist/features/tester/seed-data/authored/public-pages__store-tabs.js +0 -115
  219. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +0 -2
  220. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +0 -253
  221. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +0 -2
  222. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +0 -93
  223. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +0 -3
  224. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +0 -185
  225. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +0 -2
  226. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +0 -82
  227. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +0 -2
  228. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +0 -60
  229. package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +0 -2
  230. package/dist/features/tester/seed-data/authored/selling__become-seller.js +0 -117
  231. package/dist/features/tester/seed-data/authored/selling__digital-content-delivery.d.ts +0 -2
  232. package/dist/features/tester/seed-data/authored/selling__digital-content-delivery.js +0 -148
  233. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +0 -2
  234. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +0 -108
  235. package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +0 -2
  236. package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +0 -274
  237. package/dist/features/tester/seed-data/authored/selling__listing-edit-roundtrip.d.ts +0 -2
  238. package/dist/features/tester/seed-data/authored/selling__listing-edit-roundtrip.js +0 -145
  239. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +0 -2
  240. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +0 -336
  241. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +0 -2
  242. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +0 -136
  243. package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +0 -2
  244. package/dist/features/tester/seed-data/authored/selling__media-limits.js +0 -135
  245. package/dist/features/tester/seed-data/authored/selling__product-upload-details.d.ts +0 -2
  246. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +0 -155
  247. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.d.ts +0 -2
  248. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -138
  249. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +0 -2
  250. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +0 -191
  251. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +0 -2
  252. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +0 -138
  253. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +0 -2
  254. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +0 -106
  255. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +0 -2
  256. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +0 -192
  257. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +0 -2
  258. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +0 -109
  259. package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +0 -2
  260. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +0 -34
  261. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +0 -2
  262. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +0 -348
  263. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +0 -2
  264. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -87
  265. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +0 -2
  266. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +0 -90
  267. package/dist/features/tester/seed-data/authored/selling__seller-orders-at-scale.d.ts +0 -2
  268. package/dist/features/tester/seed-data/authored/selling__seller-orders-at-scale.js +0 -85
  269. package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +0 -2
  270. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +0 -213
  271. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +0 -2
  272. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +0 -192
  273. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +0 -2
  274. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +0 -77
  275. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +0 -2
  276. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +0 -165
  277. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +0 -2
  278. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +0 -116
  279. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +0 -2
  280. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +0 -127
  281. package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +0 -2
  282. package/dist/features/tester/seed-data/authored/seo__og-images.js +0 -107
  283. package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +0 -2
  284. package/dist/features/tester/seed-data/authored/seo__page-metadata.js +0 -120
  285. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +0 -2
  286. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +0 -105
  287. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +0 -2
  288. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +0 -58
  289. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +0 -2
  290. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +0 -284
  291. package/dist/features/tester/seed-data/index.d.ts +0 -2
  292. package/dist/features/tester/seed-data/index.js +0 -2
  293. package/dist/features/tester/seed-data/tester-checklist-seed-data.d.ts +0 -2
  294. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +0 -7601
  295. package/dist/features/tester/seed-data/tester-responses-seed-data.d.ts +0 -2
  296. package/dist/features/tester/seed-data/tester-responses-seed-data.js +0 -95
  297. package/dist/features/tester/seed-data/tester-window.d.ts +0 -25
  298. package/dist/features/tester/seed-data/tester-window.js +0 -66
  299. package/dist/seed/_helpers/brand-rows.d.ts +0 -35
  300. package/dist/seed/_helpers/brand-rows.js +0 -600
  301. package/dist/seed/_helpers/category-content-generated.d.ts +0 -24
  302. package/dist/seed/_helpers/category-content-generated.js +0 -1853
  303. package/dist/seed/_helpers/category-content.d.ts +0 -68
  304. package/dist/seed/_helpers/category-content.js +0 -731
  305. package/dist/seed/_helpers/category-forest.d.ts +0 -4
  306. package/dist/seed/_helpers/category-forest.js +0 -824
  307. package/dist/seed/_helpers/category-images-generated.d.ts +0 -57
  308. package/dist/seed/_helpers/category-images-generated.js +0 -618
  309. package/dist/seed/_helpers/category-models/chunk0.d.ts +0 -2
  310. package/dist/seed/_helpers/category-models/chunk0.js +0 -2648
  311. package/dist/seed/_helpers/category-models/chunk1.d.ts +0 -2
  312. package/dist/seed/_helpers/category-models/chunk1.js +0 -2318
  313. package/dist/seed/_helpers/category-models/chunk2.d.ts +0 -2
  314. package/dist/seed/_helpers/category-models/chunk2.js +0 -2560
  315. package/dist/seed/_helpers/category-models/chunk3.d.ts +0 -2
  316. package/dist/seed/_helpers/category-models/chunk3.js +0 -2196
  317. package/dist/seed/_helpers/category-models/chunk4.d.ts +0 -2
  318. package/dist/seed/_helpers/category-models/chunk4.js +0 -1732
  319. package/dist/seed/_helpers/category-models.d.ts +0 -12
  320. package/dist/seed/_helpers/category-models.js +0 -45
  321. package/dist/seed/_helpers/category-names.d.ts +0 -54
  322. package/dist/seed/_helpers/category-names.js +0 -118
  323. package/dist/seed/_helpers/category-parts-glossary-map.d.ts +0 -1
  324. package/dist/seed/_helpers/category-parts-glossary-map.js +0 -2499
  325. package/dist/seed/_helpers/category-parts.d.ts +0 -9
  326. package/dist/seed/_helpers/category-parts.js +0 -15022
  327. package/dist/seed/_helpers/category-tree.d.ts +0 -27
  328. package/dist/seed/_helpers/category-tree.js +0 -119
  329. package/dist/seed/_helpers/character-features.d.ts +0 -10
  330. package/dist/seed/_helpers/character-features.js +0 -120
  331. package/dist/seed/_helpers/final-sale-fixtures.d.ts +0 -35
  332. package/dist/seed/_helpers/final-sale-fixtures.js +0 -61
  333. package/dist/seed/_helpers/franchise-rows.d.ts +0 -43
  334. package/dist/seed/_helpers/franchise-rows.js +0 -189
  335. package/dist/seed/_helpers/media.d.ts +0 -67
  336. package/dist/seed/_helpers/media.js +0 -172
  337. package/dist/seed/_helpers/part-colours-generated.d.ts +0 -18
  338. package/dist/seed/_helpers/part-colours-generated.js +0 -273
  339. package/dist/seed/_helpers/product-search-txt.d.ts +0 -18
  340. package/dist/seed/_helpers/product-search-txt.js +0 -23
  341. package/dist/seed/_helpers/search-txt-wrappers.d.ts +0 -26
  342. package/dist/seed/_helpers/search-txt-wrappers.js +0 -58
  343. package/dist/seed/addresses-seed-data.d.ts +0 -2
  344. package/dist/seed/addresses-seed-data.js +0 -78
  345. package/dist/seed/authenticity-knowledge-seed-data.d.ts +0 -78
  346. package/dist/seed/authenticity-knowledge-seed-data.js +0 -10729
  347. package/dist/seed/bey-products-seed-data.d.ts +0 -18
  348. package/dist/seed/bey-products-seed-data.js +0 -18011
  349. package/dist/seed/beys/chunk0.d.ts +0 -17
  350. package/dist/seed/beys/chunk0.js +0 -36733
  351. package/dist/seed/beys/chunk1.d.ts +0 -17
  352. package/dist/seed/beys/chunk1.js +0 -35728
  353. package/dist/seed/beys/chunk2.d.ts +0 -17
  354. package/dist/seed/beys/chunk2.js +0 -35857
  355. package/dist/seed/beys/chunk3.d.ts +0 -17
  356. package/dist/seed/beys/chunk3.js +0 -34476
  357. package/dist/seed/beys-seed-data.d.ts +0 -18
  358. package/dist/seed/beys-seed-data.js +0 -11
  359. package/dist/seed/bids-seed-data.d.ts +0 -2
  360. package/dist/seed/bids-seed-data.js +0 -206
  361. package/dist/seed/blog-posts-seed-data.d.ts +0 -6
  362. package/dist/seed/blog-posts-seed-data.js +0 -442
  363. package/dist/seed/carousel-slides-seed-data.d.ts +0 -2
  364. package/dist/seed/carousel-slides-seed-data.js +0 -411
  365. package/dist/seed/carousels-seed-data.d.ts +0 -2
  366. package/dist/seed/carousels-seed-data.js +0 -36
  367. package/dist/seed/cart-seed-data.d.ts +0 -2
  368. package/dist/seed/cart-seed-data.js +0 -241
  369. package/dist/seed/catalogue-seed-data.d.ts +0 -2
  370. package/dist/seed/catalogue-seed-data.js +0 -112
  371. package/dist/seed/categories-seed-data.d.ts +0 -3
  372. package/dist/seed/categories-seed-data.js +0 -816
  373. package/dist/seed/claimed-coupons-seed-data.d.ts +0 -2
  374. package/dist/seed/claimed-coupons-seed-data.js +0 -85
  375. package/dist/seed/coupon-usage-seed-data.d.ts +0 -9
  376. package/dist/seed/coupon-usage-seed-data.js +0 -55
  377. package/dist/seed/coupons-seed-data.d.ts +0 -2
  378. package/dist/seed/coupons-seed-data.js +0 -226
  379. package/dist/seed/defaults/categories.d.ts +0 -2
  380. package/dist/seed/defaults/categories.js +0 -12
  381. package/dist/seed/defaults/faqs.d.ts +0 -2
  382. package/dist/seed/defaults/faqs.js +0 -40
  383. package/dist/seed/events-seed-data.d.ts +0 -7
  384. package/dist/seed/events-seed-data.js +0 -482
  385. package/dist/seed/factories/address.factory.d.ts +0 -21
  386. package/dist/seed/factories/address.factory.js +0 -44
  387. package/dist/seed/factories/bid.factory.d.ts +0 -15
  388. package/dist/seed/factories/bid.factory.js +0 -33
  389. package/dist/seed/factories/blog-post.factory.d.ts +0 -15
  390. package/dist/seed/factories/blog-post.factory.js +0 -22
  391. package/dist/seed/factories/carousel.factory.d.ts +0 -11
  392. package/dist/seed/factories/carousel.factory.js +0 -17
  393. package/dist/seed/factories/cart.factory.d.ts +0 -25
  394. package/dist/seed/factories/cart.factory.js +0 -35
  395. package/dist/seed/factories/category.factory.d.ts +0 -11
  396. package/dist/seed/factories/category.factory.js +0 -16
  397. package/dist/seed/factories/coupon.factory.d.ts +0 -21
  398. package/dist/seed/factories/coupon.factory.js +0 -43
  399. package/dist/seed/factories/faq.factory.d.ts +0 -10
  400. package/dist/seed/factories/faq.factory.js +0 -15
  401. package/dist/seed/factories/notification.factory.d.ts +0 -18
  402. package/dist/seed/factories/notification.factory.js +0 -39
  403. package/dist/seed/factories/order.factory.d.ts +0 -20
  404. package/dist/seed/factories/order.factory.js +0 -20
  405. package/dist/seed/factories/payout.factory.d.ts +0 -21
  406. package/dist/seed/factories/payout.factory.js +0 -38
  407. package/dist/seed/factories/product.factory.d.ts +0 -27
  408. package/dist/seed/factories/product.factory.js +0 -80
  409. package/dist/seed/factories/review.factory.d.ts +0 -14
  410. package/dist/seed/factories/review.factory.js +0 -52
  411. package/dist/seed/factories/session.factory.d.ts +0 -15
  412. package/dist/seed/factories/session.factory.js +0 -31
  413. package/dist/seed/factories/store.factory.d.ts +0 -23
  414. package/dist/seed/factories/store.factory.js +0 -47
  415. package/dist/seed/factories/user.factory.d.ts +0 -19
  416. package/dist/seed/factories/user.factory.js +0 -56
  417. package/dist/seed/faq-seed-data.d.ts +0 -18
  418. package/dist/seed/faq-seed-data.js +0 -1956
  419. package/dist/seed/firestore-indexes.d.ts +0 -12
  420. package/dist/seed/firestore-indexes.js +0 -31
  421. package/dist/seed/grouped-listings-seed-data.d.ts +0 -2
  422. package/dist/seed/grouped-listings-seed-data.js +0 -283
  423. package/dist/seed/history-seed-data.d.ts +0 -12
  424. package/dist/seed/history-seed-data.js +0 -70
  425. package/dist/seed/homepage-sections-seed-data.d.ts +0 -2
  426. package/dist/seed/homepage-sections-seed-data.js +0 -1034
  427. package/dist/seed/index.d.ts +0 -100
  428. package/dist/seed/index.js +0 -115
  429. package/dist/seed/lottery-entries-seed-data.d.ts +0 -2
  430. package/dist/seed/lottery-entries-seed-data.js +0 -108
  431. package/dist/seed/manifest.d.ts +0 -16
  432. package/dist/seed/manifest.js +0 -235
  433. package/dist/seed/media-assets-seed-data.d.ts +0 -22
  434. package/dist/seed/media-assets-seed-data.js +0 -5593
  435. package/dist/seed/model-composition-seed-data.d.ts +0 -15
  436. package/dist/seed/model-composition-seed-data.js +0 -9032
  437. package/dist/seed/notifications-seed-data.d.ts +0 -2
  438. package/dist/seed/notifications-seed-data.js +0 -606
  439. package/dist/seed/offers-seed-data.d.ts +0 -2
  440. package/dist/seed/offers-seed-data.js +0 -398
  441. package/dist/seed/orders-seed-data.d.ts +0 -2
  442. package/dist/seed/orders-seed-data.js +0 -845
  443. package/dist/seed/part-glossary/chunk0.d.ts +0 -9
  444. package/dist/seed/part-glossary/chunk0.js +0 -35448
  445. package/dist/seed/part-glossary/chunk1.d.ts +0 -9
  446. package/dist/seed/part-glossary/chunk1.js +0 -40494
  447. package/dist/seed/part-glossary/chunk2.d.ts +0 -9
  448. package/dist/seed/part-glossary/chunk2.js +0 -51242
  449. package/dist/seed/part-glossary/chunk3.d.ts +0 -9
  450. package/dist/seed/part-glossary/chunk3.js +0 -53337
  451. package/dist/seed/part-glossary/chunk4.d.ts +0 -9
  452. package/dist/seed/part-glossary/chunk4.js +0 -51454
  453. package/dist/seed/part-glossary-seed-data.d.ts +0 -15
  454. package/dist/seed/part-glossary-seed-data.js +0 -25
  455. package/dist/seed/payouts-seed-data.d.ts +0 -2
  456. package/dist/seed/payouts-seed-data.js +0 -302
  457. package/dist/seed/product-features-seed-data.d.ts +0 -3
  458. package/dist/seed/product-features-seed-data.js +0 -366
  459. package/dist/seed/products-art-seed-data.d.ts +0 -2
  460. package/dist/seed/products-art-seed-data.js +0 -289
  461. package/dist/seed/products-auctions-seed-data.d.ts +0 -2
  462. package/dist/seed/products-auctions-seed-data.js +0 -475
  463. package/dist/seed/products-beyblade-x-seed-data.d.ts +0 -2
  464. package/dist/seed/products-beyblade-x-seed-data.js +0 -476
  465. package/dist/seed/products-catalogue/chunk0.d.ts +0 -12
  466. package/dist/seed/products-catalogue/chunk0.js +0 -7262
  467. package/dist/seed/products-catalogue/chunk1.d.ts +0 -12
  468. package/dist/seed/products-catalogue/chunk1.js +0 -7290
  469. package/dist/seed/products-catalogue/chunk10.d.ts +0 -12
  470. package/dist/seed/products-catalogue/chunk10.js +0 -7290
  471. package/dist/seed/products-catalogue/chunk11.d.ts +0 -12
  472. package/dist/seed/products-catalogue/chunk11.js +0 -7005
  473. package/dist/seed/products-catalogue/chunk12.d.ts +0 -12
  474. package/dist/seed/products-catalogue/chunk12.js +0 -7002
  475. package/dist/seed/products-catalogue/chunk13.d.ts +0 -12
  476. package/dist/seed/products-catalogue/chunk13.js +0 -7002
  477. package/dist/seed/products-catalogue/chunk14.d.ts +0 -12
  478. package/dist/seed/products-catalogue/chunk14.js +0 -7002
  479. package/dist/seed/products-catalogue/chunk15.d.ts +0 -12
  480. package/dist/seed/products-catalogue/chunk15.js +0 -7002
  481. package/dist/seed/products-catalogue/chunk16.d.ts +0 -12
  482. package/dist/seed/products-catalogue/chunk16.js +0 -7002
  483. package/dist/seed/products-catalogue/chunk17.d.ts +0 -12
  484. package/dist/seed/products-catalogue/chunk17.js +0 -7002
  485. package/dist/seed/products-catalogue/chunk18.d.ts +0 -12
  486. package/dist/seed/products-catalogue/chunk18.js +0 -4398
  487. package/dist/seed/products-catalogue/chunk2.d.ts +0 -12
  488. package/dist/seed/products-catalogue/chunk2.js +0 -7268
  489. package/dist/seed/products-catalogue/chunk3.d.ts +0 -12
  490. package/dist/seed/products-catalogue/chunk3.js +0 -7264
  491. package/dist/seed/products-catalogue/chunk4.d.ts +0 -12
  492. package/dist/seed/products-catalogue/chunk4.js +0 -7268
  493. package/dist/seed/products-catalogue/chunk5.d.ts +0 -12
  494. package/dist/seed/products-catalogue/chunk5.js +0 -7258
  495. package/dist/seed/products-catalogue/chunk6.d.ts +0 -12
  496. package/dist/seed/products-catalogue/chunk6.js +0 -7268
  497. package/dist/seed/products-catalogue/chunk7.d.ts +0 -12
  498. package/dist/seed/products-catalogue/chunk7.js +0 -7311
  499. package/dist/seed/products-catalogue/chunk8.d.ts +0 -12
  500. package/dist/seed/products-catalogue/chunk8.js +0 -7304
  501. package/dist/seed/products-catalogue/chunk9.d.ts +0 -12
  502. package/dist/seed/products-catalogue/chunk9.js +0 -7309
  503. package/dist/seed/products-catalogue-seed-data.d.ts +0 -2
  504. package/dist/seed/products-catalogue-seed-data.js +0 -60
  505. package/dist/seed/products-classifieds-seed-data.d.ts +0 -7
  506. package/dist/seed/products-classifieds-seed-data.js +0 -435
  507. package/dist/seed/products-digital-codes-seed-data.d.ts +0 -7
  508. package/dist/seed/products-digital-codes-seed-data.js +0 -395
  509. package/dist/seed/products-live-items-seed-data.d.ts +0 -7
  510. package/dist/seed/products-live-items-seed-data.js +0 -269
  511. package/dist/seed/products-preorders-seed-data.d.ts +0 -2
  512. package/dist/seed/products-preorders-seed-data.js +0 -360
  513. package/dist/seed/products-prize-draws-seed-data.d.ts +0 -7
  514. package/dist/seed/products-prize-draws-seed-data.js +0 -427
  515. package/dist/seed/products-spares-seed-data.d.ts +0 -2
  516. package/dist/seed/products-spares-seed-data.js +0 -368
  517. package/dist/seed/products-standard-seed-data.d.ts +0 -2
  518. package/dist/seed/products-standard-seed-data.js +0 -632
  519. package/dist/seed/products-stickers-seed-data.d.ts +0 -2
  520. package/dist/seed/products-stickers-seed-data.js +0 -319
  521. package/dist/seed/reviews-seed-data.d.ts +0 -1
  522. package/dist/seed/reviews-seed-data.js +0 -185
  523. package/dist/seed/runner.d.ts +0 -2
  524. package/dist/seed/runner.js +0 -125
  525. package/dist/seed/scammers-seed-data.d.ts +0 -2
  526. package/dist/seed/scammers-seed-data.js +0 -235
  527. package/dist/seed/seed-market-config.d.ts +0 -48
  528. package/dist/seed/seed-market-config.js +0 -199
  529. package/dist/seed/seed-purpose.d.ts +0 -299
  530. package/dist/seed/seed-purpose.js +0 -440
  531. package/dist/seed/sessions-seed-data.d.ts +0 -3
  532. package/dist/seed/sessions-seed-data.js +0 -116
  533. package/dist/seed/shipments-seed-data.d.ts +0 -5
  534. package/dist/seed/shipments-seed-data.js +0 -185
  535. package/dist/seed/site-settings-seed-data.d.ts +0 -2
  536. package/dist/seed/site-settings-seed-data.js +0 -1069
  537. package/dist/seed/store-addresses-seed-data.d.ts +0 -18
  538. package/dist/seed/store-addresses-seed-data.js +0 -71
  539. package/dist/seed/store-extensions-seed-data.d.ts +0 -11
  540. package/dist/seed/store-extensions-seed-data.js +0 -292
  541. package/dist/seed/stores-seed-data.d.ts +0 -6
  542. package/dist/seed/stores-seed-data.js +0 -242
  543. package/dist/seed/support-tickets-seed-data.d.ts +0 -16
  544. package/dist/seed/support-tickets-seed-data.js +0 -239
  545. package/dist/seed/tax-codes-seed-data.d.ts +0 -34
  546. package/dist/seed/tax-codes-seed-data.js +0 -100
  547. package/dist/seed/test-data-ttl.d.ts +0 -29
  548. package/dist/seed/test-data-ttl.js +0 -31
  549. package/dist/seed/test-utils.d.ts +0 -49
  550. package/dist/seed/test-utils.js +0 -110
  551. package/dist/seed/types.d.ts +0 -89
  552. package/dist/seed/types.js +0 -15
  553. package/dist/seed/users-seed-data.d.ts +0 -2
  554. package/dist/seed/users-seed-data.js +0 -597
  555. package/dist/seed/wishlists-seed-data.d.ts +0 -12
  556. package/dist/seed/wishlists-seed-data.js +0 -54
@@ -1,816 +0,0 @@
1
- /*
2
- * WHY: The real catalogue taxonomy. 🛑 This file is NO LONGER Beyblade-only —
3
- * its header said "narrowed to Beyblade so the demo has a coherent
4
- * dataset instead of a sprawling multi-franchise catalog" and B5 reversed
5
- * that deliberately, on evidence: a 15-site crawl of ~25,900 live Indian
6
- * listings showed trading cards, collectible figures and Hot Wheels are
7
- * each a real vertical with its own measured price bands, and three of
8
- * the five largest competitors sell more than one of them.
9
- *
10
- * The old framing is not contradicted here, it is superseded — coherence
11
- * now comes from the TREE being one axis deep per vertical rather than
12
- * from the catalogue being one franchise wide.
13
- *
14
- * WHAT: Exports categoriesSeedData — a 5-level, SIX-root forest (Spinning Tops,
15
- * Trading Cards, Collectible Figures, Hot Wheels, Model Kits, Living
16
- * Collectibles — see _helpers/category-forest.ts), 28 brand rows
17
- * (categoryType:"brand", _helpers/brand-rows.ts), two sublisting rows and
18
- * five pricing bundles (categoryType:"bundle").
19
- *
20
- * The tree was 2 levels under a single root until 2026-08-24 and 47 nodes
21
- * across 2 roots until B5. The first state made
22
- * `categoryType:"sublisting"` — documented as "tier-4 leaf groups under a
23
- * parent category" — structurally unreachable, and left the live-item
24
- * products with no category at all.
25
- *
26
- * The tier-4 layer is 216 NAMED MODEL leaves (Lost Longinus, Storm
27
- * Pegasus, Dran Sword …), GENERATED from the canonical corpus in
28
- * _helpers/category-models.ts rather than typed by hand — a slug is the
29
- * document id, the public URL and a searchTxt source, so it is the one
30
- * field that cannot be quietly corrected later.
31
- *
32
- * Products tag their FULL ancestor chain (leaf -> … -> root) so a single
33
- * array-contains at any level returns the whole subtree. That is what lets
34
- * a category page match on its own id alone; expanding descendants into an
35
- * `array-contains-any` would break past Firestore's 30-value cap.
36
- *
37
- * Structural fields (parentIds/ancestors/tier/path/position/subtreeSize/
38
- * childrenIds/isLeaf) are DERIVED by buildCategoryTree — never hand-written.
39
- * The old hand-written values were already internally inconsistent: the root
40
- * claimed subtreeSize 4 at position 0 while its four children also occupied
41
- * positions 0-3, which is not a valid DFS pre-order numbering.
42
- *
43
- * EXPORTS:
44
- * categoriesSeedData — array of Partial<CategoryDocument> for the seed runner
45
- *
46
- * @tag domain:categories,brands
47
- * @tag layer:seed
48
- * @tag pattern:none
49
- * @tag access:server-only
50
- * @tag consumers:seed/runner.ts
51
- * @tag sideEffects:none
52
- */
53
- import { CATEGORY_FIELDS } from "../constants/field-names.js";
54
- import { seedPhoto, isSeedPlaceholderImage } from "./_helpers/media.js";
55
- import { buildCategoryTree } from "./_helpers/category-tree.js";
56
- import { withCategorySearchTxt } from "./_helpers/search-txt-wrappers.js";
57
- import { CATEGORY_FOREST } from "./_helpers/category-forest.js";
58
- import { BRAND_ROW_COUNT, buildBrandRows } from "./_helpers/brand-rows.js";
59
- import { FRANCHISE_ROW_COUNT, buildFranchiseRows } from "./_helpers/franchise-rows.js";
60
- import { MODEL_LEAF_COUNT, MODEL_LEAVES } from "./_helpers/category-models.js";
61
- import { PART_LEAF_COUNT, PART_LEAVES } from "./_helpers/category-parts.js";
62
- import { MARKET_BAND_LEAF_IDS } from "./_helpers/category-content.js";
63
- import { GENERATED_CATEGORY_CONTENT, GENERATED_CATEGORY_CONTENT_COUNT, } from "./_helpers/category-content-generated.js";
64
- import { GENERATED_CATEGORY_IMAGES, GENERATED_CATEGORY_IMAGE_COUNT, GENERATED_CATEGORY_HASBRO_IMAGES, } from "./_helpers/category-images-generated.js";
65
- import { productsStandardSeedData } from "./products-standard-seed-data.js";
66
- import { productsBeybladeXSeedData } from "./products-beyblade-x-seed-data.js";
67
- const NOW = new Date();
68
- const daysAgo = (n) => new Date(NOW.getTime() - n * 86400000);
69
- const emptyMetrics = {
70
- productCount: 0,
71
- productIds: [],
72
- auctionCount: 0,
73
- auctionIds: [],
74
- totalProductCount: 0,
75
- totalAuctionCount: 0,
76
- totalItemCount: 0,
77
- lastUpdated: daysAgo(1),
78
- };
79
- // ──────────────────────────────────────────────────────────────────────────────
80
- // Categories — 381 rows across 5 tiers and 6 roots, every structural field
81
- // derived. The shape lives in _helpers/category-forest.ts, the named-model
82
- // tier-4 leaves in the GENERATED _helpers/category-models.ts, and the
83
- // derivation in _helpers/category-tree.ts.
84
- //
85
- // 🛑 Never quote this count without running `buildCategoryTree` against the
86
- // forest — it was 47 before B5 and the comment here said so for months after
87
- // the tree changed underneath it.
88
- // ──────────────────────────────────────────────────────────────────────────────
89
- const rawCategories = buildCategoryTree(CATEGORY_FOREST, {
90
- createdBy: "user-admin-letitrip",
91
- createdAt: daysAgo(300),
92
- updatedAt: daysAgo(1),
93
- defaults: {
94
- metrics: emptyMetrics,
95
- isFeatured: false,
96
- isActive: true,
97
- isSearchable: true,
98
- showOnHomepage: false,
99
- },
100
- });
101
- /**
102
- * Sublistings — `categoryType:"sublisting"`, documented on `CategoryDocument`
103
- * as "tier-4 leaf groups under a parent category". This array was EMPTY for the
104
- * life of the seed, because the tree only went two levels deep and there was no
105
- * tier-3 leaf to hang a tier-4 group off. Now that there is, these give
106
- * `itemCode` and `ProductDocument.sublistingCategoryId` / `sublistingIcon`
107
- * their first real data.
108
- *
109
- * `itemCode` is the grading/variant code a collector actually searches by.
110
- */
111
- const sublistingRows = [
112
- {
113
- id: "sublisting-dranzer-s-a-5",
114
- slug: "sublisting-dranzer-s-a-5",
115
- name: "Dranzer S (A-5)",
116
- description: "The A-5 Dranzer S release — the original Plastic Generation Dranzer.",
117
- categoryType: CATEGORY_FIELDS.CATEGORY_TYPE_VALUES.SUBLISTING,
118
- itemCode: "A-5",
119
- rootId: "category-spinning-tops",
120
- parentIds: [
121
- "category-spinning-tops",
122
- "category-beyblade-original",
123
- "category-original-tops",
124
- "category-original-plastic-gen",
125
- ],
126
- childrenIds: [],
127
- ancestors: [
128
- { id: "category-spinning-tops", name: "Spinning Tops", tier: 0 },
129
- { id: "category-beyblade-original", name: "Beyblade Original", tier: 1 },
130
- { id: "category-original-tops", name: "Original Tops", tier: 2 },
131
- { id: "category-original-plastic-gen", name: "Plastic Generation", tier: 3 },
132
- ],
133
- tier: 4,
134
- path: "spinning-tops/beyblade-original/original-tops/original-plastic-gen/dranzer-s-a-5",
135
- isLeaf: true,
136
- order: 1,
137
- position: 900,
138
- subtreeSize: 1,
139
- metrics: emptyMetrics,
140
- isFeatured: false,
141
- isActive: true,
142
- isSearchable: true,
143
- display: { icon: "🔥", showInMenu: false, showInFooter: false },
144
- seo: { title: "Dranzer S (A-5) | LetItRip", description: "The A-5 Dranzer S release.", keywords: ["dranzer s", "a-5", "plastic generation"] },
145
- createdBy: "user-admin-letitrip",
146
- createdAt: daysAgo(300),
147
- updatedAt: daysAgo(30),
148
- },
149
- {
150
- id: "sublisting-storm-pegasus-105rf",
151
- slug: "sublisting-storm-pegasus-105rf",
152
- name: "Storm Pegasus 105RF",
153
- description: "Storm Pegasus on a 105 track with a Rubber Flat bottom — the canonical attack build.",
154
- categoryType: CATEGORY_FIELDS.CATEGORY_TYPE_VALUES.SUBLISTING,
155
- itemCode: "105RF",
156
- rootId: "category-spinning-tops",
157
- parentIds: [
158
- "category-spinning-tops",
159
- "category-beyblade-metal",
160
- "category-metal-tops",
161
- "category-metal-fusion",
162
- ],
163
- childrenIds: [],
164
- ancestors: [
165
- { id: "category-spinning-tops", name: "Spinning Tops", tier: 0 },
166
- { id: "category-beyblade-metal", name: "Beyblade Metal Fight", tier: 1 },
167
- { id: "category-metal-tops", name: "Metal Fight Tops", tier: 2 },
168
- { id: "category-metal-fusion", name: "Metal Fusion", tier: 3 },
169
- ],
170
- tier: 4,
171
- path: "spinning-tops/beyblade-metal/metal-tops/metal-fusion/storm-pegasus-105rf",
172
- isLeaf: true,
173
- order: 2,
174
- position: 901,
175
- subtreeSize: 1,
176
- metrics: emptyMetrics,
177
- isFeatured: false,
178
- isActive: true,
179
- isSearchable: true,
180
- display: { icon: "🐴", showInMenu: false, showInFooter: false },
181
- seo: { title: "Storm Pegasus 105RF | LetItRip", description: "Storm Pegasus 105RF builds.", keywords: ["storm pegasus", "105rf", "metal fusion"] },
182
- createdBy: "user-admin-letitrip",
183
- createdAt: daysAgo(300),
184
- updatedAt: daysAgo(30),
185
- },
186
- ];
187
- // ──────────────────────────────────────────────────────────────────────────────
188
- // Brands (categoryType:"brand") — 4 rows -> 28, built by a factory.
189
- //
190
- // The shape, the three live traps (display-name matching, icon-beats-cover,
191
- // and why a brand with no products is worse than no brand) and the logo
192
- // decision all live in _helpers/brand-rows.ts. Four inline rows at ~35 lines
193
- // each was already the wrong shape for 28.
194
- // ──────────────────────────────────────────────────────────────────────────────
195
- const brandRows = buildBrandRows({
196
- createdBy: "user-admin-letitrip",
197
- createdAt: daysAgo(300),
198
- updatedAt: daysAgo(30),
199
- });
200
- // FRANCHISE rows — what a product is FROM, where a brand is who MADE it.
201
- // Same tier-0, outside-the-forest shape as brands. Seven of the eight are
202
- // seeded INACTIVE on purpose; see the dead-facet rule in _helpers/franchise-rows.ts.
203
- const franchiseRows = buildFranchiseRows({
204
- createdBy: "user-admin-letitrip",
205
- createdAt: daysAgo(300),
206
- updatedAt: daysAgo(30),
207
- });
208
- // P-17 — 5 bundle rows (categoryType:"bundle") grouping the Beyblade-minimal
209
- // standard products by generation, plus one cross-generation starter pack.
210
- // Every bundle references real seeded product ids (products-standard-seed-data.ts),
211
- // all currently under store-beyblade-arena.
212
- /*
213
- * 🛑 `bundleCategorySlugs` is DERIVED, because it is a MIRROR and mirrors
214
- * drift (Root Cause #42).
215
- *
216
- * The field is the union of the members' `categorySlugs`, and it is what lets
217
- * a category page scope its Bundles tab at all. It was hand-written across
218
- * all five bundles — and it drifted in B5 the moment the Beyblade X tree
219
- * changed: two bundles still named `category-x-starters` and
220
- * `category-x-boosters`, leaves that no longer exist, so those bundles had
221
- * silently stopped appearing under any Beyblade X category.
222
- *
223
- * Worse, the stale strings were still being READ as valid seed ids by
224
- * `audit-tester-plugin-wiring` R7 once its id scan was widened, which briefly
225
- * made two genuinely-broken authored tester cases stop being reported. A
226
- * hand-maintained mirror does not only go wrong — it can keep the check that
227
- * would have caught it quiet.
228
- *
229
- * Deriving from the members' own chains means the union cannot disagree with
230
- * them, and a member whose chain moves updates every bundle holding it.
231
- */
232
- /*
233
- * Both real-product arrays, not just the standard one.
234
- *
235
- * `productsBeybladeXSeedData` was added 2026-10-19 as a separate file (real,
236
- * wiki-verified Beyblade X listings under store-letitrip-official). A bundle
237
- * may legitimately hold one of those, and resolving only the standard array
238
- * would make `bundleCategorySlugsFor` throw "not in productsStandardSeedData"
239
- * for a product that genuinely exists — which is exactly what happened when
240
- * the two fictional X fixtures this file's bundles used to reference were
241
- * removed in favour of real ones.
242
- */
243
- const PRODUCT_CHAINS = new Map([...productsStandardSeedData, ...productsBeybladeXSeedData].map((p) => [
244
- String(p.id),
245
- (p.categorySlugs ?? []),
246
- ]));
247
- function bundleCategorySlugsFor(productIds) {
248
- const out = [];
249
- for (const id of productIds) {
250
- const chain = PRODUCT_CHAINS.get(id);
251
- /*
252
- * A member missing from the real-product seeds is a BUG, not something to
253
- * shrug past: the bundle would silently lose that member's categories and
254
- * the Bundles tab would under-report. The map was widened (rather than
255
- * this check softened) on 2026-10-19 to cover
256
- * `productsBeybladeXSeedData` as well — if another real-product file is
257
- * added, widen it again.
258
- */
259
- if (!chain) {
260
- throw new Error(`bundle member ${id} is in neither productsStandardSeedData nor productsBeybladeXSeedData`);
261
- }
262
- for (const c of chain)
263
- if (!out.includes(c))
264
- out.push(c);
265
- }
266
- return out;
267
- }
268
- /**
269
- * Attach a bundle's member images so its card can render a collage.
270
- *
271
- * 🛑 A bundle IS its contents, so a single placeholder tile is the least
272
- * informative thing a bundle card can show. Resolved here, at seed time, from
273
- * the members' own `mainImage` — a card cannot do it at render time without one
274
- * query per bundle, and a grid of five would be five reads for decoration.
275
- *
276
- * `<ImageMosaic>` renders nothing below `MOSAIC_MIN` (3), so a bundle with one
277
- * or two resolvable members quietly falls back to its cover image rather than
278
- * showing a broken collage. A member id that resolves to no product is dropped
279
- * rather than defaulted — a wrong photo is worse than one fewer tile.
280
- */
281
- function withBundleMosaic(row) {
282
- const ids = row.bundleProductIds ?? [];
283
- // `row.display` must already exist — `CategoryDocumentDisplay` requires
284
- // `showInFooter`, so spreading onto `{}` would drop a required field. Every
285
- // bundle row declares one; a row without is left untouched rather than
286
- // half-built.
287
- if (ids.length === 0 || !row.display)
288
- return row;
289
- // Both real-product arrays, for the same reason as PRODUCT_CHAINS above —
290
- // otherwise a bundle holding a Beyblade X member silently loses that tile.
291
- const images = ids
292
- .map((id) => [...productsStandardSeedData, ...productsBeybladeXSeedData].find((p) => p.id === id)
293
- ?.mainImage)
294
- .filter((src) => typeof src === "string" && src.length > 0);
295
- if (images.length === 0)
296
- return row;
297
- return { ...row, display: { ...row.display, mosaicImages: images } };
298
- }
299
- const bundleRows = [
300
- {
301
- id: "bundle-original-collectors-set",
302
- name: "Original Collector's Set",
303
- slug: "bundle-original-collectors-set",
304
- description: "Both original-generation Beyblades — Dranzer S and Driger V — bundled at a discount.",
305
- categoryType: "bundle",
306
- bundleKind: "special",
307
- brandSlug: "brand-beyblade",
308
- bundlePrice: 2999,
309
- bundleQueryRule: {
310
- type: "static",
311
- productIds: ["product-beyblade-original-dranzer-s", "product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus"],
312
- },
313
- bundleProductIds: ["product-beyblade-original-dranzer-s", "product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus"],
314
- bundleCategorySlugs: bundleCategorySlugsFor(["product-beyblade-original-dranzer-s", "product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus"]),
315
- bundleOriginalTotal: 4597, // 1499 + 1799 + 1299
316
- bundleStockStatus: "in_stock",
317
- display: { coverImage: seedPhoto("bundle-original-collectors-set-20260101", 1200, 900), showInFooter: false },
318
- isActive: true,
319
- isSearchable: true,
320
- isFeatured: true,
321
- order: 0,
322
- rootId: "bundle-original-collectors-set",
323
- parentIds: [],
324
- childrenIds: [],
325
- tier: 0,
326
- path: "bundle-original-collectors-set",
327
- position: 0,
328
- subtreeSize: 1,
329
- metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
330
- createdBy: "user-admin-letitrip",
331
- createdByType: "admin",
332
- createdAt: daysAgo(20),
333
- updatedAt: daysAgo(5),
334
- },
335
- {
336
- id: "bundle-metal-fusion-duo",
337
- name: "Metal Fusion Duo",
338
- slug: "bundle-metal-fusion-duo",
339
- description: "Storm Pegasus and Flame Sagittario — the classic Metal Fight rivalry, together.",
340
- categoryType: "bundle",
341
- bundleKind: "special",
342
- brandSlug: "brand-takara-tomy",
343
- bundlePrice: 3499,
344
- bundleQueryRule: {
345
- type: "static",
346
- productIds: ["product-beyblade-metal-storm-pegasus", "product-beyblade-metal-flame-sagittario", "product-beyblade-original-dranzer-s"],
347
- },
348
- bundleProductIds: ["product-beyblade-metal-storm-pegasus", "product-beyblade-metal-flame-sagittario", "product-beyblade-original-dranzer-s"],
349
- bundleCategorySlugs: bundleCategorySlugsFor(["product-beyblade-metal-storm-pegasus", "product-beyblade-metal-flame-sagittario", "product-beyblade-original-dranzer-s"]),
350
- bundleOriginalTotal: 3997, // 1299 + 1199 + 1499
351
- bundleStockStatus: "in_stock",
352
- display: { coverImage: seedPhoto("bundle-metal-fusion-duo-20260101", 1200, 900), showInFooter: false },
353
- isActive: true,
354
- isSearchable: true,
355
- isFeatured: false,
356
- order: 1,
357
- rootId: "bundle-metal-fusion-duo",
358
- parentIds: [],
359
- childrenIds: [],
360
- tier: 0,
361
- path: "bundle-metal-fusion-duo",
362
- position: 0,
363
- subtreeSize: 1,
364
- metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
365
- createdBy: "user-admin-letitrip",
366
- createdByType: "admin",
367
- createdAt: daysAgo(18),
368
- updatedAt: daysAgo(4),
369
- },
370
- {
371
- id: "bundle-burst-battlers-pack",
372
- name: "Burst Battlers Pack",
373
- slug: "bundle-burst-battlers-pack",
374
- description: "Valkyrie and Regalia Genesis — top-tier Burst-era attackers in one set.",
375
- categoryType: "bundle",
376
- bundleKind: "special",
377
- brandSlug: "brand-beyblade",
378
- // Was 3799 — priced ABOVE the 999+1399+1199=3597 member total (no real
379
- // discount, contradicted the bundle's whole purpose). Corrected 2026-08-19.
380
- bundlePrice: 2899,
381
- bundleQueryRule: {
382
- type: "static",
383
- productIds: ["product-beyblade-burst-valkyrie", "product-beyblade-burst-regalia-genesis", "product-beyblade-metal-flame-sagittario"],
384
- },
385
- bundleProductIds: ["product-beyblade-burst-valkyrie", "product-beyblade-burst-regalia-genesis", "product-beyblade-metal-flame-sagittario"],
386
- bundleCategorySlugs: bundleCategorySlugsFor(["product-beyblade-burst-valkyrie", "product-beyblade-burst-regalia-genesis", "product-beyblade-metal-flame-sagittario"]),
387
- bundleOriginalTotal: 3597, // 999 + 1399 + 1199
388
- bundleStockStatus: "in_stock",
389
- display: { coverImage: seedPhoto("bundle-burst-battlers-pack-20260101", 1200, 900), showInFooter: false },
390
- isActive: true,
391
- isSearchable: true,
392
- isFeatured: true,
393
- order: 2,
394
- rootId: "bundle-burst-battlers-pack",
395
- parentIds: [],
396
- childrenIds: [],
397
- tier: 0,
398
- path: "bundle-burst-battlers-pack",
399
- position: 0,
400
- subtreeSize: 1,
401
- metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
402
- createdBy: "user-admin-letitrip",
403
- createdByType: "admin",
404
- createdAt: daysAgo(15),
405
- updatedAt: daysAgo(3),
406
- },
407
- {
408
- id: "bundle-x-series-starter",
409
- name: "X-Series Starter Set",
410
- slug: "bundle-x-series-starter",
411
- description: "WizardArrow and KnightShield Ver.2.0 — the re-tuned Stamina and Defense tops from the BX-53 set, paired with a Burst-era Valkyrie.",
412
- categoryType: "bundle",
413
- bundleKind: "special",
414
- brandSlug: "brand-takara-tomy",
415
- bundlePrice: 2499,
416
- bundleQueryRule: {
417
- type: "static",
418
- productIds: ["product-beyblade-x-bx-53-wizardarrow-v2", "product-beyblade-x-bx-53-knightshield-v2", "product-beyblade-burst-valkyrie"],
419
- },
420
- bundleProductIds: ["product-beyblade-x-bx-53-wizardarrow-v2", "product-beyblade-x-bx-53-knightshield-v2", "product-beyblade-burst-valkyrie"],
421
- bundleCategorySlugs: bundleCategorySlugsFor(["product-beyblade-x-bx-53-wizardarrow-v2", "product-beyblade-x-bx-53-knightshield-v2", "product-beyblade-burst-valkyrie"]),
422
- // 1500 + 1500 + 999. Recomputed 2026-10-19 when the two fictional X
423
- // fixtures (899 + 949) were replaced by the real BX-53 component
424
- // listings — a stale total here drives a wrong discount-% badge.
425
- bundleOriginalTotal: 3999,
426
- bundleStockStatus: "in_stock",
427
- display: { coverImage: seedPhoto("bundle-x-series-starter-20260101", 1200, 900), showInFooter: false },
428
- isActive: true,
429
- isSearchable: true,
430
- isFeatured: false,
431
- order: 3,
432
- rootId: "bundle-x-series-starter",
433
- parentIds: [],
434
- childrenIds: [],
435
- tier: 0,
436
- path: "bundle-x-series-starter",
437
- position: 0,
438
- subtreeSize: 1,
439
- metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
440
- createdBy: "user-admin-letitrip",
441
- createdByType: "admin",
442
- createdAt: daysAgo(12),
443
- updatedAt: daysAgo(2),
444
- },
445
- {
446
- id: "bundle-every-generation-starter-pack",
447
- name: "Every Generation Starter Pack",
448
- slug: "bundle-every-generation-starter-pack",
449
- description: "One top from every Beyblade generation — Original, Metal Fight, Burst, and X — the ultimate collector's starter pack.",
450
- categoryType: "bundle",
451
- bundleKind: "special",
452
- // Deliberately no brandSlug — genuinely cross-brand (2 Beyblade + 2
453
- // Takara-Tomy member products), a real "no specific brand" test case.
454
- // Was 5999 — priced ABOVE the 1799+1299+999+899=4996 member total (no
455
- // real discount, contradicted the bundle's whole purpose). Corrected 2026-08-19.
456
- bundlePrice: 3999,
457
- bundleQueryRule: {
458
- type: "static",
459
- productIds: [
460
- "product-beyblade-original-driger-v",
461
- "product-beyblade-metal-storm-pegasus",
462
- "product-beyblade-burst-valkyrie",
463
- "product-beyblade-x-bx-53-wizardarrow-v2",
464
- ],
465
- },
466
- bundleProductIds: [
467
- "product-beyblade-original-driger-v",
468
- "product-beyblade-metal-storm-pegasus",
469
- "product-beyblade-burst-valkyrie",
470
- "product-beyblade-x-bx-53-wizardarrow-v2",
471
- ],
472
- bundleCategorySlugs: bundleCategorySlugsFor(["product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus", "product-beyblade-burst-valkyrie", "product-beyblade-x-bx-53-wizardarrow-v2"]),
473
- // 1799 + 1299 + 999 + 1500. Recomputed 2026-10-19 — the X member changed
474
- // from the fictional "wizard-arrow" (899) to the real BX-53 WizardArrow
475
- // 4-80B Ver.2.0 (1500).
476
- bundleOriginalTotal: 5597,
477
- bundleStockStatus: "in_stock",
478
- display: { coverImage: seedPhoto("bundle-every-generation-starter-pack-20260101", 1200, 900), showInFooter: false },
479
- isActive: true,
480
- isSearchable: true,
481
- isFeatured: true,
482
- order: 4,
483
- rootId: "bundle-every-generation-starter-pack",
484
- parentIds: [],
485
- childrenIds: [],
486
- tier: 0,
487
- path: "bundle-every-generation-starter-pack",
488
- position: 0,
489
- subtreeSize: 1,
490
- metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
491
- createdBy: "user-admin-letitrip",
492
- createdByType: "admin",
493
- createdAt: daysAgo(10),
494
- updatedAt: daysAgo(1),
495
- },
496
- ];
497
- /*
498
- * One array, wrapped once.
499
- *
500
- * `categoriesSeedData` and `categoriesP1SeedData` were two byte-identical
501
- * literals, so every change had to be made twice — and `searchTxt` would have
502
- * been two derivations to keep in step, which is the exact drift
503
- * `search-txt-wrappers.ts` exists to prevent.
504
- *
505
- * 🛑 `withCategorySearchTxt` is applied AFTER the spread, deliberately:
506
- * `buildCategorySearchTxt` indexes `path` and `ancestors[].name`, both DERIVED
507
- * by `buildCategoryTree`. Wrapping a row before derivation would index
508
- * name/slug/description only and silently drop the lineage search — typing
509
- * "burst" would stop reaching a tier-4 model under Beyblade Burst.
510
- */
511
- /**
512
- * I7 — attach the GENERATED body to any row that has one and does not already
513
- * carry a hand-authored one.
514
- *
515
- * 🛑 The generator ran and its 745 bodies were imported by NOBODY. The corpus
516
- * sat in the repo as 128 KB of dead weight: not seeded, so not in Firestore,
517
- * so unreadable by the page that renders it. The generator being written is
518
- * not the same as its output being wired, and the second half is invisible —
519
- * a category page with no body renders perfectly well, it just ranks on
520
- * nothing.
521
- *
522
- * 🛑 A HAND-AUTHORED body always wins. The four generation roots and several
523
- * tier-1 nodes carry prose written against the crawl research; the generator
524
- * composes from facts and is deliberately the weaker writer at those tiers
525
- * (its own header says the part leaves are its strongest tier). Overwriting
526
- * authored copy with composed copy would be a silent downgrade of the exact
527
- * pages this is for.
528
- *
529
- * 🛑 And nothing is INVENTED here: a row absent from the map keeps no body at
530
- * all, because `GENERATED_CATEGORY_CONTENT` omits a node it has nothing
531
- * factual to say about rather than emitting an empty one.
532
- */
533
- function withGeneratedContent(row) {
534
- if (typeof row.contentBody === "string" && row.contentBody.trim().length > 0)
535
- return row;
536
- const generated = row.id ? GENERATED_CATEGORY_CONTENT[row.id] : undefined;
537
- return generated ? { ...row, contentBody: generated } : row;
538
- }
539
- /**
540
- * Attach a fetched cover image to a bey-model leaf that has no hand-authored one.
541
- *
542
- * Same three rules as `withGeneratedContent`, for the same reasons: a
543
- * hand-authored `display.coverImage` wins, a row absent from the map keeps
544
- * nothing rather than being given a placeholder, and the map is keyed on
545
- * category id so it needs no transformation here.
546
- *
547
- * 🛑 These are LOCAL paths under `public/images/beys/`, never `seedExtMedia()`.
548
- * Wrapping a third-party image URL in `/api/media/ext` makes every render a
549
- * lambda plus an upstream fetch plus a sharp watermark pass — that is Root Cause
550
- * #104, and it is part of why this project was suspended on Fast Origin
551
- * Transfer. 195 proxied covers would have been a direct repeat.
552
- *
553
- * 🛑 Measured before this existed: **1,131 of 1,177** categories had no cover at
554
- * all, and the 46 that did shared six generic SVG colour tiles. So the
555
- * alternative to this map is not "a different image" — it is a grid of blank
556
- * cards.
557
- */
558
- function withGeneratedCoverImage(row) {
559
- const existing = row.display?.coverImage;
560
- /*
561
- * 🛑 A seed PLACEHOLDER tile does not count as hand-authored.
562
- *
563
- * The rule is still "a hand-authored cover wins", but a `seedPhoto(...)`
564
- * tile was never authored — it is what the seed emits when it has nothing
565
- * better. Treating it as a decision is what made the placeholder BLOCK every
566
- * fetched wordmark: a logo could be downloaded, uploaded to Storage, mapped,
567
- * and the card would still show a grey tile, with nothing anywhere
568
- * reporting why.
569
- *
570
- * So the precedence is: real authored path > generated image > placeholder
571
- * tile. That lets every branch row keep an honest tile in source — which is
572
- * what it falls back to when no image exists, and is much better than the
573
- * empty grey box a brand row would otherwise render, since brand rows carry
574
- * no `color` and no `icon` either.
575
- */
576
- if (typeof existing === "string" && existing.trim().length > 0 && !isSeedPlaceholderImage(existing)) {
577
- return row;
578
- }
579
- const generated = row.id ? GENERATED_CATEGORY_IMAGES[row.id] : undefined;
580
- if (!generated)
581
- return row;
582
- return { ...row, display: { ...(row.display ?? {}), coverImage: generated } };
583
- }
584
- /**
585
- * Attach the REGIONAL-VARIANT logo to a row that names a Hasbro equivalent.
586
- *
587
- * 🛑 Gated on `hasbroName`, not merely on the map having an entry. The image is
588
- * rendered beside the "Also known as" line, so without the name there is
589
- * nothing to label it and a bare second logo reads as a duplicate of the
590
- * cover. The name is the fact; the image only illustrates it.
591
- *
592
- * Same hand-authored-wins rule as the cover, for the same reason: the admin
593
- * editor can set `hasbroCoverImage` on a row the generator knows nothing
594
- * about, and a reseed must not take that away.
595
- */
596
- function withGeneratedHasbroCover(row) {
597
- if (!row.hasbroName)
598
- return row;
599
- const existing = row.hasbroCoverImage;
600
- if (typeof existing === "string" && existing.trim().length > 0)
601
- return row;
602
- const generated = row.id ? GENERATED_CATEGORY_HASBRO_IMAGES[row.id] : undefined;
603
- return generated ? { ...row, hasbroCoverImage: generated } : row;
604
- }
605
- const allCategoryRows = [
606
- ...rawCategories.map((c) => ({ ancestors: [], ...c, createdByType: "admin" })),
607
- ...sublistingRows.map((s) => ({ ancestors: [], ...s, createdByType: "admin" })),
608
- ...brandRows.map((b) => ({ ancestors: [], ...b, createdByType: "admin" })),
609
- ...franchiseRows.map((f) => ({ ancestors: [], ...f, createdByType: "admin" })),
610
- ...bundleRows.map((b) => ({ ancestors: [], ...withBundleMosaic(b) })),
611
- ]
612
- .map(withGeneratedContent)
613
- .map(withGeneratedCoverImage)
614
- .map(withGeneratedHasbroCover)
615
- .map(withCategorySearchTxt);
616
- /*
617
- * ── Assertions, at MODULE LOAD, so a silent drop is loud ─────────────────────
618
- *
619
- * 🛑 These exist because of a specific failure shape this file is exposed to:
620
- * `appkit-seed status` counts documents BY ID, so it cannot see content drift
621
- * at all, and `load` is a `set(…, {merge:true})` that never removes a field.
622
- * A generated map that silently emptied — `MODEL_LEAVES` keyed on a line id
623
- * the forest renamed, say — would produce a tree that builds, typechecks,
624
- * seeds without error, reports perfectly in sync, and is missing 216 pages.
625
- *
626
- * Throwing at import is the right severity: every consumer of this module
627
- * (the seed CLI, the tester fixtures, the audits) wants to fail before writing
628
- * rather than after.
629
- */
630
- /*
631
- * 🛑 TIER 4 IS NOW TWO GENERATED FAMILIES, not one.
632
- *
633
- * This assertion compared the tier-4 count against `MODEL_LEAF_COUNT` alone,
634
- * and it CAUGHT the part leaves the moment they landed — 968 against an
635
- * expected 216 — which is precisely the job it was written for. Widening it to
636
- * the sum is the fix; deleting it or loosening it to `>=` would retire the one
637
- * check that can see a generated map silently empty.
638
- *
639
- * Kept as an exact equality for the same reason: a `>=` would pass with
640
- * `PART_LEAVES` entirely gone.
641
- */
642
- /*
643
- * 🛑 DISTINCT IDS. This assertion did not exist, and its absence is what let 20
644
- * part leaves overwrite 20 model leaves in production.
645
- *
646
- * The whole failure was silent at every layer: the forest walked 1,138 nodes
647
- * with only 1,118 distinct ids, `appkit-seed load` is a `set(…, {merge:true})`
648
- * so the second row with an id quietly replaced the first, and the CLI reported
649
- * `created 1173, errors 0` while Firestore held 1,153 documents. A buyer opening
650
- * `/categories/category-galeon` got the attack ring instead of the bey.
651
- *
652
- * Counting rows is not counting documents, and this is the one check that can
653
- * tell the difference BEFORE anything is written.
654
- */
655
- /*
656
- * 🛑 THE GENERATED BODIES ACTUALLY LANDED ON ROWS.
657
- *
658
- * I7's corpus is a `Record<id, html>` keyed on category ids, and a key that no
659
- * longer matches a row is invisible everywhere: the map still exports 745
660
- * entries, the seed still loads 1,173 rows, `appkit-seed status` still reports
661
- * in sync, and every one of those category pages renders without a body. That
662
- * is the same failure shape as the 20 ids that overwrote each other below —
663
- * counting the SOURCE is not counting what reached a row.
664
- *
665
- * Tolerance rather than exact equality, for one real reason: a hand-authored
666
- * body legitimately wins over a generated one, so the number of rows carrying
667
- * a GENERATED body is `COUNT` minus however many nodes have been written by
668
- * hand since. A floor of 90% catches a key-space break (which drops it to ~0)
669
- * without failing on authored prose being added.
670
- */
671
- const generatedApplied = allCategoryRows.filter((c) => typeof c.id === "string" && GENERATED_CATEGORY_CONTENT[c.id] === c.contentBody).length;
672
- if (generatedApplied < Math.floor(GENERATED_CATEGORY_CONTENT_COUNT * 0.9)) {
673
- throw new Error(`category seed: only ${generatedApplied} of ${GENERATED_CATEGORY_CONTENT_COUNT} generated ` +
674
- `content bodies matched a row id. The corpus is keyed on category ids, so this means ` +
675
- `the key space has drifted — re-run scripts/gen-category-content.mjs against the ` +
676
- `current forest. Nothing would error at load time: the pages would simply have no body.`);
677
- }
678
- /*
679
- * The same assertion for the cover images, and the same reasoning: the map is
680
- * keyed on category ids, so a key that stops matching a row is invisible —
681
- * the map still exports its count, the seed still loads every row, and the
682
- * pages simply go back to having no image.
683
- *
684
- * The floor is 90% for the one legitimate reason a row can be missing: a
685
- * hand-authored `display.coverImage` wins, so the number of rows carrying a
686
- * GENERATED path is `COUNT` minus however many have been art-directed by hand.
687
- */
688
- const generatedImagesApplied = allCategoryRows.filter((c) => typeof c.id === "string" && GENERATED_CATEGORY_IMAGES[c.id] === c.display?.coverImage).length;
689
- if (generatedImagesApplied < Math.floor(GENERATED_CATEGORY_IMAGE_COUNT * 0.9)) {
690
- throw new Error(`category seed: only ${generatedImagesApplied} of ${GENERATED_CATEGORY_IMAGE_COUNT} generated ` +
691
- `cover images matched a row id — the key space has drifted. Re-run ` +
692
- `scripts/fetch-taxonomy-images.mjs against the current forest. Nothing would error ` +
693
- `at load time: the category grids would just go back to blank cards.`);
694
- }
695
- /*
696
- * The regional-variant logos. This catches ORPHANED logos, and deliberately
697
- * only those.
698
- *
699
- * 🛑 The two directions are NOT symmetric, which a first draft of this comment
700
- * got wrong until a negative control was actually run against it:
701
- *
702
- * - **A map entry whose row does not name a Hasbro wave is an ERROR.**
703
- * `withGeneratedHasbroCover` gates on `hasbroName`, so that image can
704
- * never render — it was fetched, uploaded to Storage and mapped, and is
705
- * now a stored object nothing will ever serve. Silent waste. Throw.
706
- *
707
- * - **A named wave with no logo is FINE.** The "Also known as" block renders
708
- * the name and omits the image (`CategoryDetailPageView` makes the picture
709
- * conditional), which is a correct, intentional-looking page. Setting a
710
- * name we can evidence while having no logo we can source is exactly the
711
- * honest-gap rule the rest of this work follows, so failing the seed for
712
- * it would punish the right behaviour.
713
- *
714
- * Hence `covered !== keys` and NOT `covered !== named`. Exact equality rather
715
- * than a 90% floor because there are five, hand-set against five confirmed
716
- * pairings: "most of them" is not a meaningful tolerance at that size.
717
- */
718
- const hasbroNamed = allCategoryRows.filter((c) => typeof c.hasbroName === "string" && c.hasbroName);
719
- const hasbroCovered = hasbroNamed.filter((c) => typeof c.id === "string" && GENERATED_CATEGORY_HASBRO_IMAGES[c.id] === c.hasbroCoverImage);
720
- const hasbroMapKeys = Object.keys(GENERATED_CATEGORY_HASBRO_IMAGES);
721
- if (hasbroCovered.length !== hasbroMapKeys.length) {
722
- const namedIds = new Set(hasbroNamed.map((c) => c.id));
723
- const orphanLogos = hasbroMapKeys.filter((k) => !namedIds.has(k));
724
- throw new Error(`category seed: ${hasbroCovered.length} of ${hasbroMapKeys.length} regional-variant logos ` +
725
- `reached a row that names one. ` +
726
- (orphanLogos.length > 0
727
- ? `These have a logo but no hasbroName: ${orphanLogos.join(", ")}. `
728
- : "") +
729
- `Either set hasbroName in category-forest.ts, or drop the entry from the manifest and ` +
730
- `re-run scripts/fetch-category-images.mjs. Nothing would error at load time — the ` +
731
- `"Also known as" block would just render without its logo.`);
732
- }
733
- const allIds = allCategoryRows.map((c) => c.id).filter((x) => typeof x === "string");
734
- const duplicateIds = [...new Set(allIds.filter((id, i) => allIds.indexOf(id) !== i))];
735
- if (duplicateIds.length > 0) {
736
- throw new Error(`category seed: ${duplicateIds.length} duplicate id(s) — a merge write would ` +
737
- `silently overwrite, so the load would report success and lose rows. ` +
738
- `First few: ${duplicateIds.slice(0, 8).join(", ")}`);
739
- }
740
- if (allIds.length !== allCategoryRows.length) {
741
- throw new Error(`category seed: ${allCategoryRows.length - allIds.length} row(s) have no string id`);
742
- }
743
- const tier4Rows = rawCategories.filter((c) => c.tier === 4).length;
744
- const expectedTier4 = MODEL_LEAF_COUNT + PART_LEAF_COUNT;
745
- if (tier4Rows !== expectedTier4) {
746
- /*
747
- * 🛑 NAME THE DROPPED LEAVES. A count told us 2,626 of 2,711 arrived and
748
- * nothing more, which is unactionable: the ids are all distinct and every
749
- * parent key exists in the forest, so the difference is in WHICH parent each
750
- * leaf hangs off and at what depth — and that is only visible per leaf.
751
- *
752
- * The expensive version of this was a session spent inferring the cause from
753
- * indentation in the forest literal. The cheap version is the set
754
- * difference, grouped by the parent that owns each missing leaf, which also
755
- * says the tier it actually landed at. One run names the fix.
756
- */
757
- const reached = new Set(rawCategories.filter((c) => c.tier === 4).map((c) => String(c.id)));
758
- const tierOf = new Map(rawCategories.map((c) => [String(c.id), c.tier]));
759
- const declared = [];
760
- for (const [parent, leaves] of Object.entries(MODEL_LEAVES)) {
761
- for (const leaf of leaves)
762
- declared.push({ id: leaf.id, parent });
763
- }
764
- for (const [parent, leaves] of Object.entries(PART_LEAVES)) {
765
- for (const leaf of leaves)
766
- declared.push({ id: leaf.id, parent });
767
- }
768
- const missing = declared.filter((d) => !reached.has(d.id));
769
- const byParent = new Map();
770
- for (const m of missing) {
771
- if (!byParent.has(m.parent)) {
772
- byParent.set(m.parent, { n: 0, landedAt: new Set(), sample: [] });
773
- }
774
- const g = byParent.get(m.parent);
775
- g.n += 1;
776
- g.landedAt.add(tierOf.has(m.id) ? `tier ${tierOf.get(m.id)}` : "absent");
777
- if (g.sample.length < 3)
778
- g.sample.push(m.id);
779
- }
780
- const detail = [...byParent.entries()]
781
- .sort((a, b) => b[1].n - a[1].n)
782
- .map(([parent, g]) => ` ${parent}: ${g.n} leaf/leaves landed at ${[...g.landedAt].join("+")} ` +
783
- `(e.g. ${g.sample.join(", ")})`)
784
- .join("\n");
785
- throw new Error(`category seed: ${tier4Rows} tier-4 leaves reached the tree but the generated ` +
786
- `maps declare ${expectedTier4} (${MODEL_LEAF_COUNT} models + ${PART_LEAF_COUNT} parts).\n` +
787
- ` ${missing.length} declared leaf/leaves did not arrive as tier 4, by parent:\n` +
788
- `${detail}\n` +
789
- ` A parent at the wrong DEPTH puts its leaves at the wrong tier (a leaf is ` +
790
- `always parentDepth+1); a parent id the forest renamed makes them absent ` +
791
- `entirely. Fix the forest, then re-run node scripts/gen-category-models.mjs ` +
792
- `and node scripts/gen-category-parts.mjs.`);
793
- }
794
- if (brandRows.length !== BRAND_ROW_COUNT) {
795
- throw new Error(`category seed: ${brandRows.length} brand rows built, expected ${BRAND_ROW_COUNT}`);
796
- }
797
- if (franchiseRows.length !== FRANCHISE_ROW_COUNT) {
798
- throw new Error(`category seed: ${franchiseRows.length} franchise rows built, expected ${FRANCHISE_ROW_COUNT}`);
799
- }
800
- {
801
- /*
802
- * A price band keyed on a leaf that does not exist is dead weight that READS
803
- * AS COVERAGE — the hint renders nowhere and nothing says so. Cheap to
804
- * check, and it is the most likely thing to rot as the tree is edited.
805
- */
806
- const ids = new Set(rawCategories.map((c) => c.id));
807
- const orphans = MARKET_BAND_LEAF_IDS.filter((id) => !ids.has(id));
808
- if (orphans.length) {
809
- throw new Error(`category seed: ${orphans.length} market band(s) key a non-existent ` +
810
- `leaf: ${orphans.join(", ")}`);
811
- }
812
- }
813
- export const categoriesSeedData = allCategoryRows;
814
- // P-1 default seed: identical to categoriesSeedData (bundle rows included — P-17
815
- // re-added them 2026-08-15 after the earlier removal referenced below).
816
- export const categoriesP1SeedData = allCategoryRows;