@mohasinac/appkit 4.30.18 → 4.31.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 (557) hide show
  1. package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +5 -2
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -3
  3. package/dist/_internal/client/features/layout/useSidebarSearch.d.ts +21 -5
  4. package/dist/_internal/client/features/layout/useSidebarSearch.js +27 -6
  5. package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +23 -3
  6. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +106 -86
  7. package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +16 -5
  8. package/dist/_internal/client/features/lottery/LotteryPullForm.js +65 -40
  9. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +5 -2
  10. package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +11 -3
  11. package/dist/_internal/client/hand-mode/HandModeProvider.js +2 -0
  12. package/dist/_internal/server/features/auctions/actions.js +14 -3
  13. package/dist/_internal/server/features/auctions/service.js +1 -1
  14. package/dist/_internal/server/features/auth/permissions.d.ts +2 -0
  15. package/dist/_internal/server/features/auth/permissions.js +3 -2
  16. package/dist/_internal/server/features/blog/data.js +2 -2
  17. package/dist/_internal/server/features/blog/service.js +3 -3
  18. package/dist/_internal/server/features/brands/data.js +1 -1
  19. package/dist/_internal/server/features/brands/service.js +3 -3
  20. package/dist/_internal/server/features/bundles/actions.js +6 -1
  21. package/dist/_internal/server/features/bundles/data.js +21 -4
  22. package/dist/_internal/server/features/cart/data.js +3 -1
  23. package/dist/_internal/server/features/cart/service.js +13 -2
  24. package/dist/_internal/server/features/categories/data.js +26 -6
  25. package/dist/_internal/server/features/classified/index.d.ts +0 -1
  26. package/dist/_internal/server/features/classified/index.js +0 -1
  27. package/dist/_internal/server/features/digital-code/index.d.ts +0 -1
  28. package/dist/_internal/server/features/digital-code/index.js +0 -1
  29. package/dist/_internal/server/features/events/actions.js +17 -4
  30. package/dist/_internal/server/features/events/data.js +1 -1
  31. package/dist/_internal/server/features/events/service.js +1 -1
  32. package/dist/_internal/server/features/grouped/data.js +7 -2
  33. package/dist/_internal/server/features/item-requests/data.js +1 -1
  34. package/dist/_internal/server/features/live/index.d.ts +0 -1
  35. package/dist/_internal/server/features/live/index.js +0 -1
  36. package/dist/_internal/server/features/lottery/actions.js +2 -2
  37. package/dist/_internal/server/features/lottery/data.js +1 -1
  38. package/dist/_internal/server/features/orders/actions.js +7 -7
  39. package/dist/_internal/server/features/orders/data.d.ts +1 -1
  40. package/dist/_internal/server/features/orders/data.js +14 -2
  41. package/dist/_internal/server/features/orders/service.js +1 -1
  42. package/dist/_internal/server/features/pre-orders/service.js +1 -1
  43. package/dist/_internal/server/features/prize-draws/actions.js +1 -1
  44. package/dist/_internal/server/features/products/data.js +21 -6
  45. package/dist/_internal/server/features/products/list-public.d.ts +9 -0
  46. package/dist/_internal/server/features/products/list-public.js +95 -7
  47. package/dist/_internal/server/features/products/service.js +1 -1
  48. package/dist/_internal/server/features/promotions/actions.js +1 -1
  49. package/dist/_internal/server/features/promotions/data.js +1 -1
  50. package/dist/_internal/server/features/promotions/service.js +1 -1
  51. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  52. package/dist/_internal/server/features/reviews/data.js +6 -1
  53. package/dist/_internal/server/features/reviews/og-data.js +1 -1
  54. package/dist/_internal/server/features/shared/listing-data-factory.js +7 -2
  55. package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
  56. package/dist/_internal/server/features/site-settings/adapters.js +8 -5
  57. package/dist/_internal/server/features/stores/data.js +1 -1
  58. package/dist/_internal/server/features/sublisting-categories/data.js +1 -1
  59. package/dist/_internal/server/features/tester/visibility.d.ts +2 -1
  60. package/dist/_internal/server/features/tester/visibility.js +2 -2
  61. package/dist/_internal/server/functions/scheduled.d.ts +3 -1
  62. package/dist/_internal/server/functions/scheduled.js +27 -1
  63. package/dist/_internal/server/jobs/core/auctionSettlement.js +6 -1
  64. package/dist/_internal/server/jobs/core/hardBanCascade.js +4 -0
  65. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  66. package/dist/_internal/server/jobs/core/index.js +2 -0
  67. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +7 -15
  68. package/dist/_internal/server/jobs/core/pageViewPrune.d.ts +10 -0
  69. package/dist/_internal/server/jobs/core/pageViewPrune.js +44 -0
  70. package/dist/_internal/server/jobs/core/pageViewRollup.d.ts +2 -0
  71. package/dist/_internal/server/jobs/core/pageViewRollup.js +87 -0
  72. package/dist/_internal/server/jobs/core/revenueRollup.js +7 -1
  73. package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
  74. package/dist/_internal/server/jobs/handlers/index.js +2 -0
  75. package/dist/_internal/server/jobs/handlers/pageViewPrune.d.ts +2 -0
  76. package/dist/_internal/server/jobs/handlers/pageViewPrune.js +2 -0
  77. package/dist/_internal/server/jobs/handlers/pageViewRollup.d.ts +2 -0
  78. package/dist/_internal/server/jobs/handlers/pageViewRollup.js +2 -0
  79. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  80. package/dist/_internal/shared/actions/action-registry.js +69 -22
  81. package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -4
  82. package/dist/_internal/shared/checkout/rules/classified.rule.js +7 -2
  83. package/dist/_internal/shared/features/layout/matchesNavQuery.d.ts +14 -0
  84. package/dist/_internal/shared/features/layout/matchesNavQuery.js +72 -0
  85. package/dist/_internal/shared/features/layout/types.d.ts +37 -1
  86. package/dist/_internal/shared/features/layout/types.js +19 -1
  87. package/dist/_internal/shared/features/notifications/action-url.d.ts +9 -1
  88. package/dist/_internal/shared/features/notifications/action-url.js +47 -0
  89. package/dist/_internal/shared/features/offers/config.d.ts +65 -0
  90. package/dist/_internal/shared/features/offers/config.js +73 -2
  91. package/dist/_internal/shared/features/orders/schema.d.ts +19 -1
  92. package/dist/_internal/shared/features/orders/schema.js +22 -2
  93. package/dist/_internal/shared/features/site-settings/types.d.ts +12 -3
  94. package/dist/_internal/shared/listing-types/capabilities.d.ts +8 -2
  95. package/dist/_internal/shared/listing-types/capabilities.js +6 -1
  96. package/dist/_internal/shared/listing-types/classified/ctas.js +6 -1
  97. package/dist/_internal/shared/listing-types/feature-flags.d.ts +10 -5
  98. package/dist/_internal/shared/listing-types/feature-flags.js +11 -6
  99. package/dist/client/api/useApiQuery.js +17 -6
  100. package/dist/client.d.ts +38 -20
  101. package/dist/client.js +39 -14
  102. package/dist/configs/next.js +10 -2
  103. package/dist/constants/api-endpoints.d.ts +18 -54
  104. package/dist/constants/api-endpoints.js +6 -26
  105. package/dist/constants/field-names.d.ts +6 -24
  106. package/dist/constants/field-names.js +10 -27
  107. package/dist/constants/geo/countries.d.ts +50 -0
  108. package/dist/constants/geo/countries.js +129 -0
  109. package/dist/constants/geo/subdivisions.d.ts +13 -0
  110. package/dist/constants/geo/subdivisions.js +104 -0
  111. package/dist/constants/index.d.ts +2 -2
  112. package/dist/constants/index.js +2 -2
  113. package/dist/constants/table-keys.d.ts +24 -0
  114. package/dist/constants/table-keys.js +28 -0
  115. package/dist/contracts/client-realtime.d.ts +6 -0
  116. package/dist/contracts/extend.d.ts +0 -9
  117. package/dist/contracts/index.d.ts +1 -1
  118. package/dist/contracts/realtime-session.d.ts +12 -12
  119. package/dist/contracts/realtime-session.js +79 -77
  120. package/dist/core/browser.d.ts +1 -1
  121. package/dist/core/browser.js +1 -1
  122. package/dist/core/index.d.ts +1 -1
  123. package/dist/core/index.js +1 -1
  124. package/dist/core/site-config.d.ts +0 -3
  125. package/dist/core/site-config.js +0 -3
  126. package/dist/errors/index.d.ts +1 -1
  127. package/dist/errors/index.js +1 -1
  128. package/dist/errors/messages.d.ts +0 -8
  129. package/dist/errors/messages.js +0 -9
  130. package/dist/features/about/components/DeveloperView.js +7 -2
  131. package/dist/features/about/components/PolicyPageView.js +9 -1
  132. package/dist/features/about/components/PublicProfileView.js +23 -5
  133. package/dist/features/about/schemas/index.d.ts +8 -8
  134. package/dist/features/account/components/AddressFilters.js +32 -11
  135. package/dist/features/account/components/AddressForm.d.ts +26 -25
  136. package/dist/features/account/components/AddressForm.js +81 -103
  137. package/dist/features/account/components/AddressesIndexListing.js +8 -4
  138. package/dist/features/account/components/NotificationBell.js +4 -3
  139. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  140. package/dist/features/account/components/UserOffersPanel.js +1 -1
  141. package/dist/features/account/components/UserSidebar.d.ts +3 -4
  142. package/dist/features/account/components/UserSupportView.js +89 -58
  143. package/dist/features/account/components/index.d.ts +1 -7
  144. package/dist/features/account/components/index.js +0 -3
  145. package/dist/features/account/hooks/useAddresses.d.ts +4 -3
  146. package/dist/features/account/hooks/useAddresses.js +4 -6
  147. package/dist/features/account/hooks/useCollapsedSections.d.ts +51 -10
  148. package/dist/features/account/hooks/useCollapsedSections.js +211 -38
  149. package/dist/features/account/hooks/useProfile.d.ts +8 -0
  150. package/dist/features/account/index.d.ts +0 -3
  151. package/dist/features/account/index.js +0 -3
  152. package/dist/features/account/schemas/index.d.ts +0 -92
  153. package/dist/features/account/schemas/index.js +42 -20
  154. package/dist/features/addresses/components/AddressLocationFields.d.ts +13 -0
  155. package/dist/features/addresses/components/AddressLocationFields.js +41 -0
  156. package/dist/features/addresses/hooks/usePostalLookup.d.ts +17 -0
  157. package/dist/features/addresses/hooks/usePostalLookup.js +133 -0
  158. package/dist/features/addresses/schemas/address-form.d.ts +423 -0
  159. package/dist/features/addresses/schemas/address-form.js +212 -0
  160. package/dist/features/addresses/schemas/index.d.ts +1 -0
  161. package/dist/features/addresses/schemas/index.js +8 -0
  162. package/dist/features/admin/actions/admin-read-actions.d.ts +1 -1
  163. package/dist/features/admin/actions/index.d.ts +0 -1
  164. package/dist/features/admin/actions/index.js +0 -1
  165. package/dist/features/admin/actions/notification-actions.js +1 -41
  166. package/dist/features/admin/components/AdminActionIndexView.d.ts +32 -0
  167. package/dist/features/admin/components/AdminActionIndexView.js +128 -0
  168. package/dist/features/admin/components/AdminAdEditorView.js +159 -163
  169. package/dist/features/admin/components/AdminAddressEditorView.js +97 -55
  170. package/dist/features/admin/components/AdminBrandEditorView.d.ts +15 -0
  171. package/dist/features/admin/components/AdminBrandEditorView.js +113 -77
  172. package/dist/features/admin/components/AdminBundleEditorView.d.ts +19 -9
  173. package/dist/features/admin/components/AdminBundleEditorView.js +136 -168
  174. package/dist/features/admin/components/AdminCategoryEditorView.js +120 -43
  175. package/dist/features/admin/components/AdminCouponEditorView.js +145 -109
  176. package/dist/features/admin/components/AdminEmployeeEditorView.js +125 -56
  177. package/dist/features/admin/components/AdminFaqEditorView.js +112 -58
  178. package/dist/features/admin/components/AdminFeatureEditorView.js +108 -68
  179. package/dist/features/admin/components/AdminFulfillmentView.js +5 -2
  180. package/dist/features/admin/components/AdminMediaView.js +3 -3
  181. package/dist/features/admin/components/AdminNavEditorView.js +69 -44
  182. package/dist/features/admin/components/AdminOrderEditorView.js +47 -10
  183. package/dist/features/admin/components/AdminPrizeDrawsView.js +16 -2
  184. package/dist/features/admin/components/AdminSidebar.d.ts +11 -7
  185. package/dist/features/admin/components/AdminSiteSettingsView.js +37 -37
  186. package/dist/features/admin/components/AdminStoreEditorView.js +75 -52
  187. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +71 -30
  188. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +95 -65
  189. package/dist/features/admin/components/BrandQuickCreateForm.d.ts +10 -0
  190. package/dist/features/admin/components/BrandQuickCreateForm.js +49 -26
  191. package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +11 -0
  192. package/dist/features/admin/components/CategoryQuickCreateForm.js +48 -26
  193. package/dist/features/admin/components/index.d.ts +2 -2
  194. package/dist/features/admin/components/index.js +1 -1
  195. package/dist/features/admin/constants/site-settings-tabs.d.ts +120 -0
  196. package/dist/features/admin/constants/site-settings-tabs.js +152 -0
  197. package/dist/features/admin/index.d.ts +0 -3
  198. package/dist/features/admin/index.js +0 -2
  199. package/dist/features/admin/repository/analytics-rollup.repository.d.ts +35 -0
  200. package/dist/features/admin/repository/analytics-rollup.repository.js +30 -0
  201. package/dist/features/admin/schemas/admin-editor-forms.d.ts +56 -57
  202. package/dist/features/admin/schemas/admin-editor-forms.js +97 -54
  203. package/dist/features/admin/schemas/admin-ops-forms.d.ts +57 -5
  204. package/dist/features/admin/schemas/admin-ops-forms.js +104 -20
  205. package/dist/features/admin/schemas/admin-user-form.js +7 -0
  206. package/dist/features/admin/schemas/firestore.d.ts +48 -95
  207. package/dist/features/admin/schemas/firestore.js +15 -151
  208. package/dist/features/admin/schemas/nav-item-form.js +9 -2
  209. package/dist/features/admin/server.d.ts +0 -4
  210. package/dist/features/admin/server.js +0 -2
  211. package/dist/features/admin/types/index.d.ts +0 -7
  212. package/dist/features/analytics/repository/page-views.repository.d.ts +14 -0
  213. package/dist/features/analytics/repository/page-views.repository.js +24 -0
  214. package/dist/features/analytics/types.d.ts +1 -1
  215. package/dist/features/analytics/types.js +13 -0
  216. package/dist/features/auctions/components/AuctionDetailPageView.js +6 -2
  217. package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -1
  218. package/dist/features/auth/actions/index.d.ts +0 -1
  219. package/dist/features/auth/actions/index.js +0 -1
  220. package/dist/features/auth/actions/profile-actions.js +4 -3
  221. package/dist/features/auth/actions/realtime-token-actions.js +1 -12
  222. package/dist/features/auth/auth-helpers.js +5 -7
  223. package/dist/features/auth/components/ForgotPasswordView.js +1 -1
  224. package/dist/features/auth/components/Guards.js +2 -1
  225. package/dist/features/auth/components/LoginForm.d.ts +0 -2
  226. package/dist/features/auth/components/LoginForm.js +2 -4
  227. package/dist/features/auth/components/RegisterForm.js +62 -19
  228. package/dist/features/auth/components/ResetPasswordView.js +1 -1
  229. package/dist/features/auth/hooks/useAuth.js +3 -0
  230. package/dist/features/auth/permissions/constants.d.ts +27 -1
  231. package/dist/features/auth/role-predicates.d.ts +75 -7
  232. package/dist/features/auth/role-predicates.js +28 -2
  233. package/dist/features/auth/schemas/firestore.d.ts +22 -0
  234. package/dist/features/auth/schemas/index.d.ts +1 -1
  235. package/dist/features/auth/schemas/index.js +44 -8
  236. package/dist/features/auth/types/index.d.ts +14 -1
  237. package/dist/features/blog/api/route.js +10 -2
  238. package/dist/features/blog/components/BlogIndexListing.js +1 -1
  239. package/dist/features/blog/hooks/useBlog.js +2 -2
  240. package/dist/features/blog/repository/blog.repository.js +3 -1
  241. package/dist/features/blog/schemas/index.d.ts +4 -0
  242. package/dist/features/blog/schemas/index.js +2 -0
  243. package/dist/features/blog/types/index.d.ts +1 -1
  244. package/dist/features/cart/actions/cart-actions.js +13 -4
  245. package/dist/features/cart/utils/pending-ops.js +1 -1
  246. package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +22 -0
  247. package/dist/features/catalogue/components/CatalogueItemEditorView.js +112 -52
  248. package/dist/features/catalogue/schemas/validation.d.ts +4 -4
  249. package/dist/features/catalogue/schemas/validation.js +47 -10
  250. package/dist/features/categories/components/BrandDetailPageView.js +28 -12
  251. package/dist/features/categories/components/CategoryDetailPageView.js +37 -20
  252. package/dist/features/categories/repository/categories.repository.js +3 -1
  253. package/dist/features/categories/schemas/bundle-form.d.ts +142 -0
  254. package/dist/features/categories/schemas/bundle-form.js +149 -0
  255. package/dist/features/checkout/actions/checkout-value-otp-actions.js +10 -1
  256. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +1 -1
  257. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +5 -4
  258. package/dist/features/classified/components/ClassifiedDetailPageView.js +47 -18
  259. package/dist/features/consultation/components/ConsultationForm.js +1 -1
  260. package/dist/features/consultation/schemas/index.js +34 -10
  261. package/dist/features/corporate/schemas/index.js +36 -15
  262. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +4 -1
  263. package/dist/features/events/components/EventBanner.js +5 -2
  264. package/dist/features/events/components/EventOfferCard.js +3 -1
  265. package/dist/features/events/components/EventPollWidget.js +1 -1
  266. package/dist/features/events/components/SpinWheelView.js +3 -2
  267. package/dist/features/filters/FilterPanel.js +3 -3
  268. package/dist/features/filters/RangeFilter.d.ts +10 -0
  269. package/dist/features/filters/RangeFilter.js +41 -4
  270. package/dist/features/grouped/components/GroupedListingEditorView.js +2 -1
  271. package/dist/features/history/hooks/useHistory.js +29 -27
  272. package/dist/features/homepage/components/AdSlot.js +3 -1
  273. package/dist/features/homepage/components/GoogleReviewsSection.js +8 -2
  274. package/dist/features/homepage/components/MarketplaceHomepageView.js +58 -15
  275. package/dist/features/homepage/components/SocialFeedSection.js +4 -1
  276. package/dist/features/homepage/hooks/useBlogArticles.js +1 -1
  277. package/dist/features/homepage/lib/live-stats.js +8 -1
  278. package/dist/features/homepage/repository/carousel.repository.js +2 -1
  279. package/dist/features/layout/BottomActions.js +84 -11
  280. package/dist/features/layout/BottomActionsContext.d.ts +1 -6
  281. package/dist/features/layout/BottomActionsContext.js +1 -1
  282. package/dist/features/layout/hooks/useBottomActions.js +2 -2
  283. package/dist/features/layout/hooks/useFormBottomActions.d.ts +12 -1
  284. package/dist/features/layout/hooks/useFormBottomActions.js +12 -6
  285. package/dist/features/live/components/LiveItemDetailPageView.js +4 -1
  286. package/dist/features/lottery/schemas/config-write.d.ts +9 -5
  287. package/dist/features/lottery/schemas/config-write.js +69 -9
  288. package/dist/features/media/finalize.js +3 -1
  289. package/dist/features/media/modals/ImageEditor.js +1 -1
  290. package/dist/features/media/modals/VideoThumbnailSelector.js +5 -2
  291. package/dist/features/media/modals/VideoTrimModal.js +5 -2
  292. package/dist/features/media/upload/MediaUploadField.js +2 -2
  293. package/dist/features/messages/hooks/useConversation.js +18 -4
  294. package/dist/features/messages/hooks/useConversations.js +25 -8
  295. package/dist/features/orders/components/RefundRequestView.js +5 -2
  296. package/dist/features/orders/schemas/buyer-forms.d.ts +6 -3
  297. package/dist/features/orders/schemas/buyer-forms.js +31 -3
  298. package/dist/features/orders/schemas/index.d.ts +2 -2
  299. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -1
  300. package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
  301. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -1
  302. package/dist/features/products/components/GroupSettingsPanel.js +3 -1
  303. package/dist/features/products/components/MakeOfferButton.d.ts +13 -2
  304. package/dist/features/products/components/MakeOfferButton.js +33 -11
  305. package/dist/features/products/components/PrizeDrawDetailPageView.js +4 -1
  306. package/dist/features/products/components/ProductDetailActions.js +0 -1
  307. package/dist/features/products/components/ProductDetailPageView.d.ts +7 -3
  308. package/dist/features/products/components/ProductDetailPageView.js +16 -7
  309. package/dist/features/products/components/ShareButton.js +3 -1
  310. package/dist/features/products/constants/action-defs.d.ts +1 -2
  311. package/dist/features/products/constants/action-defs.js +40 -43
  312. package/dist/features/products/repository/loadProductFeatures.js +10 -2
  313. package/dist/features/products/repository/products.repository.d.ts +5 -1
  314. package/dist/features/products/repository/products.repository.js +25 -2
  315. package/dist/features/products/schemas/firestore.d.ts +7 -3
  316. package/dist/features/products/schemas/product-features.validators.js +3 -0
  317. package/dist/features/promotions/components/CouponCard.js +11 -8
  318. package/dist/features/reviews/actions/review-actions.js +8 -1
  319. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -3
  320. package/dist/features/reviews/components/ReviewDetailShell.js +3 -1
  321. package/dist/features/scams/actions/scam-actions.d.ts +9 -1
  322. package/dist/features/scams/actions/scam-actions.js +52 -12
  323. package/dist/features/scams/components/SellerTrustBadge.d.ts +1 -1
  324. package/dist/features/scams/components/SellerTrustBadge.js +13 -0
  325. package/dist/features/scams/repository/scammer.repository.js +2 -1
  326. package/dist/features/scams/schemas/firestore.d.ts +15 -1
  327. package/dist/features/scams/schemas/report-form.d.ts +5 -5
  328. package/dist/features/scams/schemas/report-form.js +18 -3
  329. package/dist/features/search/action-index/derive.d.ts +49 -0
  330. package/dist/features/search/action-index/derive.js +121 -0
  331. package/dist/features/search/action-index/repository.d.ts +42 -0
  332. package/dist/features/search/action-index/repository.js +100 -0
  333. package/dist/features/search/action-index/settings-entries.d.ts +41 -0
  334. package/dist/features/search/action-index/settings-entries.js +268 -0
  335. package/dist/features/search/action-index/types.d.ts +81 -0
  336. package/dist/features/search/action-index/types.js +102 -0
  337. package/dist/features/search/action-index/validate-entry.d.ts +34 -0
  338. package/dist/features/search/action-index/validate-entry.js +114 -0
  339. package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
  340. package/dist/features/search/hooks/useNavSuggestions.js +23 -3
  341. package/dist/features/search/repository/search.repository.js +3 -1
  342. package/dist/features/seller/actions/offer-actions.js +43 -19
  343. package/dist/features/seller/actions/seller-actions.js +29 -5
  344. package/dist/features/seller/components/CategoryChipPicker.d.ts +9 -0
  345. package/dist/features/seller/components/CategoryChipPicker.js +12 -0
  346. package/dist/features/seller/components/FulfillmentView.js +5 -2
  347. package/dist/features/seller/components/PhysicalLocationModal.js +1 -1
  348. package/dist/features/seller/components/PrintCenterView.js +3 -1
  349. package/dist/features/seller/components/SellerAddressesView.js +5 -1
  350. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +83 -43
  351. package/dist/features/seller/components/SellerArtView.d.ts +14 -7
  352. package/dist/features/seller/components/SellerArtView.js +4 -119
  353. package/dist/features/seller/components/SellerBidsView.js +1 -1
  354. package/dist/features/seller/components/SellerClassifiedView.d.ts +14 -7
  355. package/dist/features/seller/components/SellerClassifiedView.js +4 -124
  356. package/dist/features/seller/components/SellerCouponEditorView.d.ts +22 -1
  357. package/dist/features/seller/components/SellerCouponEditorView.js +91 -45
  358. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  359. package/dist/features/seller/components/SellerDigitalCodesView.d.ts +14 -7
  360. package/dist/features/seller/components/SellerDigitalCodesView.js +4 -126
  361. package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
  362. package/dist/features/seller/components/SellerListingTypeView.d.ts +66 -0
  363. package/dist/features/seller/components/SellerListingTypeView.js +277 -0
  364. package/dist/features/seller/components/SellerLiveView.d.ts +14 -7
  365. package/dist/features/seller/components/SellerLiveView.js +4 -126
  366. package/dist/features/seller/components/SellerOrdersView.js +3 -3
  367. package/dist/features/seller/components/SellerPayoutMethodsView.js +2 -2
  368. package/dist/features/seller/components/SellerProductShell.d.ts +5 -0
  369. package/dist/features/seller/components/SellerProductShell.js +15 -5
  370. package/dist/features/seller/components/SellerProductsView.js +24 -10
  371. package/dist/features/seller/components/SellerReviewsView.js +47 -16
  372. package/dist/features/seller/components/SellerShippingConfigsView.js +5 -4
  373. package/dist/features/seller/components/SellerSidebar.d.ts +3 -6
  374. package/dist/features/seller/components/SellerStickersView.d.ts +14 -7
  375. package/dist/features/seller/components/SellerStickersView.js +4 -119
  376. package/dist/features/seller/components/SellerStoreCategoriesView.js +3 -2
  377. package/dist/features/seller/components/SellerSupportView.d.ts +31 -0
  378. package/dist/features/seller/components/SellerSupportView.js +100 -0
  379. package/dist/features/seller/components/index.d.ts +4 -8
  380. package/dist/features/seller/components/index.js +2 -4
  381. package/dist/features/seller/index.d.ts +0 -1
  382. package/dist/features/seller/index.js +0 -1
  383. package/dist/features/seller/schemas/coupon-form.d.ts +214 -0
  384. package/dist/features/seller/schemas/coupon-form.js +155 -23
  385. package/dist/features/seller/schemas/offer-forms.d.ts +16 -7
  386. package/dist/features/seller/schemas/offer-forms.js +28 -12
  387. package/dist/features/shell/FormShell.js +2 -2
  388. package/dist/features/shell/QuickFormDrawer.js +2 -2
  389. package/dist/features/shell/SectionForm.d.ts +19 -1
  390. package/dist/features/shell/SectionForm.js +104 -17
  391. package/dist/features/shell/build-sections.d.ts +23 -0
  392. package/dist/features/shell/build-sections.js +106 -8
  393. package/dist/features/shell/field-ui-meta.d.ts +44 -0
  394. package/dist/features/shell/field-ui-meta.js +14 -7
  395. package/dist/features/shell/form-sections.d.ts +46 -0
  396. package/dist/features/shell/form-sections.js +114 -0
  397. package/dist/features/shipments/components/AdminShipmentEditorView.js +87 -64
  398. package/dist/features/shipments/schemas/validation.d.ts +2 -2
  399. package/dist/features/shipments/schemas/validation.js +44 -13
  400. package/dist/features/store-extensions/schemas/custom-role-form.js +6 -2
  401. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +7 -7
  402. package/dist/features/store-extensions/schemas/payout-method-form.js +14 -0
  403. package/dist/features/stores/actions/store-query-actions.js +3 -2
  404. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -1
  405. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -1
  406. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  407. package/dist/features/stores/components/StoreDetailLayoutView.js +12 -3
  408. package/dist/features/support/repository/support.repository.d.ts +21 -0
  409. package/dist/features/support/repository/support.repository.js +63 -0
  410. package/dist/features/support/schemas/firestore.d.ts +27 -2
  411. package/dist/features/support/schemas/firestore.js +2 -0
  412. package/dist/features/support/schemas/ticket-create-form.js +7 -0
  413. package/dist/features/tester/schemas/checklist-item-form.d.ts +43 -0
  414. package/dist/features/tester/schemas/checklist-item-form.js +109 -0
  415. package/dist/features/tester/seed-data/blog-tester-seed-data.js +2 -2
  416. package/dist/features/tester/seed-data/categories-tester-seed-data.js +2 -2
  417. package/dist/features/tester/seed-data/events-tester-seed-data.js +5 -5
  418. package/dist/features/tester/seed-data/orders-tester-seed-data.js +2 -2
  419. package/dist/features/tester/seed-data/products-tester-seed-data.js +48 -49
  420. package/dist/features/tester/seed-data/stores-tester-seed-data.js +3 -3
  421. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +291 -30
  422. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +51 -14
  423. package/dist/features/wishlist/hooks/useWishlistToggle.js +8 -1
  424. package/dist/http/api-handler.js +2 -1
  425. package/dist/index.d.ts +25 -104
  426. package/dist/index.js +38 -143
  427. package/dist/jobs.d.ts +1 -1
  428. package/dist/jobs.js +1 -1
  429. package/dist/monitoring/browser.d.ts +0 -2
  430. package/dist/monitoring/browser.js +12 -1
  431. package/dist/monitoring/index.d.ts +0 -2
  432. package/dist/monitoring/index.js +0 -1
  433. package/dist/next/api/routeHandler.js +9 -4
  434. package/dist/next/index.d.ts +1 -2
  435. package/dist/next/index.js +0 -1
  436. package/dist/next/middleware/index.d.ts +0 -2
  437. package/dist/next/middleware/index.js +0 -1
  438. package/dist/next/routing/route-map.d.ts +8 -7
  439. package/dist/next/routing/route-map.js +10 -3
  440. package/dist/providers/auth-firebase/session.js +3 -1
  441. package/dist/providers/db-firebase/admin-app-lite.js +8 -8
  442. package/dist/providers/db-firebase/admin.js +27 -13
  443. package/dist/providers/db-firebase/browser-stub.d.ts +1 -11
  444. package/dist/providers/db-firebase/browser-stub.js +6 -11
  445. package/dist/providers/db-firebase/index.d.ts +0 -1
  446. package/dist/providers/db-firebase/index.js +0 -1
  447. package/dist/providers/db-firebase/rtdb-paths.d.ts +15 -6
  448. package/dist/providers/db-firebase/rtdb-paths.js +15 -6
  449. package/dist/providers/db-firebase/rtdb-url.d.ts +27 -0
  450. package/dist/providers/db-firebase/rtdb-url.js +50 -0
  451. package/dist/providers/db-firebase/sieve.d.ts +22 -0
  452. package/dist/providers/firebase-client/realtime.d.ts +20 -0
  453. package/dist/providers/firebase-client/realtime.js +34 -1
  454. package/dist/providers.d.ts +1 -1
  455. package/dist/providers.js +1 -1
  456. package/dist/react/hooks/use-action-dispatch.js +8 -2
  457. package/dist/react/hooks/useFormStatePreservation.js +3 -1
  458. package/dist/react/hooks/useListingTypeFlags.d.ts +1 -1
  459. package/dist/react/hooks/useListingTypeFlags.js +1 -1
  460. package/dist/react/hooks/usePendingFilters.js +5 -3
  461. package/dist/react/hooks/usePendingTable.js +15 -3
  462. package/dist/react/hooks/useRealtimeEvent.js +20 -9
  463. package/dist/repositories/index.d.ts +0 -1
  464. package/dist/repositories/index.js +0 -1
  465. package/dist/schemas/registry.d.ts +197 -232
  466. package/dist/schemas/registry.js +5 -6
  467. package/dist/schemas/webhooks/razorpay.d.ts +50 -50
  468. package/dist/security/authorization.d.ts +9 -0
  469. package/dist/security/authorization.js +16 -2
  470. package/dist/security/browser.d.ts +1 -3
  471. package/dist/security/browser.js +5 -2
  472. package/dist/security/index.d.ts +1 -3
  473. package/dist/security/index.js +19 -2
  474. package/dist/security/pii-encrypt.js +16 -0
  475. package/dist/security/pii-schemas.d.ts +0 -14
  476. package/dist/security/pii-schemas.js +7 -15
  477. package/dist/seed/_helpers/category-forest.js +2 -2
  478. package/dist/seed/_helpers/media.d.ts +19 -0
  479. package/dist/seed/_helpers/media.js +75 -0
  480. package/dist/seed/blog-posts-seed-data.js +17 -17
  481. package/dist/seed/carousel-slides-seed-data.js +7 -7
  482. package/dist/seed/cart-seed-data.js +13 -13
  483. package/dist/seed/categories-seed-data.js +10 -10
  484. package/dist/seed/events-seed-data.js +24 -24
  485. package/dist/seed/factories/product.factory.js +4 -4
  486. package/dist/seed/factories/store.factory.js +3 -3
  487. package/dist/seed/factories/user.factory.js +2 -2
  488. package/dist/seed/grouped-listings-seed-data.js +11 -11
  489. package/dist/seed/homepage-sections-seed-data.js +2 -2
  490. package/dist/seed/index.d.ts +0 -1
  491. package/dist/seed/index.js +0 -1
  492. package/dist/seed/manifest.d.ts +1 -1
  493. package/dist/seed/manifest.js +0 -5
  494. package/dist/seed/notifications-seed-data.js +20 -1
  495. package/dist/seed/orders-seed-data.js +2 -2
  496. package/dist/seed/products-art-seed-data.js +16 -16
  497. package/dist/seed/products-auctions-seed-data.js +34 -34
  498. package/dist/seed/products-classifieds-seed-data.js +35 -37
  499. package/dist/seed/products-digital-codes-seed-data.js +20 -20
  500. package/dist/seed/products-live-items-seed-data.js +11 -11
  501. package/dist/seed/products-preorders-seed-data.js +13 -13
  502. package/dist/seed/products-prize-draws-seed-data.js +43 -43
  503. package/dist/seed/products-standard-seed-data.js +54 -54
  504. package/dist/seed/products-stickers-seed-data.js +15 -15
  505. package/dist/seed/reviews-seed-data.js +4 -4
  506. package/dist/seed/scammers-seed-data.js +3 -3
  507. package/dist/seed/site-settings-seed-data.js +11 -24
  508. package/dist/seed/store-extensions-seed-data.js +10 -10
  509. package/dist/seed/stores-seed-data.js +11 -11
  510. package/dist/seed/support-tickets-seed-data.d.ts +14 -0
  511. package/dist/seed/support-tickets-seed-data.js +20 -1
  512. package/dist/seed/users-seed-data.js +20 -20
  513. package/dist/server-entry.d.ts +0 -1
  514. package/dist/server-entry.js +0 -1
  515. package/dist/server.d.ts +9 -6
  516. package/dist/server.js +7 -13
  517. package/dist/styles.css +248 -68
  518. package/dist/tailwind-utilities.css +1 -1
  519. package/dist/tokens/themes/default-dark.js +2 -2
  520. package/dist/tokens/themes/default-light.js +2 -2
  521. package/dist/tokens/tokens.css +24 -4
  522. package/dist/ui/components/ActionRow.d.ts +50 -0
  523. package/dist/ui/components/ActionRow.js +53 -0
  524. package/dist/ui/components/ActionRow.style.css +145 -0
  525. package/dist/ui/components/Drawer.d.ts +10 -0
  526. package/dist/ui/components/Drawer.js +2 -1
  527. package/dist/ui/components/FilterDrawer.js +4 -1
  528. package/dist/ui/components/FilterDrawer.style.css +6 -12
  529. package/dist/ui/components/FormActionBar.js +14 -1
  530. package/dist/ui/components/FormActionBar.style.css +12 -11
  531. package/dist/ui/components/ListingLayout.js +8 -1
  532. package/dist/ui/components/ListingLayout.style.css +6 -13
  533. package/dist/ui/components/Modal.d.ts +15 -1
  534. package/dist/ui/components/Modal.js +17 -3
  535. package/dist/ui/components/QuickCreateModal.js +2 -2
  536. package/dist/ui/components/QuickCreateModal.style.css +78 -84
  537. package/dist/ui/components/RecordDetailModal.js +2 -2
  538. package/dist/ui/components/SideDrawer.d.ts +8 -0
  539. package/dist/ui/components/SideDrawer.js +2 -1
  540. package/dist/ui/components/SideDrawer.style.css +6 -3
  541. package/dist/ui/components/SideModal.d.ts +11 -1
  542. package/dist/ui/components/SideModal.js +3 -2
  543. package/dist/ui/components/SideModal.style.css +14 -0
  544. package/dist/ui/components/Typography.style.css +33 -24
  545. package/dist/ui/components/index.style.css +1 -0
  546. package/dist/ui/components/toolbar-collapse.js +1 -2
  547. package/dist/ui/forms/FormShell.style.css +260 -311
  548. package/dist/ui/index.d.ts +2 -0
  549. package/dist/ui/index.js +1 -0
  550. package/dist/utils/index.d.ts +0 -1
  551. package/dist/utils/index.js +0 -1
  552. package/dist/validation/index.d.ts +1 -1
  553. package/dist/validation/index.js +1 -1
  554. package/dist/validation/schemas.d.ts +0 -19
  555. package/dist/validation/schemas.js +8 -19
  556. package/package.json +1 -1
  557. package/scripts/seed-cli.mjs +3 -6
@@ -0,0 +1,129 @@
1
+ /*
2
+ * WHY: A postal code was validated by **fifteen** different rules, and they
3
+ * disagreed. Two of them are server-side rules on the SAME entity:
4
+ * `src/actions/address.actions.ts` said `.min(4).max(10)` while
5
+ * `src/validation/request-schemas.ts` said `/^\d{6}$/`. Another accepted
6
+ * 5-or-6 digits. And `src/app/api/admin/addresses/route.ts` used
7
+ * `.min(6).max(6)` — a LENGTH check with no character class, so
8
+ * `"abcdef"` was a valid Indian PIN code as far as it was concerned.
9
+ *
10
+ * Meanwhile the client form said `z.string().min(1)`, so `abc` passed
11
+ * every check the user could see and came back as a server 400 with
12
+ * nothing on the field.
13
+ *
14
+ * The India-only regex was itself a bug in waiting: `country` is a free
15
+ * text field, so a Canadian address was being held to `/^\d{6}$/`.
16
+ *
17
+ * WHAT: One postal rule per country, and the country list that carries it.
18
+ *
19
+ * ## Why this is curated rather than all 250 ISO countries
20
+ *
21
+ * A pattern is only worth having if it is RIGHT. Hand-typing 250 of them from
22
+ * memory produces a table that looks authoritative and quietly rejects real
23
+ * addresses — which is worse than not knowing, because the user cannot
24
+ * override it. So the list covers the countries this marketplace actually
25
+ * ships to and to which its sellers source, and everything else resolves to
26
+ * `null`, which means "accept anything plausible".
27
+ *
28
+ * 🛑 An unknown country must never BLOCK a save. A postal rule exists to catch
29
+ * a typo, not to police the atlas.
30
+ *
31
+ * EXPORTS:
32
+ * COUNTRIES, COUNTRY_CODES, DEFAULT_COUNTRY, type CountryCode,
33
+ * type CountryDef, countryFor, postalPatternFor, isValidPostalCode,
34
+ * postalLabelFor, POSTAL_MIN, POSTAL_MAX
35
+ *
36
+ * @tag domain:geo
37
+ * @tag layer:constants
38
+ * @tag pattern:registry
39
+ * @tag access:isomorphic
40
+ * @tag consumers:address forms,address routes,usePostalLookup
41
+ * @tag sideEffects:none
42
+ */
43
+ /** The permissive bound applied when a country has no pattern. */
44
+ export const POSTAL_MIN = 3;
45
+ export const POSTAL_MAX = 12;
46
+ /**
47
+ * 🛑 Patterns are anchored and case-insensitive where the country's format
48
+ * includes letters. An unanchored pattern would accept a code with trailing
49
+ * junk, which is exactly the class of typo this is meant to catch.
50
+ */
51
+ const COUNTRY_LIST = [
52
+ { code: "IN", name: "India", postalPattern: /^[1-9]\d{5}$/, postalLabel: "PIN code", hasStates: true, dialCode: "91" },
53
+ { code: "US", name: "United States", postalPattern: /^\d{5}(-\d{4})?$/, postalLabel: "ZIP code", hasStates: true, dialCode: "1" },
54
+ { code: "GB", name: "United Kingdom", postalPattern: /^[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}$/i, postalLabel: "Postcode", hasStates: false, dialCode: "44" },
55
+ { code: "CA", name: "Canada", postalPattern: /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i, postalLabel: "Postal code", hasStates: true, dialCode: "1" },
56
+ { code: "AU", name: "Australia", postalPattern: /^\d{4}$/, postalLabel: "Postcode", hasStates: true, dialCode: "61" },
57
+ { code: "NZ", name: "New Zealand", postalPattern: /^\d{4}$/, postalLabel: "Postcode", hasStates: false, dialCode: "64" },
58
+ { code: "SG", name: "Singapore", postalPattern: /^\d{6}$/, postalLabel: "Postal code", hasStates: false, dialCode: "65" },
59
+ { code: "MY", name: "Malaysia", postalPattern: /^\d{5}$/, postalLabel: "Postcode", hasStates: false, dialCode: "60" },
60
+ { code: "JP", name: "Japan", postalPattern: /^\d{3}-?\d{4}$/, postalLabel: "Postal code", hasStates: false, dialCode: "81" },
61
+ { code: "DE", name: "Germany", postalPattern: /^\d{5}$/, postalLabel: "PLZ", hasStates: false, dialCode: "49" },
62
+ { code: "FR", name: "France", postalPattern: /^\d{5}$/, postalLabel: "Code postal", hasStates: false, dialCode: "33" },
63
+ { code: "NL", name: "Netherlands", postalPattern: /^\d{4}\s*[A-Z]{2}$/i, postalLabel: "Postcode", hasStates: false, dialCode: "31" },
64
+ { code: "IT", name: "Italy", postalPattern: /^\d{5}$/, postalLabel: "CAP", hasStates: false, dialCode: "39" },
65
+ { code: "ES", name: "Spain", postalPattern: /^\d{5}$/, postalLabel: "Código postal", hasStates: false, dialCode: "34" },
66
+ { code: "AE", name: "United Arab Emirates", postalPattern: null, postalLabel: "Postal code", hasStates: false, dialCode: "971" },
67
+ { code: "SA", name: "Saudi Arabia", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "966" },
68
+ { code: "LK", name: "Sri Lanka", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "94" },
69
+ { code: "BD", name: "Bangladesh", postalPattern: /^\d{4}$/, postalLabel: "Postal code", hasStates: false, dialCode: "880" },
70
+ { code: "NP", name: "Nepal", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "977" },
71
+ { code: "PK", name: "Pakistan", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "92" },
72
+ { code: "CN", name: "China", postalPattern: /^\d{6}$/, postalLabel: "Postal code", hasStates: false, dialCode: "86" },
73
+ { code: "HK", name: "Hong Kong", postalPattern: null, postalLabel: "Postal code", hasStates: false, dialCode: "852" },
74
+ { code: "TH", name: "Thailand", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "66" },
75
+ { code: "ID", name: "Indonesia", postalPattern: /^\d{5}$/, postalLabel: "Postal code", hasStates: false, dialCode: "62" },
76
+ { code: "PH", name: "Philippines", postalPattern: /^\d{4}$/, postalLabel: "Postal code", hasStates: false, dialCode: "63" },
77
+ { code: "ZA", name: "South Africa", postalPattern: /^\d{4}$/, postalLabel: "Postal code", hasStates: false, dialCode: "27" },
78
+ { code: "BR", name: "Brazil", postalPattern: /^\d{5}-?\d{3}$/, postalLabel: "CEP", hasStates: false, dialCode: "55" },
79
+ { code: "MX", name: "Mexico", postalPattern: /^\d{5}$/, postalLabel: "Código postal", hasStates: false, dialCode: "52" },
80
+ ];
81
+ export const COUNTRIES = Object.fromEntries(COUNTRY_LIST.map((c) => [c.code, c]));
82
+ export const COUNTRY_CODES = COUNTRY_LIST.map((c) => c.code);
83
+ /** Where this marketplace is, and what an address defaults to. */
84
+ export const DEFAULT_COUNTRY = "IN";
85
+ /**
86
+ * Resolve a country by code or by name.
87
+ *
88
+ * By NAME as well, because `AddressDocument.country` is a free-text string
89
+ * today and holds `"India"` on every seeded and user-entered row. A resolver
90
+ * that only understood codes would treat every existing address as an unknown
91
+ * country and silently drop to the permissive rule — the migration would look
92
+ * like it worked and would have switched validation off.
93
+ */
94
+ export function countryFor(value) {
95
+ if (!value)
96
+ return null;
97
+ const trimmed = value.trim();
98
+ if (!trimmed)
99
+ return null;
100
+ const byCode = COUNTRIES[trimmed.toUpperCase()];
101
+ if (byCode)
102
+ return byCode;
103
+ const lower = trimmed.toLowerCase();
104
+ return COUNTRY_LIST.find((c) => c.name.toLowerCase() === lower) ?? null;
105
+ }
106
+ /** The postal pattern for a country, or `null` when none is known. */
107
+ export function postalPatternFor(country) {
108
+ return countryFor(country)?.postalPattern ?? null;
109
+ }
110
+ /** "PIN code" / "ZIP code" / "Postcode" — what to put on the label. */
111
+ export function postalLabelFor(country) {
112
+ return countryFor(country)?.postalLabel ?? "Postal code";
113
+ }
114
+ /**
115
+ * The ONE postal check, used by every form and every route.
116
+ *
117
+ * An empty code is NOT valid — required-ness is the caller's business, but a
118
+ * blank string is never a postal code, and letting it through here is how the
119
+ * `.min(1)` client rule came to disagree with the server in the first place.
120
+ */
121
+ export function isValidPostalCode(country, postalCode) {
122
+ const code = (postalCode ?? "").trim();
123
+ if (!code)
124
+ return false;
125
+ const pattern = postalPatternFor(country);
126
+ if (pattern)
127
+ return pattern.test(code);
128
+ return code.length >= POSTAL_MIN && code.length <= POSTAL_MAX;
129
+ }
@@ -0,0 +1,13 @@
1
+ /** India's 28 states + 8 union territories. */
2
+ declare const INDIA: readonly ["Andhra Pradesh", "Arunachal Pradesh", "Assam", "Bihar", "Chhattisgarh", "Goa", "Gujarat", "Haryana", "Himachal Pradesh", "Jharkhand", "Karnataka", "Kerala", "Madhya Pradesh", "Maharashtra", "Manipur", "Meghalaya", "Mizoram", "Nagaland", "Odisha", "Punjab", "Rajasthan", "Sikkim", "Tamil Nadu", "Telangana", "Tripura", "Uttar Pradesh", "Uttarakhand", "West Bengal", "Andaman and Nicobar Islands", "Chandigarh", "Dadra and Nagar Haveli and Daman and Diu", "Delhi", "Jammu and Kashmir", "Ladakh", "Lakshadweep", "Puducherry"];
3
+ export type IndianState = (typeof INDIA)[number];
4
+ /** Country code → its subdivisions, alphabetical within each. */
5
+ export declare const SUBDIVISIONS: Record<string, readonly string[]>;
6
+ /**
7
+ * The subdivisions for a country, or an empty list when it has none.
8
+ *
9
+ * An empty list is the signal to render a free-text State input rather than a
10
+ * picker — see `hasStates` on the country definition.
11
+ */
12
+ export declare function subdivisionsFor(countryCode: string | undefined | null): readonly string[];
13
+ export {};
@@ -0,0 +1,104 @@
1
+ /*
2
+ * WHY: `INDIAN_STATES` existed and was used by **one** file — the admin
3
+ * address editor — while the user-facing `AddressForm` and
4
+ * `SellerAddressesView` both wrote the same `AddressDocument.state`
5
+ * through a FREE TEXT input. So the same field held "Karnataka",
6
+ * "karnataka", "KA" and "Karnatka" depending on which of the three
7
+ * surfaces created the row, and nothing could group or filter on it.
8
+ * WHAT: Country → subdivisions, for every country whose `hasStates` is true.
9
+ *
10
+ * ## Only what is enumerated
11
+ *
12
+ * A country appears here when `COUNTRIES[code].hasStates` is true, and the two
13
+ * must agree — `audit-address-shape` checks that. A country with `hasStates`
14
+ * and no list would render an empty picker with no way to type a state, which
15
+ * is strictly worse than the free-text box this replaces.
16
+ *
17
+ * EXPORTS: SUBDIVISIONS, subdivisionsFor, type IndianState
18
+ *
19
+ * @tag domain:geo
20
+ * @tag layer:constants
21
+ * @tag pattern:registry
22
+ * @tag access:isomorphic
23
+ * @tag consumers:address forms
24
+ * @tag sideEffects:none
25
+ */
26
+ /** India's 28 states + 8 union territories. */
27
+ const INDIA = [
28
+ "Andhra Pradesh",
29
+ "Arunachal Pradesh",
30
+ "Assam",
31
+ "Bihar",
32
+ "Chhattisgarh",
33
+ "Goa",
34
+ "Gujarat",
35
+ "Haryana",
36
+ "Himachal Pradesh",
37
+ "Jharkhand",
38
+ "Karnataka",
39
+ "Kerala",
40
+ "Madhya Pradesh",
41
+ "Maharashtra",
42
+ "Manipur",
43
+ "Meghalaya",
44
+ "Mizoram",
45
+ "Nagaland",
46
+ "Odisha",
47
+ "Punjab",
48
+ "Rajasthan",
49
+ "Sikkim",
50
+ "Tamil Nadu",
51
+ "Telangana",
52
+ "Tripura",
53
+ "Uttar Pradesh",
54
+ "Uttarakhand",
55
+ "West Bengal",
56
+ "Andaman and Nicobar Islands",
57
+ "Chandigarh",
58
+ "Dadra and Nagar Haveli and Daman and Diu",
59
+ "Delhi",
60
+ "Jammu and Kashmir",
61
+ "Ladakh",
62
+ "Lakshadweep",
63
+ "Puducherry",
64
+ ];
65
+ const US = [
66
+ "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
67
+ "Connecticut", "Delaware", "District of Columbia", "Florida", "Georgia",
68
+ "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
69
+ "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
70
+ "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
71
+ "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota",
72
+ "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
73
+ "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
74
+ "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming",
75
+ ];
76
+ const CA = [
77
+ "Alberta", "British Columbia", "Manitoba", "New Brunswick",
78
+ "Newfoundland and Labrador", "Northwest Territories", "Nova Scotia",
79
+ "Nunavut", "Ontario", "Prince Edward Island", "Quebec", "Saskatchewan",
80
+ "Yukon",
81
+ ];
82
+ const AU = [
83
+ "Australian Capital Territory", "New South Wales", "Northern Territory",
84
+ "Queensland", "South Australia", "Tasmania", "Victoria",
85
+ "Western Australia",
86
+ ];
87
+ /** Country code → its subdivisions, alphabetical within each. */
88
+ export const SUBDIVISIONS = {
89
+ IN: INDIA,
90
+ US,
91
+ CA,
92
+ AU,
93
+ };
94
+ /**
95
+ * The subdivisions for a country, or an empty list when it has none.
96
+ *
97
+ * An empty list is the signal to render a free-text State input rather than a
98
+ * picker — see `hasStates` on the country definition.
99
+ */
100
+ export function subdivisionsFor(countryCode) {
101
+ if (!countryCode)
102
+ return [];
103
+ return SUBDIVISIONS[countryCode.trim().toUpperCase()] ?? [];
104
+ }
@@ -9,7 +9,7 @@
9
9
  * import { COLLECTION_CACHE_PATHS } from "@mohasinac/appkit/constants";
10
10
  * import { resolveEndpoint } from "@mohasinac/appkit/constants";
11
11
  */
12
- export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDPOINTS, NOTIFICATIONS_ENDPOINTS, SITE_SETTINGS_ENDPOINTS, ADMIN_ENDPOINTS, CHAT_ENDPOINTS, AUCTION_ENDPOINTS, BID_ENDPOINTS, CART_ENDPOINTS, CATEGORY_ENDPOINTS, CHECKOUT_ENDPOINTS, PAYMENT_ENDPOINTS, COLLECTION_ENDPOINTS, CONSULTATION_ENDPOINTS, COPILOT_ENDPOINTS, CORPORATE_ENDPOINTS, EVENT_ENDPOINTS, FAQ_ENDPOINTS, HOMEPAGE_ENDPOINTS, LOYALTY_ENDPOINTS, ANALYTICS_ENDPOINTS, MEDIA_ENDPOINTS, ORDER_ENDPOINTS, PREORDER_ENDPOINTS, PRODUCT_ENDPOINTS, PROMOTION_ENDPOINTS, REVIEW_ENDPOINTS, SEARCH_ENDPOINTS, SELLER_ENDPOINTS, BLOG_ENDPOINTS, STORE_ENDPOINTS, WISHLIST_ENDPOINTS, PROFILE_STATS_ENDPOINTS, } from "./api-endpoints";
12
+ export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDPOINTS, NOTIFICATIONS_ENDPOINTS, SITE_SETTINGS_ENDPOINTS, ADMIN_ENDPOINTS, AUCTION_ENDPOINTS, BID_ENDPOINTS, CART_ENDPOINTS, CATEGORY_ENDPOINTS, CHECKOUT_ENDPOINTS, PAYMENT_ENDPOINTS, COLLECTION_ENDPOINTS, CONSULTATION_ENDPOINTS, COPILOT_ENDPOINTS, CORPORATE_ENDPOINTS, EVENT_ENDPOINTS, FAQ_ENDPOINTS, HOMEPAGE_ENDPOINTS, LOYALTY_ENDPOINTS, ANALYTICS_ENDPOINTS, MEDIA_ENDPOINTS, ORDER_ENDPOINTS, PREORDER_ENDPOINTS, PRODUCT_ENDPOINTS, PROMOTION_ENDPOINTS, REVIEW_ENDPOINTS, SEARCH_ENDPOINTS, SELLER_ENDPOINTS, BLOG_ENDPOINTS, STORE_ENDPOINTS, WISHLIST_ENDPOINTS, PROFILE_STATS_ENDPOINTS, } from "./api-endpoints";
13
13
  export { COLLECTION_CACHE_PATHS } from "./cache-invalidation";
14
14
  export { PAGE_SIZES, MAX_PAGE_SIZE, FEATURED_LIMITS, SITEMAP_LIMITS, } from "./pagination-presets";
15
15
  export type { PageSizeKey } from "./pagination-presets";
@@ -18,6 +18,6 @@ export type { NotificationType } from "./notification-types";
18
18
  export { resolveEndpoint, resolveEndpointFn } from "./api-endpoint-resolver";
19
19
  export { ROUTES, PUBLIC_ROUTES, PROTECTED_ROUTES, AUTH_ROUTES } from "../next/routing/route-map";
20
20
  export { WISHLIST_MAX, HISTORY_MAX, CART_MAX_ITEMS, WISHLIST_DOC_ID, HISTORY_DOC_ID, WISHLIST_COLLECTION, HISTORY_COLLECTION, } from "./limits";
21
- export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./field-names";
21
+ export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./field-names";
22
22
  export { SELLER_LISTING_TABS, type SellerListingTabId, } from "../features/products/constants/listing-tabs";
23
23
  export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "../features/admin/constants/filter-tabs";
@@ -9,7 +9,7 @@
9
9
  * import { COLLECTION_CACHE_PATHS } from "@mohasinac/appkit/constants";
10
10
  * import { resolveEndpoint } from "@mohasinac/appkit/constants";
11
11
  */
12
- export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDPOINTS, NOTIFICATIONS_ENDPOINTS, SITE_SETTINGS_ENDPOINTS, ADMIN_ENDPOINTS, CHAT_ENDPOINTS, AUCTION_ENDPOINTS, BID_ENDPOINTS, CART_ENDPOINTS, CATEGORY_ENDPOINTS, CHECKOUT_ENDPOINTS, PAYMENT_ENDPOINTS, COLLECTION_ENDPOINTS, CONSULTATION_ENDPOINTS, COPILOT_ENDPOINTS, CORPORATE_ENDPOINTS, EVENT_ENDPOINTS, FAQ_ENDPOINTS, HOMEPAGE_ENDPOINTS, LOYALTY_ENDPOINTS, ANALYTICS_ENDPOINTS, MEDIA_ENDPOINTS, ORDER_ENDPOINTS, PREORDER_ENDPOINTS, PRODUCT_ENDPOINTS, PROMOTION_ENDPOINTS, REVIEW_ENDPOINTS, SEARCH_ENDPOINTS, SELLER_ENDPOINTS, BLOG_ENDPOINTS, STORE_ENDPOINTS, WISHLIST_ENDPOINTS, PROFILE_STATS_ENDPOINTS, } from "./api-endpoints";
12
+ export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDPOINTS, NOTIFICATIONS_ENDPOINTS, SITE_SETTINGS_ENDPOINTS, ADMIN_ENDPOINTS, AUCTION_ENDPOINTS, BID_ENDPOINTS, CART_ENDPOINTS, CATEGORY_ENDPOINTS, CHECKOUT_ENDPOINTS, PAYMENT_ENDPOINTS, COLLECTION_ENDPOINTS, CONSULTATION_ENDPOINTS, COPILOT_ENDPOINTS, CORPORATE_ENDPOINTS, EVENT_ENDPOINTS, FAQ_ENDPOINTS, HOMEPAGE_ENDPOINTS, LOYALTY_ENDPOINTS, ANALYTICS_ENDPOINTS, MEDIA_ENDPOINTS, ORDER_ENDPOINTS, PREORDER_ENDPOINTS, PRODUCT_ENDPOINTS, PROMOTION_ENDPOINTS, REVIEW_ENDPOINTS, SEARCH_ENDPOINTS, SELLER_ENDPOINTS, BLOG_ENDPOINTS, STORE_ENDPOINTS, WISHLIST_ENDPOINTS, PROFILE_STATS_ENDPOINTS, } from "./api-endpoints";
13
13
  export { COLLECTION_CACHE_PATHS } from "./cache-invalidation";
14
14
  export { PAGE_SIZES, MAX_PAGE_SIZE, FEATURED_LIMITS, SITEMAP_LIMITS, } from "./pagination-presets";
15
15
  export { NOTIFICATION_TYPES, NOTIFICATION_TYPE_TABS, } from "./notification-types";
@@ -21,7 +21,7 @@ export { WISHLIST_MAX, HISTORY_MAX, CART_MAX_ITEMS, WISHLIST_DOC_ID, HISTORY_DOC
21
21
  // derived objects (e.g. Object.values(...) for a Zod enum) at module-eval
22
22
  // time, which needs a small, synchronously-resolvable subpath rather than
23
23
  // the much larger client.ts barrel.
24
- export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./field-names";
24
+ export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./field-names";
25
25
  // Dashboard filter-tab sets — same rationale as the field-name maps above.
26
26
  export { SELLER_LISTING_TABS, } from "../features/products/constants/listing-tabs";
27
27
  export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "../features/admin/constants/filter-tabs";
@@ -68,6 +68,30 @@ export declare const TABLE_KEYS: {
68
68
  readonly LIVE_TRANSPORT_METHOD: "liveTransportMethod";
69
69
  };
70
70
  export type TableKey = (typeof TABLE_KEYS)[keyof typeof TABLE_KEYS];
71
+ /**
72
+ * The one delimiter joining several values of ONE filter key in a URL.
73
+ *
74
+ * 🛑 `"|"`, never `","`. sievejs reads same-field `|` as an OR-group, which the
75
+ * Firestore adapter upgrades to an `in` query. A comma is a clause SEPARATOR —
76
+ * `condition==new,condition==used` is an AND of two equalities on one field and
77
+ * can never match a document.
78
+ *
79
+ * Two filter systems disagreed on this. `ProductFilters` and the 11 sites like
80
+ * it wrote `vals.join("|")`; `usePendingFilters` and `FilterPanel` split and
81
+ * joined on `","` for the SAME URL keys. Nothing broke visibly, because a
82
+ * pipe-joined string survives a comma split as a single element and round-trips
83
+ * intact — but it counts as ONE, so the active-filter badge reported 1 for a
84
+ * three-category selection, and `usePendingTable.get`'s `[0]` returned the
85
+ * whole `"a|b|c"` string and appeared correct for the same wrong reason.
86
+ *
87
+ * Split and join through the two helpers below rather than inlining either
88
+ * character; that is what keeps the count, the wire format and Sieve agreeing.
89
+ */
90
+ export declare const FILTER_VALUE_DELIMITER = "|";
91
+ /** Parse a multi-value filter param. Empty string → no values, never `[""]`. */
92
+ export declare function splitFilterValues(raw: string | null | undefined): string[];
93
+ /** Serialise a multi-value filter param for the URL. */
94
+ export declare function joinFilterValues(values: readonly string[]): string;
71
95
  export declare const VIEW_MODE: {
72
96
  readonly GRID: "grid";
73
97
  readonly LIST: "list";
@@ -70,6 +70,34 @@ export const TABLE_KEYS = {
70
70
  LIVE_SEX: "liveSex",
71
71
  LIVE_TRANSPORT_METHOD: "liveTransportMethod",
72
72
  };
73
+ /**
74
+ * The one delimiter joining several values of ONE filter key in a URL.
75
+ *
76
+ * 🛑 `"|"`, never `","`. sievejs reads same-field `|` as an OR-group, which the
77
+ * Firestore adapter upgrades to an `in` query. A comma is a clause SEPARATOR —
78
+ * `condition==new,condition==used` is an AND of two equalities on one field and
79
+ * can never match a document.
80
+ *
81
+ * Two filter systems disagreed on this. `ProductFilters` and the 11 sites like
82
+ * it wrote `vals.join("|")`; `usePendingFilters` and `FilterPanel` split and
83
+ * joined on `","` for the SAME URL keys. Nothing broke visibly, because a
84
+ * pipe-joined string survives a comma split as a single element and round-trips
85
+ * intact — but it counts as ONE, so the active-filter badge reported 1 for a
86
+ * three-category selection, and `usePendingTable.get`'s `[0]` returned the
87
+ * whole `"a|b|c"` string and appeared correct for the same wrong reason.
88
+ *
89
+ * Split and join through the two helpers below rather than inlining either
90
+ * character; that is what keeps the count, the wire format and Sieve agreeing.
91
+ */
92
+ export const FILTER_VALUE_DELIMITER = "|";
93
+ /** Parse a multi-value filter param. Empty string → no values, never `[""]`. */
94
+ export function splitFilterValues(raw) {
95
+ return raw ? raw.split(FILTER_VALUE_DELIMITER).filter(Boolean) : [];
96
+ }
97
+ /** Serialise a multi-value filter param for the URL. */
98
+ export function joinFilterValues(values) {
99
+ return values.filter(Boolean).join(FILTER_VALUE_DELIMITER);
100
+ }
73
101
  export const VIEW_MODE = {
74
102
  GRID: "grid",
75
103
  LIST: "list",
@@ -13,6 +13,12 @@ export interface RealtimeSnapshot {
13
13
  /** Unsubscribe function returned by subscribe */
14
14
  export type Unsubscribe = () => void;
15
15
  export interface IClientRealtimeProvider {
16
+ /**
17
+ * A provider on its own Firebase app for this claim scope, so concurrent
18
+ * channels do not overwrite each other's auth. Optional: a provider that
19
+ * cannot isolate returns itself, keeping the old shared-app behaviour.
20
+ */
21
+ forScope?(scope: string): IClientRealtimeProvider;
16
22
  /** Authenticate the realtime connection with a custom token */
17
23
  signInWithToken(token: string): Promise<void>;
18
24
  /** Sign out of the realtime connection */
@@ -52,15 +52,6 @@ export interface WithTransformOpts<Base, Target extends Base = Base> {
52
52
  * Convenience helper: build a response type for list endpoints that mirrors
53
53
  * the package's standard list-response shape but with a generic item type.
54
54
  */
55
- export interface GenericListResponse<T> {
56
- items: T[];
57
- total: number;
58
- page: number;
59
- pageSize?: number;
60
- perPage?: number;
61
- totalPages: number;
62
- hasMore?: boolean;
63
- }
64
55
  /**
65
56
  * A single column definition for data tables.
66
57
  * Defined here in contracts so feat-* packages can export default column sets
@@ -17,7 +17,7 @@ export type { ExtraFormField, ExtraFieldRenderArgs } from "./form";
17
17
  export { registerFormFields, resolveFormFields, removeFormFields, _resetFormFields, } from "./form";
18
18
  export type { RouteStub, ApiRouteStub, FeatureManifest, FeaturesConfig, } from "./feature";
19
19
  export type { SiteConfig, NavItem } from "./config";
20
- export type { WithTransformOpts, GenericListResponse, TableColumn, ColumnPriority, ColumnExtensionOpts, LayoutSlots, FeatureExtension, } from "./extend";
20
+ export type { WithTransformOpts, TableColumn, ColumnPriority, ColumnExtensionOpts, LayoutSlots, FeatureExtension, } from "./extend";
21
21
  export { COLUMN_PRIORITY_CLASS, COLUMN_PRIORITY_CLASS_BLOCK } from "./extend";
22
22
  export type { PaginationConfig, StickyConfig, TableConfig, TableViewMode, } from "./table";
23
23
  export { DEFAULT_PAGINATION_CONFIG, DEFAULT_STICKY_CONFIG, DEFAULT_TABLE_CONFIG, mergeTableConfig, } from "./table";
@@ -1,3 +1,4 @@
1
+ import { type IClientRealtimeProvider } from "./client-realtime";
1
2
  export interface RealtimeToken {
2
3
  customToken: string;
3
4
  expiresAt: number;
@@ -12,16 +13,15 @@ export interface RealtimeToken {
12
13
  * @returns a release function. **Always call it** — the session is only torn
13
14
  * down when every lease is released.
14
15
  */
15
- export declare function acquireRealtimeSession(scope: string, getToken: () => Promise<RealtimeToken>): Promise<() => void>;
16
- /**
17
- * Take a lease WITHOUT signing in — for a consumer that manages its own
18
- * sign-in but must still participate in the reference count.
19
- *
20
- * `useRealtimeEvent` is the case: its token carries a job-scoped `bulkJobId`
21
- * claim it receives from the caller, so it cannot use `acquireRealtimeSession`'s
22
- * fetcher. It still must not be able to sign the shared app out from under
23
- * another channel, which is precisely what its `cleanup()` used to do.
24
- */
25
- export declare function acquireExternalRealtimeLease(): () => void;
26
- /** Test/diagnostic only. */
16
+ export interface RealtimeLease {
17
+ /**
18
+ * Subscribe through THIS provider, not the global one — it is bound to the
19
+ * app this scope signed in on. Using the global provider would read from an
20
+ * app with someone else's claims.
21
+ */
22
+ provider: IClientRealtimeProvider;
23
+ release: () => void;
24
+ }
25
+ export declare function acquireRealtimeSession(scope: string, getToken: () => Promise<RealtimeToken>): Promise<RealtimeLease>;
26
+ /** Test/diagnostic only — total leases across every scope. */
27
27
  export declare function activeRealtimeLeases(): number;
@@ -1,10 +1,21 @@
1
1
  import { normalizeError } from "../errors/normalize";
2
- import { getClientRealtimeProvider } from "./client-realtime";
2
+ import { getClientRealtimeProvider, } from "./client-realtime";
3
3
  /**
4
- * Shared, REFERENCE-COUNTED sign-in for the one client realtime app.
4
+ * PER-SCOPE, reference-counted sign-in for the client realtime channels.
5
+ *
6
+ * Each claim scope gets its own Firebase app (via `provider.forScope`), because
7
+ * Firebase Auth state is per-app and two channels legitimately need two
8
+ * different claim sets at the same time.
5
9
  *
6
10
  * WHY THIS EXISTS — two distinct bugs, one cause.
7
11
  *
12
+ * 🛑 Both examples below are HISTORICAL: buyer↔seller messaging was deleted
13
+ * 2026-08-31, so `useConversation` / `useConversations` / `useChat` and the
14
+ * `chats/*` and `chat/*` RTDB paths no longer exist — don't go looking for
15
+ * them. The mechanism is not historical. `auth_events`, `payment_events` and
16
+ * `bulk_events` are all still live, still concurrent, and still each need their
17
+ * own claim scope, which is the whole reason this file is here.
18
+ *
8
19
  * 1. **Nobody signed in for messaging.** `useConversation` and
9
20
  * `useConversations` subscribed to `chats/...` without ever calling
10
21
  * `signInWithToken`, so `auth == null` and both RTDB rules evaluated false.
@@ -21,98 +32,89 @@ import { getClientRealtimeProvider } from "./client-realtime";
21
32
  * bulk token (carrying `bulkJobId`), killing an in-flight job subscription.
22
33
  * Whoever finished last broke whoever was still working.
23
34
  *
24
- * The fix for (2) is not "sign out more carefully" — it is that **no individual
25
- * consumer may decide to sign out at all**. Each acquires a lease and releases
26
- * it; the session ends only when the last lease is gone.
35
+ * (2) needed BOTH halves, and only one was done at first:
36
+ * - sign-OUT: no consumer may decide to sign out. Each takes a lease; the
37
+ * session ends only when the last lease for that scope is gone.
38
+ * - sign-IN: ref-counting cannot help here, because nothing is being shared
39
+ * by agreement — a bulk job and a message thread need different claims
40
+ * simultaneously. The answer is separate apps, not coordination.
27
41
  *
28
- * Tokens differ per channel (different claims), so `acquire` takes a fetcher and
29
- * re-signs when the token it holds is for a different scope or has expired.
42
+ * 🛑 Subscribe through `lease.provider`, never `getClientRealtimeProvider()`.
43
+ * The global one is the root app; the lease's is the app your scope actually
44
+ * authenticated on.
30
45
  */
31
46
  /** Refresh a little early — a token that expires mid-subscription is a silent drop. */
32
47
  const EXPIRY_SKEW_MS = 60000;
33
- let leases = 0;
34
- let currentScope = null;
35
- let expiresAt = 0;
36
- let inFlight = null;
37
48
  /**
38
- * Ensure the shared realtime app is signed in for `scope`, and take a lease.
49
+ * One entry per claim scope, each on its OWN Firebase app.
39
50
  *
40
- * @param scope an identifier for the claim set (e.g. `"messages"`,
41
- * `"chat:<id>"`). Signing in again for the SAME scope while a
42
- * valid token is held is a no-op.
43
- * @param getToken fetches a fresh custom token. Called only when needed.
44
- * @returns a release function. **Always call it** — the session is only torn
45
- * down when every lease is released.
51
+ * 🛑 This used to be three module-level singletons — `currentScope`,
52
+ * `expiresAt`, `leases` — describing ONE shared app. That shape could not
53
+ * express the real situation: two channels legitimately need two different
54
+ * claim sets at the same time, and Firebase Auth state is per-app, so every
55
+ * sign-in replaced the previous one's claims. Ref-counting only stopped a
56
+ * finishing channel from signing the others OUT; it could not stop a starting
57
+ * channel from signing itself IN over them.
46
58
  */
59
+ const scopes = new Map();
47
60
  export async function acquireRealtimeSession(scope, getToken) {
48
- const lease = { scope };
49
- leases++;
50
- const needsSignIn = currentScope !== lease.scope || Date.now() > expiresAt - EXPIRY_SKEW_MS;
51
- if (needsSignIn) {
52
- // Collapse concurrent acquires — several hooks mount in the same tick and
53
- // would otherwise each fetch a token and race to sign in.
54
- inFlight ?? (inFlight = (async () => {
61
+ const root = getClientRealtimeProvider();
62
+ let state = scopes.get(scope);
63
+ if (!state) {
64
+ // `forScope` is optional on the contract: a provider that cannot isolate
65
+ // falls back to the shared app, which is the old behaviour rather than a
66
+ // crash.
67
+ state = {
68
+ leases: 0,
69
+ expiresAt: 0,
70
+ inFlight: null,
71
+ provider: root.forScope?.(scope) ?? root,
72
+ };
73
+ scopes.set(scope, state);
74
+ }
75
+ state.leases++;
76
+ if (Date.now() > state.expiresAt - EXPIRY_SKEW_MS) {
77
+ // Collapse concurrent acquires for the SAME scope — several hooks mount in
78
+ // one tick and would otherwise each fetch a token and race to sign in.
79
+ state.inFlight ?? (state.inFlight = (async () => {
55
80
  try {
56
81
  const token = await getToken();
57
- await getClientRealtimeProvider().signInWithToken(token.customToken);
58
- currentScope = lease.scope;
59
- expiresAt = token.expiresAt;
82
+ await state.provider.signInWithToken(token.customToken);
83
+ state.expiresAt = token.expiresAt;
60
84
  }
61
85
  finally {
62
- inFlight = null;
86
+ state.inFlight = null;
63
87
  }
64
88
  })());
65
- await inFlight;
89
+ await state.inFlight;
66
90
  }
67
91
  let released = false;
68
- return () => {
69
- if (released)
70
- return; // React StrictMode double-invokes cleanups
71
- released = true;
72
- leases = Math.max(0, leases - 1);
73
- if (leases > 0)
74
- return;
75
- currentScope = null;
76
- expiresAt = 0;
77
- getClientRealtimeProvider()
78
- .signOut()
79
- .catch((err) => {
80
- void normalizeError(err);
81
- });
82
- };
83
- }
84
- /**
85
- * Take a lease WITHOUT signing in — for a consumer that manages its own
86
- * sign-in but must still participate in the reference count.
87
- *
88
- * `useRealtimeEvent` is the case: its token carries a job-scoped `bulkJobId`
89
- * claim it receives from the caller, so it cannot use `acquireRealtimeSession`'s
90
- * fetcher. It still must not be able to sign the shared app out from under
91
- * another channel, which is precisely what its `cleanup()` used to do.
92
- */
93
- export function acquireExternalRealtimeLease() {
94
- leases++;
95
- // Its own sign-in has replaced whatever scope was active; forget the cached
96
- // one so the next acquire() re-authenticates rather than trusting a token
97
- // that is no longer installed.
98
- currentScope = null;
99
- expiresAt = 0;
100
- let released = false;
101
- return () => {
102
- if (released)
103
- return;
104
- released = true;
105
- leases = Math.max(0, leases - 1);
106
- if (leases > 0)
107
- return;
108
- getClientRealtimeProvider()
109
- .signOut()
110
- .catch((err) => {
111
- void normalizeError(err);
112
- });
92
+ return {
93
+ provider: state.provider,
94
+ release: () => {
95
+ if (released)
96
+ return; // React StrictMode double-invokes cleanups
97
+ released = true;
98
+ const cur = scopes.get(scope);
99
+ if (!cur)
100
+ return;
101
+ cur.leases = Math.max(0, cur.leases - 1);
102
+ if (cur.leases > 0)
103
+ return;
104
+ // Last holder of THIS scope. Signing out touches only this scope's app,
105
+ // so it cannot disturb any other channel.
106
+ cur.expiresAt = 0;
107
+ scopes.delete(scope);
108
+ cur.provider.signOut().catch((err) => {
109
+ void normalizeError(err);
110
+ });
111
+ },
113
112
  };
114
113
  }
115
- /** Test/diagnostic only. */
114
+ /** Test/diagnostic only — total leases across every scope. */
116
115
  export function activeRealtimeLeases() {
117
- return leases;
116
+ let total = 0;
117
+ for (const s of scopes.values())
118
+ total += s.leases;
119
+ return total;
118
120
  }
@@ -8,7 +8,7 @@ export { EventBus, eventBus } from "./EventBus";
8
8
  export type { EventSubscription } from "./EventBus";
9
9
  export { CacheManager, cacheManager } from "./CacheManager";
10
10
  export type { CacheOptions, CacheEntry } from "./CacheManager";
11
- export { SITE_CONFIG, FEATURE_FLAGS, createSiteConfig, resolveSiteConfig, } from "./site-config";
11
+ export { SITE_CONFIG, createSiteConfig, resolveSiteConfig, } from "./site-config";
12
12
  export type { RuntimeSiteConfig } from "./site-config";
13
13
  export { useSiteSettings } from "./hooks/useSiteSettings";
14
14
  export { MUTATION_EVENTS, emitMutation, onMutation, inferMutationEvent, } from "./mutation-events";