@mohasinac/appkit 4.11.1 → 4.11.3

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 (212) hide show
  1. package/dist/_internal/server/features/checkout/actions.d.ts +4 -0
  2. package/dist/_internal/server/features/checkout/actions.js +138 -27
  3. package/dist/_internal/server/features/checkout/data.d.ts +10 -0
  4. package/dist/_internal/server/features/checkout/locked-lines.d.ts +30 -0
  5. package/dist/_internal/server/features/checkout/locked-lines.js +116 -0
  6. package/dist/_internal/server/features/orders/adapters.js +7 -0
  7. package/dist/_internal/server/features/products/data.d.ts +12 -3
  8. package/dist/_internal/server/features/products/data.js +55 -4
  9. package/dist/_internal/server/features/products/index.d.ts +2 -1
  10. package/dist/_internal/server/features/products/index.js +2 -1
  11. package/dist/_internal/server/features/products/list-public.d.ts +130 -0
  12. package/dist/_internal/server/features/products/list-public.js +375 -0
  13. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  14. package/dist/_internal/server/features/reviews/data.js +3 -2
  15. package/dist/_internal/server/features/tester/visibility.js +3 -3
  16. package/dist/_internal/server/jobs/core/auctionSettlement.js +89 -16
  17. package/dist/_internal/server/jobs/core/offerExpiry.js +116 -4
  18. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -1
  19. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
  20. package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +2 -0
  21. package/dist/_internal/server/jobs/handlers/_helpers.js +4 -1
  22. package/dist/_internal/server/jobs/handlers/messages.d.ts +5 -0
  23. package/dist/_internal/server/jobs/handlers/messages.js +5 -0
  24. package/dist/_internal/shared/checkout/lanes.d.ts +41 -0
  25. package/dist/_internal/shared/checkout/lanes.js +106 -0
  26. package/dist/_internal/shared/checkout/order-math.d.ts +19 -0
  27. package/dist/_internal/shared/checkout/order-math.js +30 -6
  28. package/dist/_internal/shared/features/promotions/schema.d.ts +0 -16
  29. package/dist/_internal/shared/features/promotions/schema.js +0 -2
  30. package/dist/_internal/shared/features/reviews/config.d.ts +8 -1
  31. package/dist/_internal/shared/features/reviews/config.js +8 -1
  32. package/dist/_internal/shared/listing-types/_registry.d.ts +88 -1
  33. package/dist/_internal/shared/listing-types/_registry.js +63 -1
  34. package/dist/_internal/shared/listing-types/art/config.d.ts +59 -0
  35. package/dist/_internal/shared/listing-types/art/config.js +12 -0
  36. package/dist/_internal/shared/listing-types/auction/config.d.ts +53 -0
  37. package/dist/_internal/shared/listing-types/auction/config.js +17 -0
  38. package/dist/_internal/shared/listing-types/classified/config.d.ts +59 -0
  39. package/dist/_internal/shared/listing-types/classified/config.js +14 -0
  40. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +59 -0
  41. package/dist/_internal/shared/listing-types/digital-code/config.js +12 -0
  42. package/dist/_internal/shared/listing-types/feature-flags.d.ts +1 -0
  43. package/dist/_internal/shared/listing-types/feature-flags.js +24 -10
  44. package/dist/_internal/shared/listing-types/live/config.d.ts +59 -0
  45. package/dist/_internal/shared/listing-types/live/config.js +14 -0
  46. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +110 -0
  47. package/dist/_internal/shared/listing-types/pre-order/config.js +14 -0
  48. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +44 -0
  49. package/dist/_internal/shared/listing-types/prize-draw/config.js +10 -0
  50. package/dist/_internal/shared/listing-types/standard/config.d.ts +59 -0
  51. package/dist/_internal/shared/listing-types/standard/config.js +9 -0
  52. package/dist/_internal/shared/listing-types/stickers/config.d.ts +59 -0
  53. package/dist/_internal/shared/listing-types/stickers/config.js +12 -0
  54. package/dist/client.d.ts +7 -2
  55. package/dist/client.js +8 -2
  56. package/dist/constants/field-names.d.ts +12 -0
  57. package/dist/constants/field-names.js +12 -0
  58. package/dist/constants/table-keys.d.ts +2 -0
  59. package/dist/constants/table-keys.js +2 -0
  60. package/dist/features/account/components/NotificationBell.js +1 -0
  61. package/dist/features/account/components/UserOffersPanel.js +8 -1
  62. package/dist/features/account/components/UserOrdersView.js +27 -5
  63. package/dist/features/admin/actions/notification-actions.js +1 -1
  64. package/dist/features/admin/components/AdminAddressesView.js +3 -1
  65. package/dist/features/admin/components/AdminCouponEditorView.js +1 -4
  66. package/dist/features/admin/components/AdminPaymentMethodsView.js +3 -1
  67. package/dist/features/admin/components/AdminProductsView.js +34 -18
  68. package/dist/features/admin/constants/filter-tabs.d.ts +26 -9
  69. package/dist/features/admin/constants/filter-tabs.js +22 -9
  70. package/dist/features/admin/schemas/firestore.d.ts +2 -1
  71. package/dist/features/admin/schemas/firestore.js +1 -0
  72. package/dist/features/auctions/actions/bid-actions.d.ts +11 -1
  73. package/dist/features/auctions/actions/bid-actions.js +29 -15
  74. package/dist/features/auctions/components/AuctionBidsTable.js +6 -2
  75. package/dist/features/auctions/components/AuctionBottomActions.js +1 -0
  76. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -11
  77. package/dist/features/auctions/components/AuctionsListView.js +12 -53
  78. package/dist/features/auctions/components/PlaceBidFormClient.js +10 -1
  79. package/dist/features/auctions/repository/bid.repository.d.ts +15 -0
  80. package/dist/features/auctions/repository/bid.repository.js +19 -0
  81. package/dist/features/auctions/schemas/firestore.d.ts +11 -1
  82. package/dist/features/auctions/schemas/firestore.js +1 -0
  83. package/dist/features/cart/actions/cart-actions.d.ts +11 -0
  84. package/dist/features/cart/actions/cart-actions.js +24 -0
  85. package/dist/features/cart/repository/cart.repository.d.ts +24 -1
  86. package/dist/features/cart/repository/cart.repository.js +71 -6
  87. package/dist/features/cart/schemas/firestore.d.ts +23 -4
  88. package/dist/features/categories/components/BrandDetailTabs.js +31 -11
  89. package/dist/features/categories/components/CategoryDetailTabs.js +27 -7
  90. package/dist/features/categories/components/CategoryProductsListing.d.ts +9 -1
  91. package/dist/features/categories/components/CategoryProductsListing.js +5 -2
  92. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  93. package/dist/features/contact/email.js +56 -1
  94. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +17 -16
  95. package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
  96. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  97. package/dist/features/homepage/components/ShopByCategorySection.js +1 -1
  98. package/dist/features/layout/AppLayoutShell.js +9 -2
  99. package/dist/features/layout/BottomActions.js +26 -3
  100. package/dist/features/layout/BottomActionsContext.d.ts +14 -0
  101. package/dist/features/layout/BottomActionsContext.js +13 -1
  102. package/dist/features/layout/hooks/useBottomActions.d.ts +6 -1
  103. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  104. package/dist/features/layout/index.d.ts +1 -1
  105. package/dist/features/live/components/LiveItemDetailPageView.js +7 -6
  106. package/dist/features/orders/repository/orders.repository.d.ts +4 -15
  107. package/dist/features/orders/repository/orders.repository.js +4 -27
  108. package/dist/features/orders/types/index.d.ts +16 -0
  109. package/dist/features/orders/utils/order-splitter.js +14 -2
  110. package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +1 -1
  111. package/dist/features/pre-orders/components/PreOrderBottomActions.js +3 -19
  112. package/dist/features/pre-orders/components/PreOrdersListView.js +11 -39
  113. package/dist/features/products/components/ArtStickersListView.js +10 -49
  114. package/dist/features/products/components/AuctionsIndexListing.js +1 -2
  115. package/dist/features/products/components/ListingBottomActions.d.ts +28 -0
  116. package/dist/features/products/components/ListingBottomActions.js +25 -0
  117. package/dist/features/products/components/PrizeDrawBottomActions.d.ts +1 -1
  118. package/dist/features/products/components/PrizeDrawBottomActions.js +3 -21
  119. package/dist/features/products/components/ProductDetailActions.js +4 -0
  120. package/dist/features/products/components/ProductDetailPageView.js +7 -7
  121. package/dist/features/products/components/ProductsIndexPageView.js +9 -62
  122. package/dist/features/products/constants/listing-tabs.d.ts +43 -198
  123. package/dist/features/products/constants/listing-tabs.js +71 -58
  124. package/dist/features/products/constants/sieve.d.ts +104 -1
  125. package/dist/features/products/constants/sieve.js +27 -7
  126. package/dist/features/products/repository/products.repository.d.ts +45 -1
  127. package/dist/features/products/repository/products.repository.js +67 -8
  128. package/dist/features/products/utils/listing-badge-variant.d.ts +20 -1
  129. package/dist/features/products/utils/listing-badge-variant.js +26 -1
  130. package/dist/features/products/utils/listing-type.d.ts +24 -0
  131. package/dist/features/products/utils/listing-type.js +48 -0
  132. package/dist/features/promotions/actions/coupon-actions.d.ts +7 -0
  133. package/dist/features/promotions/actions/coupon-actions.js +12 -1
  134. package/dist/features/promotions/actions/coupon-stacking.d.ts +24 -0
  135. package/dist/features/promotions/actions/coupon-stacking.js +21 -0
  136. package/dist/features/promotions/actions/index.d.ts +1 -0
  137. package/dist/features/promotions/actions/index.js +1 -0
  138. package/dist/features/promotions/actions/seller-coupon-actions.d.ts +0 -1
  139. package/dist/features/promotions/actions/seller-coupon-actions.js +0 -1
  140. package/dist/features/promotions/components/CouponHelpDetails.d.ts +20 -0
  141. package/dist/features/promotions/components/CouponHelpDetails.js +17 -0
  142. package/dist/features/promotions/components/CouponsIndexListing.js +2 -1
  143. package/dist/features/promotions/components/index.d.ts +2 -0
  144. package/dist/features/promotions/components/index.js +1 -0
  145. package/dist/features/promotions/constants/coupon-help.d.ts +27 -0
  146. package/dist/features/promotions/constants/coupon-help.js +42 -0
  147. package/dist/features/promotions/repository/coupons.repository.d.ts +10 -1
  148. package/dist/features/promotions/repository/coupons.repository.js +22 -8
  149. package/dist/features/promotions/schemas/firestore.d.ts +0 -1
  150. package/dist/features/promotions/schemas/firestore.js +1 -1
  151. package/dist/features/promotions/schemas/index.d.ts +0 -20
  152. package/dist/features/promotions/schemas/index.js +0 -1
  153. package/dist/features/reviews/actions/review-actions.js +5 -1
  154. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -1
  155. package/dist/features/reviews/components/ReviewFilters.d.ts +7 -1
  156. package/dist/features/reviews/components/ReviewFilters.js +4 -3
  157. package/dist/features/reviews/components/ReviewsIndexListing.d.ts +6 -0
  158. package/dist/features/reviews/components/ReviewsIndexListing.js +9 -109
  159. package/dist/features/reviews/components/ReviewsListingPanel.d.ts +41 -0
  160. package/dist/features/reviews/components/ReviewsListingPanel.js +226 -0
  161. package/dist/features/reviews/components/index.d.ts +2 -0
  162. package/dist/features/reviews/components/index.js +1 -0
  163. package/dist/features/reviews/hooks/useReviews.d.ts +8 -0
  164. package/dist/features/reviews/hooks/useReviews.js +14 -6
  165. package/dist/features/reviews/repository/reviews.repository.d.ts +29 -1
  166. package/dist/features/reviews/repository/reviews.repository.js +77 -41
  167. package/dist/features/reviews/types/index.d.ts +8 -1
  168. package/dist/features/seller/actions/offer-actions.d.ts +6 -0
  169. package/dist/features/seller/actions/offer-actions.js +8 -9
  170. package/dist/features/seller/components/SellerOffersView.d.ts +6 -1
  171. package/dist/features/seller/components/SellerOffersView.js +59 -8
  172. package/dist/features/seller/components/SellerProductsCards.js +2 -2
  173. package/dist/features/seller/components/SellerProductsView.js +21 -18
  174. package/dist/features/seller/repository/offer.repository.d.ts +18 -2
  175. package/dist/features/seller/repository/offer.repository.js +38 -2
  176. package/dist/features/seller/schemas/firestore.d.ts +7 -2
  177. package/dist/features/seller/schemas/firestore.js +3 -0
  178. package/dist/features/seller/schemas/offer-forms.d.ts +12 -0
  179. package/dist/features/seller/schemas/offer-forms.js +28 -0
  180. package/dist/features/stores/actions/store-query-actions.js +1 -1
  181. package/dist/features/stores/components/StoreAuctionsListing.js +5 -11
  182. package/dist/features/stores/components/StorePreOrdersListing.js +6 -11
  183. package/dist/features/stores/components/StoreReviewsListing.d.ts +4 -0
  184. package/dist/features/stores/components/StoreReviewsListing.js +7 -108
  185. package/dist/features/stores/schemas/index.d.ts +2 -2
  186. package/dist/features/tester/seed-data/coupons-tester-seed-data.js +3 -3
  187. package/dist/features/tester/seed-data/index.d.ts +1 -0
  188. package/dist/features/tester/seed-data/index.js +1 -0
  189. package/dist/features/tester/seed-data/offers-tester-seed-data.d.ts +2 -0
  190. package/dist/features/tester/seed-data/offers-tester-seed-data.js +61 -0
  191. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +337 -1
  192. package/dist/index.d.ts +11 -4
  193. package/dist/index.js +15 -3
  194. package/dist/react/hooks/useListingTypeFlags.d.ts +12 -19
  195. package/dist/react/hooks/useListingTypeFlags.js +4 -9
  196. package/dist/schemas/registry.d.ts +0 -12
  197. package/dist/seed/claimed-coupons-seed-data.js +3 -3
  198. package/dist/seed/coupons-seed-data.js +29 -10
  199. package/dist/seed/faq-seed-data.js +2 -2
  200. package/dist/seed/manifest.js +2 -2
  201. package/dist/server-entry.d.ts +1 -0
  202. package/dist/server-entry.js +1 -0
  203. package/dist/server.d.ts +1 -0
  204. package/dist/server.js +3 -0
  205. package/dist/styles.css +44 -39
  206. package/dist/tailwind-utilities.css +1 -1
  207. package/dist/ui/components/FilterChipGroup.d.ts +21 -3
  208. package/dist/ui/components/FilterChipGroup.js +33 -4
  209. package/dist/ui/components/HorizontalScroller.d.ts +1 -2
  210. package/dist/ui/components/HorizontalScroller.js +9 -5
  211. package/dist/ui/components/HorizontalScroller.style.css +43 -38
  212. package/package.json +1 -1
@@ -6,16 +6,20 @@
6
6
  * filter on the `products` collection or to a separate collection
7
7
  * (currently only `bundles`).
8
8
  *
9
- * Add new tab variants here never inline the tab list inside the view.
9
+ * DERIVED, NOT HAND-WRITTEN (2026-08-21). Every array below is built from
10
+ * `ALL_LISTING_TYPES` + the listing-type plugin registry, so a new listing
11
+ * type appears on every tab bar automatically. They used to be nine separate
12
+ * hand-maintained literals and had drifted badly: `/products` offered only 4
13
+ * of 9 types (missing auctions, pre-orders, prize draws, art, stickers — the
14
+ * bug that started this sweep), the admin type chips used display LABELS as
15
+ * Sieve filter ids, and several arrays still listed `bundle`, which stopped
16
+ * being a listingType in SB-UNI-D. `scripts/audit-listing-type-tab-coverage.mjs`
17
+ * blocks any regression.
18
+ *
19
+ * To add a tab that ISN'T a listing type (bundles, stores), append it to the
20
+ * relevant array explicitly — those are genuinely different collections.
10
21
  */
11
22
  import type { ListingType } from "../types";
12
- /**
13
- * The consolidated generic `/products` browse tab covers these 4 listing
14
- * types (auctions/pre-orders/bundles/prize-draws/art+stickers each have
15
- * their own dedicated public page). Shared between the server-rendered
16
- * page view and the client listing component so they can't drift apart.
17
- */
18
- export declare const GENERIC_PRODUCT_LISTING_TYPES: readonly ["standard", "classified", "digital-code", "live"];
19
23
  export interface ListingTab {
20
24
  id: string;
21
25
  label: string;
@@ -28,197 +32,38 @@ export interface ListingTab {
28
32
  /** Set when the tab queries a non-product entity (e.g. `stores`). */
29
33
  entity?: "stores";
30
34
  }
35
+ /**
36
+ * The generic `/products` browse page spans EVERY listing type (2026-08-21).
37
+ *
38
+ * It used to span only `standard|classified|digital-code|live` on the theory
39
+ * that auctions/pre-orders/prize-draws/art each had a dedicated page — but
40
+ * that made five of nine types unreachable from the main catalogue, broke
41
+ * seven legacy `/search/.../tab/<type>` permanent redirects that all point at
42
+ * `/products`, and made the cross-type Compare + bulk-cart features (which
43
+ * only exist on this page) unusable for those types. The dedicated pages
44
+ * remain, and `/products` links to them when a single time-boxed type is
45
+ * selected.
46
+ */
47
+ export declare const GENERIC_PRODUCT_LISTING_TYPES: readonly ListingType[];
48
+ /** The listing types the combined `/art` page spans. */
49
+ export declare const ART_STICKERS_LISTING_TYPES: readonly ListingType[];
31
50
  /** Tabs shown on `/categories/[slug]` and `/brands/[slug]` detail pages. */
32
- export declare const CATEGORY_PAGE_TABS: readonly [{
33
- readonly id: "products";
34
- readonly label: "Products";
35
- readonly listingType: "standard";
36
- }, {
37
- readonly id: "auctions";
38
- readonly label: "Auctions";
39
- readonly listingType: "auction";
40
- }, {
41
- readonly id: "pre-orders";
42
- readonly label: "Pre-Orders";
43
- readonly listingType: "pre-order";
44
- }, {
45
- readonly id: "prize-draws";
46
- readonly label: "Prize Draws";
47
- readonly listingType: "prize-draw";
48
- }, {
49
- readonly id: "bundles";
50
- readonly label: "Bundles";
51
- readonly collection: "bundles";
52
- }, {
53
- readonly id: "classifieds";
54
- readonly label: "Classifieds";
55
- readonly listingType: "classified";
56
- }, {
57
- readonly id: "digital-codes";
58
- readonly label: "Digital Codes";
59
- readonly listingType: "digital-code";
60
- }, {
61
- readonly id: "live";
62
- readonly label: "Live Items";
63
- readonly listingType: "live";
64
- }, {
65
- readonly id: "art";
66
- readonly label: "Art & Stickers";
67
- readonly listingType: "art|stickers";
68
- }, {
69
- readonly id: "stores";
70
- readonly label: "Stores";
71
- readonly entity: "stores";
72
- }];
73
- export type CategoryTabId = (typeof CATEGORY_PAGE_TABS)[number]["id"];
51
+ export declare const CATEGORY_PAGE_TABS: readonly ListingTab[];
52
+ export type CategoryTabId = string;
74
53
  /** Tabs shown on the public `/stores/[slug]` nav bar. */
75
- export declare const STORE_PAGE_TABS: readonly [{
76
- readonly id: "products";
77
- readonly label: "Products";
78
- readonly listingType: "standard";
79
- }, {
80
- readonly id: "auctions";
81
- readonly label: "Auctions";
82
- readonly listingType: "auction";
83
- }, {
84
- readonly id: "pre-orders";
85
- readonly label: "Pre-Orders";
86
- readonly listingType: "pre-order";
87
- }, {
88
- readonly id: "prize-draws";
89
- readonly label: "Prize Draws";
90
- readonly listingType: "prize-draw";
91
- }, {
92
- readonly id: "bundles";
93
- readonly label: "Bundles";
94
- readonly collection: "bundles";
95
- }, {
96
- readonly id: "classifieds";
97
- readonly label: "Classifieds";
98
- readonly listingType: "classified";
99
- }, {
100
- readonly id: "digital-codes";
101
- readonly label: "Digital Codes";
102
- readonly listingType: "digital-code";
103
- }, {
104
- readonly id: "live";
105
- readonly label: "Live Items";
106
- readonly listingType: "live";
107
- }, {
108
- readonly id: "art";
109
- readonly label: "Art & Stickers";
110
- readonly listingType: "art|stickers";
111
- }];
112
- export type StoreTabId = (typeof STORE_PAGE_TABS)[number]["id"];
54
+ export declare const STORE_PAGE_TABS: readonly ListingTab[];
55
+ export type StoreTabId = string;
113
56
  /** Tabs shown on the seller-dashboard listings view + admin products list. */
114
- export declare const SELLER_LISTING_TABS: readonly [{
115
- readonly id: "all";
116
- readonly label: "All";
117
- }, {
118
- readonly id: "products";
119
- readonly label: "Products";
120
- readonly listingType: "standard";
121
- }, {
122
- readonly id: "auctions";
123
- readonly label: "Auctions";
124
- readonly listingType: "auction";
125
- }, {
126
- readonly id: "pre-orders";
127
- readonly label: "Pre-Orders";
128
- readonly listingType: "pre-order";
129
- }, {
130
- readonly id: "prize-draws";
131
- readonly label: "Prize Draws";
132
- readonly listingType: "prize-draw";
133
- }, {
134
- readonly id: "classifieds";
135
- readonly label: "Classifieds";
136
- readonly listingType: "classified";
137
- }, {
138
- readonly id: "digital-codes";
139
- readonly label: "Digital Codes";
140
- readonly listingType: "digital-code";
141
- }, {
142
- readonly id: "live";
143
- readonly label: "Live Items";
144
- readonly listingType: "live";
145
- }, {
146
- readonly id: "art";
147
- readonly label: "Art";
148
- readonly listingType: "art";
149
- }, {
150
- readonly id: "stickers";
151
- readonly label: "Stickers";
152
- readonly listingType: "stickers";
153
- }];
154
- export type SellerListingTabId = (typeof SELLER_LISTING_TABS)[number]["id"];
155
- /** Tabs shown on `/search` results. */
156
- export declare const SEARCH_RESULT_TABS: readonly [{
157
- readonly id: "all";
158
- readonly label: "All";
159
- }, {
160
- readonly id: "products";
161
- readonly label: "Products";
162
- readonly listingType: "standard";
163
- }, {
164
- readonly id: "auctions";
165
- readonly label: "Auctions";
166
- readonly listingType: "auction";
167
- }, {
168
- readonly id: "pre-orders";
169
- readonly label: "Pre-Orders";
170
- readonly listingType: "pre-order";
171
- }, {
172
- readonly id: "prize-draws";
173
- readonly label: "Prize Draws";
174
- readonly listingType: "prize-draw";
175
- }, {
176
- readonly id: "bundles";
177
- readonly label: "Bundles";
178
- readonly collection: "bundles";
179
- }, {
180
- readonly id: "classifieds";
181
- readonly label: "Classifieds";
182
- readonly listingType: "classified";
183
- }, {
184
- readonly id: "digital-codes";
185
- readonly label: "Digital Codes";
186
- readonly listingType: "digital-code";
187
- }, {
188
- readonly id: "live";
189
- readonly label: "Live Items";
190
- readonly listingType: "live";
191
- }, {
192
- readonly id: "art";
193
- readonly label: "Art & Stickers";
194
- readonly listingType: "art|stickers";
195
- }];
196
- export type SearchTabId = (typeof SEARCH_RESULT_TABS)[number]["id"];
197
- /** In-page type-filter chips on the generic `/products` browse page. */
198
- export declare const PRODUCT_TYPE_FILTER_TABS: readonly [{
199
- readonly id: "All";
200
- readonly label: "All";
201
- }, {
202
- readonly id: "standard";
203
- readonly label: "Standard";
204
- }, {
205
- readonly id: "classified";
206
- readonly label: "Classified";
207
- }, {
208
- readonly id: "digital-code";
209
- readonly label: "Digital Codes";
210
- }, {
211
- readonly id: "live";
212
- readonly label: "Live Items";
213
- }];
57
+ export declare const SELLER_LISTING_TABS: readonly ListingTab[];
58
+ export type SellerListingTabId = string;
59
+ /**
60
+ * In-page type-filter chips on the generic `/products` browse page.
61
+ *
62
+ * Multi-select (checkbox semantics) — no "All" sentinel chip, because "none
63
+ * checked" already means "every type". A sentinel would be a second way to
64
+ * express the same state and would have to be cleared whenever a real chip
65
+ * was ticked.
66
+ */
67
+ export declare const PRODUCT_TYPE_FILTER_TABS: readonly ListingTab[];
214
68
  /** In-page type-filter chips on the combined `/art` (Art & Stickers) page. */
215
- export declare const ART_STICKERS_TYPE_FILTER_TABS: readonly [{
216
- readonly id: "All";
217
- readonly label: "All";
218
- }, {
219
- readonly id: "art";
220
- readonly label: "Art";
221
- }, {
222
- readonly id: "stickers";
223
- readonly label: "Stickers";
224
- }];
69
+ export declare const ART_STICKERS_TYPE_FILTER_TABS: readonly ListingTab[];
@@ -6,78 +6,91 @@
6
6
  * filter on the `products` collection or to a separate collection
7
7
  * (currently only `bundles`).
8
8
  *
9
- * Add new tab variants here never inline the tab list inside the view.
9
+ * DERIVED, NOT HAND-WRITTEN (2026-08-21). Every array below is built from
10
+ * `ALL_LISTING_TYPES` + the listing-type plugin registry, so a new listing
11
+ * type appears on every tab bar automatically. They used to be nine separate
12
+ * hand-maintained literals and had drifted badly: `/products` offered only 4
13
+ * of 9 types (missing auctions, pre-orders, prize draws, art, stickers — the
14
+ * bug that started this sweep), the admin type chips used display LABELS as
15
+ * Sieve filter ids, and several arrays still listed `bundle`, which stopped
16
+ * being a listingType in SB-UNI-D. `scripts/audit-listing-type-tab-coverage.mjs`
17
+ * blocks any regression.
18
+ *
19
+ * To add a tab that ISN'T a listing type (bundles, stores), append it to the
20
+ * relevant array explicitly — those are genuinely different collections.
21
+ */
22
+ import { ALL_LISTING_TYPES } from "../../../_internal/shared/listing-types/feature-flags";
23
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
24
+ /**
25
+ * The generic `/products` browse page spans EVERY listing type (2026-08-21).
26
+ *
27
+ * It used to span only `standard|classified|digital-code|live` on the theory
28
+ * that auctions/pre-orders/prize-draws/art each had a dedicated page — but
29
+ * that made five of nine types unreachable from the main catalogue, broke
30
+ * seven legacy `/search/.../tab/<type>` permanent redirects that all point at
31
+ * `/products`, and made the cross-type Compare + bulk-cart features (which
32
+ * only exist on this page) unusable for those types. The dedicated pages
33
+ * remain, and `/products` links to them when a single time-boxed type is
34
+ * selected.
35
+ */
36
+ export const GENERIC_PRODUCT_LISTING_TYPES = ALL_LISTING_TYPES;
37
+ /** The listing types the combined `/art` page spans. */
38
+ export const ART_STICKERS_LISTING_TYPES = ["art", "stickers"];
39
+ /**
40
+ * A FILTER chip — `id` is the canonical `listingType`, because it is passed
41
+ * straight into `sieveFilter("listingType", EQ, id)`. Never a display label.
42
+ */
43
+ function chipTab(type) {
44
+ return { id: type, label: pluginFor(type).chipLabel, listingType: type };
45
+ }
46
+ /**
47
+ * A ROUTE-BACKED tab — `id` is the plugin's `tabSlug`, because it doubles as
48
+ * the URL segment (`/stores/{slug}/pre-orders`) and is live in bookmarks.
49
+ * The canonical type still rides along in `listingType` for the query.
10
50
  */
51
+ function pluralTab(type) {
52
+ const plugin = pluginFor(type);
53
+ return { id: plugin.tabSlug, label: plugin.pluralLabel, listingType: type };
54
+ }
11
55
  /**
12
- * The consolidated generic `/products` browse tab covers these 4 listing
13
- * types (auctions/pre-orders/bundles/prize-draws/art+stickers each have
14
- * their own dedicated public page). Shared between the server-rendered
15
- * page view and the client listing component so they can't drift apart.
56
+ * Art and stickers share the combined `/art` browse page, so category/brand/
57
+ * store tab bars show them as ONE tab backed by a two-value OR-group. Derived
58
+ * from both plugins rather than a hardcoded `"art|stickers"` string so the
59
+ * pipe-group can't drift from the registry.
16
60
  */
17
- export const GENERIC_PRODUCT_LISTING_TYPES = ["standard", "classified", "digital-code", "live"];
61
+ const ART_STICKERS_COMBINED_TAB = {
62
+ id: pluginFor("art").tabSlug,
63
+ label: `${pluginFor("art").pluralLabel} & ${pluginFor("stickers").pluralLabel}`,
64
+ listingType: ART_STICKERS_LISTING_TYPES.join("|"),
65
+ };
66
+ /** Listing types that get their own tab on a combined surface (art+stickers merge into one). */
67
+ const SEPARATELY_TABBED_TYPES = ALL_LISTING_TYPES.filter((t) => t !== "art" && t !== "stickers");
18
68
  /** Tabs shown on `/categories/[slug]` and `/brands/[slug]` detail pages. */
19
69
  export const CATEGORY_PAGE_TABS = [
20
- { id: "products", label: "Products", listingType: "standard" },
21
- { id: "auctions", label: "Auctions", listingType: "auction" },
22
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
23
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
70
+ ...SEPARATELY_TABBED_TYPES.map(pluralTab),
24
71
  { id: "bundles", label: "Bundles", collection: "bundles" },
25
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
26
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
27
- { id: "live", label: "Live Items", listingType: "live" },
28
- // Combined — one public browse page (`/art`) spans both listing types.
29
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
72
+ ART_STICKERS_COMBINED_TAB,
30
73
  { id: "stores", label: "Stores", entity: "stores" },
31
74
  ];
32
75
  /** Tabs shown on the public `/stores/[slug]` nav bar. */
33
76
  export const STORE_PAGE_TABS = [
34
- { id: "products", label: "Products", listingType: "standard" },
35
- { id: "auctions", label: "Auctions", listingType: "auction" },
36
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
37
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
77
+ ...SEPARATELY_TABBED_TYPES.map(pluralTab),
38
78
  { id: "bundles", label: "Bundles", collection: "bundles" },
39
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
40
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
41
- { id: "live", label: "Live Items", listingType: "live" },
42
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
79
+ ART_STICKERS_COMBINED_TAB,
43
80
  ];
44
81
  /** Tabs shown on the seller-dashboard listings view + admin products list. */
45
82
  export const SELLER_LISTING_TABS = [
46
83
  { id: "all", label: "All" },
47
- { id: "products", label: "Products", listingType: "standard" },
48
- { id: "auctions", label: "Auctions", listingType: "auction" },
49
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
50
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
51
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
52
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
53
- { id: "live", label: "Live Items", listingType: "live" },
54
- { id: "art", label: "Art", listingType: "art" },
55
- { id: "stickers", label: "Stickers", listingType: "stickers" },
56
- ];
57
- /** Tabs shown on `/search` results. */
58
- export const SEARCH_RESULT_TABS = [
59
- { id: "all", label: "All" },
60
- { id: "products", label: "Products", listingType: "standard" },
61
- { id: "auctions", label: "Auctions", listingType: "auction" },
62
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
63
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
64
- { id: "bundles", label: "Bundles", collection: "bundles" },
65
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
66
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
67
- { id: "live", label: "Live Items", listingType: "live" },
68
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
69
- ];
70
- /** In-page type-filter chips on the generic `/products` browse page. */
71
- export const PRODUCT_TYPE_FILTER_TABS = [
72
- { id: "All", label: "All" },
73
- { id: "standard", label: "Standard" },
74
- { id: "classified", label: "Classified" },
75
- { id: "digital-code", label: "Digital Codes" },
76
- { id: "live", label: "Live Items" },
84
+ ...ALL_LISTING_TYPES.map(pluralTab),
77
85
  ];
86
+ /**
87
+ * In-page type-filter chips on the generic `/products` browse page.
88
+ *
89
+ * Multi-select (checkbox semantics) — no "All" sentinel chip, because "none
90
+ * checked" already means "every type". A sentinel would be a second way to
91
+ * express the same state and would have to be cleared whenever a real chip
92
+ * was ticked.
93
+ */
94
+ export const PRODUCT_TYPE_FILTER_TABS = ALL_LISTING_TYPES.map(chipTab);
78
95
  /** In-page type-filter chips on the combined `/art` (Art & Stickers) page. */
79
- export const ART_STICKERS_TYPE_FILTER_TABS = [
80
- { id: "All", label: "All" },
81
- { id: "art", label: "Art" },
82
- { id: "stickers", label: "Stickers" },
83
- ];
96
+ export const ART_STICKERS_TYPE_FILTER_TABS = ART_STICKERS_LISTING_TYPES.map(chipTab);
@@ -141,6 +141,90 @@ export declare const PREORDER_SORT_OPTIONS: readonly [{
141
141
  readonly value: string;
142
142
  readonly label: "Lowest Deposit First";
143
143
  }];
144
+ /**
145
+ * Public pre-order browse subset. Drops "Lowest Deposit First" — deposit
146
+ * amount is a seller-side pricing lever buyers don't shop by — but keeps
147
+ * both delivery-date directions, which are the primary browse intent.
148
+ */
149
+ export declare const PREORDER_PUBLIC_SORT_OPTIONS: readonly [{
150
+ readonly value: string;
151
+ readonly label: "Earliest Delivery";
152
+ }, {
153
+ readonly value: string;
154
+ readonly label: "Latest Delivery";
155
+ }, {
156
+ readonly value: string;
157
+ readonly label: "Newest First";
158
+ } | {
159
+ readonly value: string;
160
+ readonly label: "Oldest First";
161
+ } | {
162
+ readonly value: string;
163
+ readonly label: "Price: Low to High";
164
+ } | {
165
+ readonly value: string;
166
+ readonly label: "Price: High to Low";
167
+ } | {
168
+ readonly value: string;
169
+ readonly label: "Fewest Slots Left";
170
+ } | {
171
+ readonly value: string;
172
+ readonly label: "Lowest Deposit First";
173
+ }, {
174
+ readonly value: string;
175
+ readonly label: "Newest First";
176
+ } | {
177
+ readonly value: string;
178
+ readonly label: "Oldest First";
179
+ } | {
180
+ readonly value: string;
181
+ readonly label: "Price: Low to High";
182
+ } | {
183
+ readonly value: string;
184
+ readonly label: "Price: High to Low";
185
+ } | {
186
+ readonly value: string;
187
+ readonly label: "Fewest Slots Left";
188
+ } | {
189
+ readonly value: string;
190
+ readonly label: "Lowest Deposit First";
191
+ }, {
192
+ readonly value: string;
193
+ readonly label: "Newest First";
194
+ } | {
195
+ readonly value: string;
196
+ readonly label: "Oldest First";
197
+ } | {
198
+ readonly value: string;
199
+ readonly label: "Price: Low to High";
200
+ } | {
201
+ readonly value: string;
202
+ readonly label: "Price: High to Low";
203
+ } | {
204
+ readonly value: string;
205
+ readonly label: "Fewest Slots Left";
206
+ } | {
207
+ readonly value: string;
208
+ readonly label: "Lowest Deposit First";
209
+ }, {
210
+ readonly value: string;
211
+ readonly label: "Newest First";
212
+ } | {
213
+ readonly value: string;
214
+ readonly label: "Oldest First";
215
+ } | {
216
+ readonly value: string;
217
+ readonly label: "Price: Low to High";
218
+ } | {
219
+ readonly value: string;
220
+ readonly label: "Price: High to Low";
221
+ } | {
222
+ readonly value: string;
223
+ readonly label: "Fewest Slots Left";
224
+ } | {
225
+ readonly value: string;
226
+ readonly label: "Lowest Deposit First";
227
+ }];
144
228
  export declare const BUNDLE_SORT_OPTIONS: readonly [...({
145
229
  readonly value: string;
146
230
  readonly label: "Newest First";
@@ -173,4 +257,23 @@ export declare const PRIZE_DRAW_SORT_OPTIONS: readonly [{
173
257
  readonly value: string;
174
258
  readonly label: "Entry: High to Low";
175
259
  }];
176
- export declare const SORT_OPTIONS_BY_LISTING_TYPE: Record<string, readonly SortOption[]>;
260
+ /** Public prize-draw browse subset every option is buyer-meaningful. */
261
+ export declare const PRIZE_DRAW_PUBLIC_SORT_OPTIONS: readonly [{
262
+ readonly value: string;
263
+ readonly label: "Newest First";
264
+ }, {
265
+ readonly value: string;
266
+ readonly label: "Oldest First";
267
+ }, {
268
+ readonly value: string;
269
+ readonly label: "Reveal: Soonest";
270
+ }, {
271
+ readonly value: string;
272
+ readonly label: "Reveal: Furthest";
273
+ }, {
274
+ readonly value: string;
275
+ readonly label: "Entry: Low to High";
276
+ }, {
277
+ readonly value: string;
278
+ readonly label: "Entry: High to Low";
279
+ }];
@@ -73,6 +73,19 @@ export const PREORDER_SORT_OPTIONS = [
73
73
  { value: sortBy(PRODUCT_FIELDS.PRE_ORDER_CURRENT_COUNT), label: "Fewest Slots Left" },
74
74
  { value: sortBy(PRODUCT_FIELDS.PRE_ORDER_DEPOSIT_AMOUNT, "ASC"), label: "Lowest Deposit First" },
75
75
  ];
76
+ /**
77
+ * Public pre-order browse subset. Drops "Lowest Deposit First" — deposit
78
+ * amount is a seller-side pricing lever buyers don't shop by — but keeps
79
+ * both delivery-date directions, which are the primary browse intent.
80
+ */
81
+ export const PREORDER_PUBLIC_SORT_OPTIONS = [
82
+ PREORDER_SORT_OPTIONS[0],
83
+ PREORDER_SORT_OPTIONS[1],
84
+ PREORDER_SORT_OPTIONS[2],
85
+ PREORDER_SORT_OPTIONS[3],
86
+ PREORDER_SORT_OPTIONS[4],
87
+ PREORDER_SORT_OPTIONS[5],
88
+ ];
76
89
  // ---------------------------------------------------------------------------
77
90
  // Bundles
78
91
  // ---------------------------------------------------------------------------
@@ -94,13 +107,20 @@ export const PRIZE_DRAW_SORT_OPTIONS = [
94
107
  { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Entry: Low to High" },
95
108
  { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Entry: High to Low" },
96
109
  ];
110
+ /** Public prize-draw browse subset — every option is buyer-meaningful. */
111
+ export const PRIZE_DRAW_PUBLIC_SORT_OPTIONS = PRIZE_DRAW_SORT_OPTIONS;
97
112
  // ---------------------------------------------------------------------------
98
113
  // Lookup by listing type
99
114
  // ---------------------------------------------------------------------------
100
- export const SORT_OPTIONS_BY_LISTING_TYPE = {
101
- standard: STANDARD_SORT_OPTIONS,
102
- auction: AUCTION_SORT_OPTIONS,
103
- "pre-order": PREORDER_SORT_OPTIONS,
104
- bundle: BUNDLE_SORT_OPTIONS,
105
- "prize-draw": PRIZE_DRAW_SORT_OPTIONS,
106
- };
115
+ //
116
+ // The per-type lookup used to live here as a hand-written map keyed on plain
117
+ // strings. It carried a `bundle` key long after SB-UNI-D stopped bundles from
118
+ // being a listingType, and had no entry at all for classified / digital-code /
119
+ // live / art / stickers — five of nine types. It is now DERIVED from the
120
+ // listing-type plugin registry (`sortOptionsFor()` in
121
+ // `_internal/shared/listing-types/_registry.ts`), so a type can never be
122
+ // missing from it again.
123
+ //
124
+ // `BUNDLE_SORT_OPTIONS` above stays a standalone export on purpose — bundles
125
+ // are a `categoryType` on the `categories` collection, not a listingType, so
126
+ // they must not be reachable through a ListingType-keyed lookup.
@@ -109,6 +109,10 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
109
109
  canFilter: boolean;
110
110
  canSort: boolean;
111
111
  };
112
+ isOnSale: {
113
+ canFilter: boolean;
114
+ canSort: boolean;
115
+ };
112
116
  price: {
113
117
  canFilter: boolean;
114
118
  canSort: boolean;
@@ -117,6 +121,10 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
117
121
  canFilter: boolean;
118
122
  canSort: boolean;
119
123
  };
124
+ availableQuantity: {
125
+ canFilter: boolean;
126
+ canSort: boolean;
127
+ };
120
128
  viewCount: {
121
129
  canFilter: boolean;
122
130
  canSort: boolean;
@@ -129,6 +137,10 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
129
137
  canFilter: boolean;
130
138
  canSort: boolean;
131
139
  };
140
+ bidsHaveStarted: {
141
+ canFilter: boolean;
142
+ canSort: boolean;
143
+ };
132
144
  isSold: {
133
145
  canFilter: boolean;
134
146
  canSort: boolean;
@@ -137,6 +149,18 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
137
149
  canFilter: boolean;
138
150
  canSort: boolean;
139
151
  };
152
+ isTestData: {
153
+ canFilter: boolean;
154
+ canSort: boolean;
155
+ };
156
+ brandSlug: {
157
+ canFilter: boolean;
158
+ canSort: boolean;
159
+ };
160
+ sublistingCategoryId: {
161
+ canFilter: boolean;
162
+ canSort: boolean;
163
+ };
140
164
  createdAt: {
141
165
  canFilter: boolean;
142
166
  canSort: boolean;
@@ -166,6 +190,22 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
166
190
  canFilter: boolean;
167
191
  canSort: boolean;
168
192
  };
193
+ prizeDrawMode: {
194
+ canFilter: boolean;
195
+ canSort: boolean;
196
+ };
197
+ pricePerEntry: {
198
+ canFilter: boolean;
199
+ canSort: boolean;
200
+ };
201
+ prizeCurrentEntries: {
202
+ canFilter: boolean;
203
+ canSort: boolean;
204
+ };
205
+ prizeMaxEntries: {
206
+ canFilter: boolean;
207
+ canSort: boolean;
208
+ };
169
209
  startingBid: {
170
210
  canFilter: boolean;
171
211
  canSort: boolean;
@@ -215,6 +255,10 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
215
255
  canFilter: boolean;
216
256
  canSort: boolean;
217
257
  };
258
+ preOrderClosed: {
259
+ canFilter: boolean;
260
+ canSort: boolean;
261
+ };
218
262
  tags: {
219
263
  canFilter: boolean;
220
264
  canSort: boolean;
@@ -231,7 +275,7 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
231
275
  canFilter: boolean;
232
276
  canSort: boolean;
233
277
  };
234
- freeShipping: {
278
+ shippingPaidBy: {
235
279
  canFilter: boolean;
236
280
  canSort: boolean;
237
281
  };