@mohasinac/appkit 4.52.5 → 4.53.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 (630) hide show
  1. package/dist/.build-stamp.json +4 -4
  2. package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
  3. package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
  4. package/dist/_internal/server/features/auctions/actions.js +1 -1
  5. package/dist/_internal/server/features/categories/data.js +23 -7
  6. package/dist/_internal/server/features/checkout/actions.js +10 -3
  7. package/dist/_internal/server/features/checkout/data.d.ts +15 -0
  8. package/dist/_internal/server/features/checkout/data.js +20 -3
  9. package/dist/_internal/server/features/lottery/actions.js +9 -1
  10. package/dist/_internal/server/features/lottery/og.d.ts +40 -0
  11. package/dist/_internal/server/features/lottery/og.js +79 -0
  12. package/dist/_internal/server/features/messages/actions.js +4 -0
  13. package/dist/_internal/server/features/offers/adapters.js +17 -3
  14. package/dist/_internal/server/features/orders/actions.js +7 -2
  15. package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
  16. package/dist/_internal/server/features/raffle/actions.js +25 -0
  17. package/dist/_internal/server/features/reviews/actions.js +1 -1
  18. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  19. package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
  20. package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
  21. package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
  22. package/dist/_internal/server/features/search/index-build/build.js +285 -0
  23. package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
  24. package/dist/_internal/server/features/search/index-build/sources.js +385 -0
  25. package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
  26. package/dist/_internal/server/features/search/search-sources.js +142 -7
  27. package/dist/_internal/server/features/seo/robots.js +21 -1
  28. package/dist/_internal/server/features/seo/sitemap.js +1 -1
  29. package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
  30. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  31. package/dist/_internal/server/features/site-settings/adapters.js +26 -0
  32. package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
  33. package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
  34. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
  35. package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
  36. package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
  37. package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
  38. package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
  39. package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
  40. package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
  41. package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
  42. package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
  43. package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
  44. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
  45. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
  46. package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
  47. package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
  48. package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
  49. package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
  50. package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
  51. package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
  52. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
  53. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
  54. package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
  55. package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
  56. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  57. package/dist/_internal/server/functions/scheduled.js +25 -1
  58. package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
  59. package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
  60. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
  61. package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
  62. package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
  63. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
  64. package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
  65. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
  66. package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
  67. package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
  68. package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
  69. package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
  70. package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
  71. package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
  72. package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
  73. package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
  74. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
  75. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
  76. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
  77. package/dist/_internal/server/jobs/core/promotions.js +7 -4
  78. package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
  79. package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
  80. package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
  81. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
  83. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
  84. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
  85. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  86. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  87. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
  88. package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
  89. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
  90. package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
  91. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
  92. package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
  93. package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
  94. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
  95. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
  96. package/dist/_internal/shared/actions/action-registry.js +29 -0
  97. package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
  98. package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
  99. package/dist/_internal/shared/features/events/config.d.ts +14 -0
  100. package/dist/_internal/shared/features/events/config.js +14 -0
  101. package/dist/_internal/shared/features/notifications/action-url.js +8 -0
  102. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  103. package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
  104. package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
  105. package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
  106. package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
  107. package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
  108. package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
  109. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
  110. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
  111. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
  112. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
  113. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
  114. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
  115. package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
  116. package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
  117. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
  118. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
  119. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
  120. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
  121. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
  122. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
  123. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
  124. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
  125. package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
  126. package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
  127. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
  128. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
  129. package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
  130. package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
  131. package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
  132. package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
  133. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
  134. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
  135. package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
  136. package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
  137. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
  138. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
  139. package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
  140. package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
  141. package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
  142. package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
  143. package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
  144. package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
  145. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
  146. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
  147. package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
  148. package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
  149. package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
  150. package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
  151. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
  152. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
  153. package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
  154. package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
  155. package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
  156. package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
  157. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
  158. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
  159. package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
  160. package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
  161. package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
  162. package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
  163. package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
  164. package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
  165. package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
  166. package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
  167. package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
  168. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  169. package/dist/_internal/shared/listing-types/art/config.js +1 -0
  170. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  171. package/dist/_internal/shared/listing-types/auction/config.js +1 -0
  172. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  173. package/dist/_internal/shared/listing-types/classified/config.js +1 -0
  174. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  175. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
  176. package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
  177. package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
  178. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  179. package/dist/_internal/shared/listing-types/live/config.js +1 -0
  180. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  181. package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
  182. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  183. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
  184. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  185. package/dist/_internal/shared/listing-types/standard/config.js +1 -0
  186. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  187. package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
  188. package/dist/_internal/shared/media/limits.d.ts +12 -2
  189. package/dist/_internal/shared/media/limits.js +12 -2
  190. package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
  191. package/dist/_internal/shared/search/artifact-url.js +119 -0
  192. package/dist/_internal/shared/search/index-record.d.ts +68 -0
  193. package/dist/_internal/shared/search/index-record.js +96 -0
  194. package/dist/_internal/shared/search/match.d.ts +65 -0
  195. package/dist/_internal/shared/search/match.js +263 -0
  196. package/dist/client.d.ts +8 -7
  197. package/dist/client.js +12 -5
  198. package/dist/configs/eslint.js +22 -2
  199. package/dist/constants/api-endpoints.d.ts +68 -0
  200. package/dist/constants/api-endpoints.js +32 -0
  201. package/dist/constants/field-names.d.ts +7 -1
  202. package/dist/constants/field-names.js +36 -1
  203. package/dist/contracts/repository.d.ts +8 -7
  204. package/dist/contracts/search.d.ts +2 -2
  205. package/dist/contracts/table.d.ts +3 -3
  206. package/dist/contracts/table.js +3 -3
  207. package/dist/core/contact-submissions.repository.js +2 -2
  208. package/dist/core/integration-keys.js +7 -1
  209. package/dist/core/newsletter.repository.js +2 -2
  210. package/dist/core/site-config.js +1 -1
  211. package/dist/errors/error-codes.d.ts +30 -0
  212. package/dist/errors/error-codes.js +30 -0
  213. package/dist/errors/error-display-map.js +40 -1
  214. package/dist/features/account/api/[userId]/addresses/route.js +1 -1
  215. package/dist/features/account/components/UserBidsView.js +1 -1
  216. package/dist/features/account/components/index.d.ts +0 -8
  217. package/dist/features/account/components/index.js +0 -4
  218. package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
  219. package/dist/features/addresses/repository/addresses.repository.js +65 -9
  220. package/dist/features/addresses/schemas/firestore.d.ts +17 -6
  221. package/dist/features/admin/actions/notification-actions.js +15 -6
  222. package/dist/features/admin/api/bids/route.js +1 -1
  223. package/dist/features/admin/api/coupons/route.js +1 -1
  224. package/dist/features/admin/api/products/route.js +1 -1
  225. package/dist/features/admin/api/reviews/route.js +1 -1
  226. package/dist/features/admin/components/AdminAdEditorView.js +19 -5
  227. package/dist/features/admin/components/AdminAuditLogView.js +1 -1
  228. package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
  229. package/dist/features/admin/components/AdminBlogView.js +1 -1
  230. package/dist/features/admin/components/AdminBrandsView.js +17 -1
  231. package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
  232. package/dist/features/admin/components/AdminContactView.js +1 -1
  233. package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
  234. package/dist/features/admin/components/AdminNewsletterView.js +1 -1
  235. package/dist/features/admin/components/AdminOrdersView.js +9 -2
  236. package/dist/features/admin/components/AdminPayoutsView.js +1 -1
  237. package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
  238. package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
  239. package/dist/features/admin/components/AdminProductEditorView.js +24 -37
  240. package/dist/features/admin/components/AdminProductsView.js +10 -3
  241. package/dist/features/admin/components/AdminScammersView.js +1 -1
  242. package/dist/features/admin/components/AdminSectionsView.js +21 -5
  243. package/dist/features/admin/components/AdminSessionsView.js +1 -1
  244. package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
  245. package/dist/features/admin/components/AdminTeamView.js +1 -1
  246. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
  247. package/dist/features/admin/components/AdminUsersView.js +1 -1
  248. package/dist/features/admin/components/DataListingView.d.ts +2 -1
  249. package/dist/features/admin/components/DataListingView.js +9 -4
  250. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
  251. package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
  252. package/dist/features/admin/repository/site-settings.repository.js +8 -3
  253. package/dist/features/admin/schemas/firestore.d.ts +62 -1
  254. package/dist/features/admin/schemas/firestore.js +32 -0
  255. package/dist/features/admin/types/index.d.ts +1 -1
  256. package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
  257. package/dist/features/auctions/actions/bid-actions.js +16 -4
  258. package/dist/features/auctions/api/route.js +1 -1
  259. package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
  260. package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
  261. package/dist/features/auctions/repository/bid.repository.js +114 -13
  262. package/dist/features/auctions/schemas/firestore.d.ts +24 -4
  263. package/dist/features/auctions/schemas/firestore.js +1 -0
  264. package/dist/features/auth/actions/profile-actions.js +30 -4
  265. package/dist/features/auth/components/index.d.ts +0 -1
  266. package/dist/features/auth/components/index.js +0 -1
  267. package/dist/features/auth/repository/session.repository.d.ts +17 -3
  268. package/dist/features/auth/repository/session.repository.js +46 -5
  269. package/dist/features/auth/repository/token.repository.d.ts +27 -4
  270. package/dist/features/auth/repository/token.repository.js +65 -11
  271. package/dist/features/auth/repository/user.repository.d.ts +33 -7
  272. package/dist/features/auth/repository/user.repository.js +100 -15
  273. package/dist/features/auth/schemas/firestore.d.ts +63 -12
  274. package/dist/features/auth/schemas/firestore.js +11 -0
  275. package/dist/features/before-after/api/route.js +1 -1
  276. package/dist/features/blog/components/BlogListView.js +16 -3
  277. package/dist/features/blog/components/BlogPostView.js +1 -1
  278. package/dist/features/blog/schemas/index.d.ts +2 -2
  279. package/dist/features/cart/api/route.js +1 -1
  280. package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
  281. package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
  282. package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
  283. package/dist/features/categories/api/route.js +10 -10
  284. package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
  285. package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
  286. package/dist/features/categories/components/index.d.ts +0 -2
  287. package/dist/features/categories/components/index.js +0 -1
  288. package/dist/features/categories/repository/categories.repository.d.ts +1 -0
  289. package/dist/features/categories/repository/categories.repository.js +31 -1
  290. package/dist/features/categories/schemas/index.d.ts +2 -2
  291. package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
  292. package/dist/features/categories/utils/taxonomy-visual.js +58 -0
  293. package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
  294. package/dist/features/collections/api/[slug]/route.js +3 -3
  295. package/dist/features/collections/api/route.js +1 -1
  296. package/dist/features/consultation/api/route.js +1 -1
  297. package/dist/features/consultation/repository/consultations.repository.js +1 -1
  298. package/dist/features/consultation/types/index.d.ts +1 -1
  299. package/dist/features/contact/components/ContactForm.js +1 -3
  300. package/dist/features/corporate/api/route.js +1 -1
  301. package/dist/features/corporate/repository/corporate.repository.js +1 -1
  302. package/dist/features/corporate/types/index.d.ts +1 -1
  303. package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
  304. package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
  305. package/dist/features/events/actions/event-actions.d.ts +14 -0
  306. package/dist/features/events/actions/event-actions.js +82 -3
  307. package/dist/features/events/api/[id]/route.js +2 -2
  308. package/dist/features/events/components/AdminEventEditorView.js +22 -3
  309. package/dist/features/events/components/AdminEventsView.js +32 -8
  310. package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
  311. package/dist/features/events/components/EventRafflesSection.js +52 -3
  312. package/dist/features/events/components/SpinWheelView.d.ts +2 -2
  313. package/dist/features/events/components/SpinWheelView.js +41 -4
  314. package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
  315. package/dist/features/events/repository/event-entry.repository.js +41 -7
  316. package/dist/features/events/schemas/firestore.d.ts +17 -4
  317. package/dist/features/events/types/index.d.ts +37 -0
  318. package/dist/features/faq/repository/faqs.repository.js +1 -1
  319. package/dist/features/faq/schemas/index.d.ts +5 -2
  320. package/dist/features/faq/schemas/index.js +6 -0
  321. package/dist/features/faq/types/index.d.ts +0 -1
  322. package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
  323. package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
  324. package/dist/features/homepage/api/carousel/route.js +4 -4
  325. package/dist/features/homepage/api/route.js +2 -2
  326. package/dist/features/homepage/api/sections/route.js +1 -1
  327. package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
  328. package/dist/features/homepage/components/AnnouncementBar.js +13 -19
  329. package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
  330. package/dist/features/homepage/components/index.d.ts +0 -2
  331. package/dist/features/homepage/components/index.js +0 -1
  332. package/dist/features/homepage/repository/homepage.repository.js +1 -1
  333. package/dist/features/homepage/schemas/firestore.d.ts +6 -0
  334. package/dist/features/homepage/schemas/index.d.ts +10 -10
  335. package/dist/features/layout/AppLayoutShell.d.ts +11 -0
  336. package/dist/features/layout/AppLayoutShell.js +64 -12
  337. package/dist/features/layout/BottomActionsContext.d.ts +16 -0
  338. package/dist/features/layout/BottomActionsContext.js +5 -0
  339. package/dist/features/layout/BottomChrome.js +48 -9
  340. package/dist/features/layout/BottomNavbar.d.ts +14 -0
  341. package/dist/features/layout/BottomNavbar.js +43 -3
  342. package/dist/features/layout/MainNavbar.d.ts +11 -0
  343. package/dist/features/layout/NavbarLayout.d.ts +3 -0
  344. package/dist/features/layout/NavbarLayout.js +88 -11
  345. package/dist/features/layout/SideActionDock.d.ts +1 -0
  346. package/dist/features/layout/SideActionDock.js +219 -0
  347. package/dist/features/layout/TitleBarLayout.js +1 -1
  348. package/dist/features/layout/cta-anchor.d.ts +31 -0
  349. package/dist/features/layout/cta-anchor.js +31 -0
  350. package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
  351. package/dist/features/layout/hooks/useBottomActions.js +6 -1
  352. package/dist/features/layout/index.d.ts +9 -1
  353. package/dist/features/layout/index.js +9 -1
  354. package/dist/features/layout/useCtaReveal.d.ts +24 -0
  355. package/dist/features/layout/useCtaReveal.js +82 -0
  356. package/dist/features/layout/useHoldToOpen.d.ts +41 -0
  357. package/dist/features/layout/useHoldToOpen.js +84 -0
  358. package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
  359. package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
  360. package/dist/features/lottery/schemas/firestore.d.ts +33 -5
  361. package/dist/features/loyalty/api/balance/route.js +1 -1
  362. package/dist/features/loyalty/api/history/route.js +1 -1
  363. package/dist/features/media/MediaImage.js +0 -1
  364. package/dist/features/media/MediaPickerModal.js +7 -1
  365. package/dist/features/media/modals/ImageEditor.js +5 -1
  366. package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
  367. package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
  368. package/dist/features/media/upload/CameraCapture.js +16 -1
  369. package/dist/features/media/upload/ImageUpload.js +42 -4
  370. package/dist/features/media/upload/MediaUploadField.js +69 -13
  371. package/dist/features/media/upload/downscale-image.d.ts +56 -0
  372. package/dist/features/media/upload/downscale-image.js +150 -0
  373. package/dist/features/messages/components/ConversationThreadView.js +45 -2
  374. package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
  375. package/dist/features/messages/components/MessageSellerButton.js +10 -2
  376. package/dist/features/messages/schemas/firestore.d.ts +15 -0
  377. package/dist/features/orders/hooks/useOrders.js +4 -2
  378. package/dist/features/orders/repository/orders.repository.d.ts +15 -4
  379. package/dist/features/orders/repository/orders.repository.js +52 -20
  380. package/dist/features/orders/schemas/firestore.d.ts +15 -4
  381. package/dist/features/orders/schemas/index.d.ts +8 -8
  382. package/dist/features/orders/types/index.d.ts +2 -2
  383. package/dist/features/payments/repository/payments.repository.js +2 -2
  384. package/dist/features/payments/repository/payout.repository.d.ts +23 -6
  385. package/dist/features/payments/repository/payout.repository.js +63 -23
  386. package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
  387. package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
  388. package/dist/features/payments/schemas/firestore.d.ts +14 -3
  389. package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
  390. package/dist/features/pre-orders/api/[slug]/route.js +1 -1
  391. package/dist/features/pre-orders/api/admin/route.js +1 -1
  392. package/dist/features/pre-orders/api/route.js +1 -1
  393. package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
  394. package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
  395. package/dist/features/products/api/[id]/route.js +1 -1
  396. package/dist/features/products/components/ListingBottomActions.js +4 -0
  397. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  398. package/dist/features/products/components/ProductGalleryClient.js +2 -2
  399. package/dist/features/products/components/ProductGrid.js +12 -1
  400. package/dist/features/products/components/index.d.ts +0 -2
  401. package/dist/features/products/components/index.js +0 -1
  402. package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
  403. package/dist/features/products/config/listing-type-listing-config.js +27 -2
  404. package/dist/features/products/constants/listing-tabs.d.ts +9 -0
  405. package/dist/features/products/constants/listing-tabs.js +3 -2
  406. package/dist/features/products/hooks/useProducts.js +2 -2
  407. package/dist/features/products/repository/products.repository.js +13 -1
  408. package/dist/features/products/schemas/index.d.ts +2 -2
  409. package/dist/features/products/types/index.d.ts +1 -1
  410. package/dist/features/promotions/api/route.js +1 -1
  411. package/dist/features/reviews/actions/review-actions.d.ts +6 -6
  412. package/dist/features/reviews/actions/review-actions.js +22 -8
  413. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
  414. package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
  415. package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
  416. package/dist/features/reviews/repository/reviews.repository.js +63 -12
  417. package/dist/features/reviews/schemas/firestore.d.ts +13 -2
  418. package/dist/features/reviews/schemas/index.d.ts +2 -2
  419. package/dist/features/scams/actions/scam-actions.js +16 -4
  420. package/dist/features/search/components/SearchResultsPageView.js +2 -1
  421. package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
  422. package/dist/features/search/hooks/useSearchIndex.js +172 -0
  423. package/dist/features/search/repository/search.repository.js +2 -2
  424. package/dist/features/seller/actions/offer-actions.d.ts +5 -5
  425. package/dist/features/seller/actions/offer-actions.js +38 -8
  426. package/dist/features/seller/actions/seller-actions.js +34 -7
  427. package/dist/features/seller/api/coupons/route.js +1 -1
  428. package/dist/features/seller/api/products/route.js +1 -1
  429. package/dist/features/seller/api/store/route.js +1 -1
  430. package/dist/features/seller/components/SellerBidsView.js +1 -1
  431. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  432. package/dist/features/seller/components/SellerListingTypeView.js +9 -1
  433. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  434. package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
  435. package/dist/features/seller/components/SellerPayoutsView.js +1 -1
  436. package/dist/features/seller/components/SellerProductShell.js +0 -1
  437. package/dist/features/seller/components/SellerProductsView.js +1 -1
  438. package/dist/features/seller/components/SellerShippingView.js +0 -1
  439. package/dist/features/seller/components/SellerStorefrontView.js +0 -1
  440. package/dist/features/seller/components/index.d.ts +0 -4
  441. package/dist/features/seller/components/index.js +0 -2
  442. package/dist/features/seller/repository/offer.repository.d.ts +15 -3
  443. package/dist/features/seller/repository/offer.repository.js +43 -7
  444. package/dist/features/seller/schemas/firestore.d.ts +14 -3
  445. package/dist/features/seller/schemas/index.d.ts +4 -4
  446. package/dist/features/seller/schemas/order-forms.d.ts +39 -0
  447. package/dist/features/seller/schemas/order-forms.js +37 -0
  448. package/dist/features/shell/FormShell.js +6 -2
  449. package/dist/features/shell/QuickFormDrawer.js +15 -1
  450. package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
  451. package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
  452. package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
  453. package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
  454. package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
  455. package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
  456. package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
  457. package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
  458. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
  459. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
  460. package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
  461. package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
  462. package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
  463. package/dist/features/sticker-trace/constants/help-content.js +172 -0
  464. package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
  465. package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
  466. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
  467. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
  468. package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
  469. package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
  470. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
  471. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
  472. package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
  473. package/dist/features/sticker-trace/schemas/firestore.js +79 -0
  474. package/dist/features/sticker-trace/server.d.ts +8 -0
  475. package/dist/features/sticker-trace/server.js +51 -0
  476. package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
  477. package/dist/features/stores/actions/store-query-actions.js +7 -2
  478. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
  479. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
  480. package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
  481. package/dist/features/stores/api/[storeSlug]/route.js +1 -1
  482. package/dist/features/stores/components/StoreNavTabs.js +17 -2
  483. package/dist/features/stores/manifest.js +8 -4
  484. package/dist/features/support/repository/support.repository.d.ts +14 -3
  485. package/dist/features/support/repository/support.repository.js +93 -13
  486. package/dist/features/support/schemas/firestore.d.ts +16 -5
  487. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
  488. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
  489. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  490. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
  491. package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
  492. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
  493. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
  494. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
  495. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
  496. package/dist/features/tester/seed-data/authored/index.js +8 -0
  497. package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
  498. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
  499. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
  500. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
  501. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +192 -22
  502. package/dist/index.d.ts +10 -23
  503. package/dist/index.js +27 -19
  504. package/dist/next/api/routeHandler.js +9 -0
  505. package/dist/next/routing/require-record.d.ts +13 -0
  506. package/dist/next/routing/require-record.js +62 -0
  507. package/dist/next/routing/route-map.d.ts +4 -4
  508. package/dist/next/routing/route-map.js +25 -3
  509. package/dist/providers/db-firebase/base.d.ts +4 -2
  510. package/dist/providers/db-firebase/base.js +21 -5
  511. package/dist/providers/db-firebase/base.repository.d.ts +11 -9
  512. package/dist/providers/db-firebase/base.repository.js +19 -0
  513. package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
  514. package/dist/providers/db-firebase/rtdb-paths.js +12 -0
  515. package/dist/react/ErrorBoundary.js +6 -1
  516. package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
  517. package/dist/react/hooks/realtime-event-constants.js +8 -0
  518. package/dist/react/hooks/useEntityDelete.js +5 -1
  519. package/dist/react/hooks/useMessage.js +5 -1
  520. package/dist/repositories/index.d.ts +2 -2
  521. package/dist/repositories/index.js +6 -1
  522. package/dist/schemas/registry.d.ts +13 -20
  523. package/dist/schemas/registry.js +31 -14
  524. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  525. package/dist/security/encrypted.d.ts +117 -0
  526. package/dist/security/encrypted.js +100 -0
  527. package/dist/security/index.d.ts +5 -2
  528. package/dist/security/index.js +16 -2
  529. package/dist/security/pii-accessors.d.ts +71 -0
  530. package/dist/security/pii-accessors.js +150 -0
  531. package/dist/security/pii-encrypt.d.ts +0 -8
  532. package/dist/security/pii-encrypt.js +22 -15
  533. package/dist/security/pii-mask.d.ts +18 -0
  534. package/dist/security/pii-mask.js +27 -0
  535. package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
  536. package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
  537. package/dist/seed/addresses-seed-data.d.ts +2 -2
  538. package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
  539. package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
  540. package/dist/seed/bids-seed-data.d.ts +2 -2
  541. package/dist/seed/bids-seed-data.js +23 -2
  542. package/dist/seed/events-seed-data.d.ts +2 -2
  543. package/dist/seed/events-seed-data.js +5 -0
  544. package/dist/seed/faq-seed-data.js +175 -5
  545. package/dist/seed/homepage-sections-seed-data.js +39 -23
  546. package/dist/seed/index.d.ts +1 -0
  547. package/dist/seed/index.js +1 -0
  548. package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
  549. package/dist/seed/offers-seed-data.d.ts +2 -2
  550. package/dist/seed/offers-seed-data.js +1 -1
  551. package/dist/seed/orders-seed-data.d.ts +2 -2
  552. package/dist/seed/payouts-seed-data.d.ts +2 -2
  553. package/dist/seed/payouts-seed-data.js +1 -1
  554. package/dist/seed/reviews-seed-data.d.ts +1 -2
  555. package/dist/seed/seed-purpose.js +7 -0
  556. package/dist/seed/sessions-seed-data.d.ts +2 -2
  557. package/dist/seed/sessions-seed-data.js +5 -0
  558. package/dist/seed/site-settings-seed-data.js +1 -1
  559. package/dist/seed/support-tickets-seed-data.d.ts +2 -2
  560. package/dist/seed/support-tickets-seed-data.js +1 -1
  561. package/dist/seed/users-seed-data.d.ts +2 -2
  562. package/dist/seed/users-seed-data.js +1 -1
  563. package/dist/seo/json-ld.js +5 -1
  564. package/dist/server.d.ts +18 -3
  565. package/dist/server.js +59 -3
  566. package/dist/styles.css +237 -1
  567. package/dist/tailwind-utilities.css +1 -1
  568. package/dist/ui/components/Button.js +7 -1
  569. package/dist/ui/components/FilterChipGroup.d.ts +11 -0
  570. package/dist/ui/components/FilterChipGroup.js +1 -1
  571. package/dist/ui/components/ImageGallery.js +6 -1
  572. package/dist/ui/components/ListingLayout.js +14 -8
  573. package/dist/ui/components/OverflowRow.d.ts +92 -0
  574. package/dist/ui/components/OverflowRow.js +203 -0
  575. package/dist/ui/components/OverflowRow.style.css +235 -0
  576. package/dist/ui/components/RecordDetailModal.js +14 -1
  577. package/dist/ui/components/RowActionMenu.js +5 -1
  578. package/dist/ui/components/SideDrawer.js +5 -1
  579. package/dist/ui/components/SideModal.js +9 -1
  580. package/dist/ui/components/TabBarShell.d.ts +12 -1
  581. package/dist/ui/components/TabBarShell.js +3 -2
  582. package/dist/ui/components/Tabs.js +36 -24
  583. package/dist/ui/components/Toast.d.ts +3 -24
  584. package/dist/ui/components/Toast.js +2 -19
  585. package/dist/ui/components/TopBannerPortal.d.ts +15 -0
  586. package/dist/ui/components/TopBannerPortal.js +19 -0
  587. package/dist/ui/components/UnsavedChangesModal.js +5 -1
  588. package/dist/ui/components/index.style.css +1 -0
  589. package/dist/ui/components/row-collapse.d.ts +15 -0
  590. package/dist/ui/components/row-collapse.js +127 -0
  591. package/dist/ui/components/toast-context.d.ts +63 -0
  592. package/dist/ui/components/toast-context.js +48 -0
  593. package/dist/ui/components/top-banner-slot.d.ts +37 -0
  594. package/dist/ui/components/top-banner-slot.js +45 -0
  595. package/dist/ui/icons/icon-registry.d.ts +6 -0
  596. package/dist/ui/icons/icon-registry.js +17 -1
  597. package/dist/ui/index.d.ts +2 -0
  598. package/dist/ui/index.js +1 -0
  599. package/dist/utils/array.helper.d.ts +2 -2
  600. package/dist/utils/array.helper.js +5 -5
  601. package/dist/utils/id-generators.d.ts +6 -0
  602. package/dist/utils/id-generators.js +10 -0
  603. package/dist/utils/media-url.js +0 -2
  604. package/dist/utils/search-txt-builders.d.ts +28 -4
  605. package/dist/utils/search-txt-builders.js +41 -1
  606. package/dist/validation/schemas.d.ts +8 -8
  607. package/package.json +6 -2
  608. package/scripts/seed-cli.mjs +3 -0
  609. package/dist/features/account/components/UserAddressesView.d.ts +0 -13
  610. package/dist/features/account/components/UserAddressesView.js +0 -5
  611. package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
  612. package/dist/features/account/components/UserNotificationsView.js +0 -12
  613. package/dist/features/account/components/UserSettingsView.d.ts +0 -16
  614. package/dist/features/account/components/UserSettingsView.js +0 -13
  615. package/dist/features/account/components/UserSupportView.d.ts +0 -3
  616. package/dist/features/account/components/UserSupportView.js +0 -166
  617. package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
  618. package/dist/features/admin/components/DemoSeedView.js +0 -5
  619. package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
  620. package/dist/features/auth/components/AuthStatusPanel.js +0 -22
  621. package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
  622. package/dist/features/categories/components/CategoryProductsView.js +0 -21
  623. package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
  624. package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
  625. package/dist/features/layout/BottomActions.d.ts +0 -1
  626. package/dist/features/layout/BottomActions.js +0 -311
  627. package/dist/features/products/components/ProductsView.d.ts +0 -6
  628. package/dist/features/products/components/ProductsView.js +0 -5
  629. package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
  630. package/dist/features/seller/components/SellerStoreView.js +0 -8
@@ -1,7 +1,7 @@
1
1
  import { normalizeError } from "../../../errors/normalize.js";
2
2
  import { DatabaseError } from "../../../errors/index.js";
3
3
  import { BaseRepository } from "../../../providers/db-firebase/index.js";
4
- import { TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, decryptPiiFields, piiBlindIndex, } from "../../../security/index.js";
4
+ import { TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, maskPii, piiBlindIndex, revealPii, } from "../../../security/index.js";
5
5
  import { resolveDate } from "../../../utils/index.js";
6
6
  import { EMAIL_VERIFICATION_COLLECTION, PASSWORD_RESET_COLLECTION, TOKEN_FIELDS, } from "../schemas/index.js";
7
7
  export class EmailVerificationTokenRepository extends BaseRepository {
@@ -24,11 +24,38 @@ export class EmailVerificationTokenRepository extends BaseRepository {
24
24
  this.piiFields = TOKEN_PII_FIELDS;
25
25
  this.piiIndexMap = TOKEN_PII_INDEX_MAP;
26
26
  }
27
- mapDoc(snap) {
28
- const raw = super.mapDoc(snap);
29
- return decryptPiiFields(raw, [
30
- ...TOKEN_PII_FIELDS,
31
- ]);
27
+ /*
28
+ * 🛑 `mapDoc` is NOT overridden, and that absence IS the change.
29
+ *
30
+ * It used to decrypt on every read, so ciphertext never left the database
31
+ * and every caller handled plaintext without ever saying so. Following
32
+ * `SiteSettingsRepository`: reads return what Firestore holds, and plaintext
33
+ * requires one of the two named methods below.
34
+ *
35
+ * A convention would not hold this. `EmailVerificationTokenDocument`'s PII fields are
36
+ * `Encrypted<string>`, assignable to nothing that wants a plain `string`, so
37
+ * a reader that skips both accessors is a compile error naming file and line.
38
+ */
39
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
40
+ revealToken(doc) {
41
+ return revealPii(doc, TOKEN_PII_FIELDS);
42
+ }
43
+ /** As `revealToken`, for a list read. */
44
+ revealTokens(docs) {
45
+ return docs.map((d) => this.revealToken(d));
46
+ }
47
+ /**
48
+ * Masked PII — **the default for any surface that only needs to identify a
49
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
50
+ * ciphertext by design, so passing a stored field straight in would return
51
+ * "Anonymous" for every row.
52
+ */
53
+ maskedToken(doc) {
54
+ return maskPii(doc, TOKEN_PII_FIELDS);
55
+ }
56
+ /** As `maskedToken`, for a list read. */
57
+ maskedTokens(docs) {
58
+ return docs.map((d) => this.maskedToken(d));
32
59
  }
33
60
  async findByToken(token) {
34
61
  return this.findOneBy(TOKEN_FIELDS.TOKEN, token);
@@ -97,11 +124,38 @@ export class PasswordResetTokenRepository extends BaseRepository {
97
124
  this.piiFields = TOKEN_PII_FIELDS;
98
125
  this.piiIndexMap = TOKEN_PII_INDEX_MAP;
99
126
  }
100
- mapDoc(snap) {
101
- const raw = super.mapDoc(snap);
102
- return decryptPiiFields(raw, [
103
- ...TOKEN_PII_FIELDS,
104
- ]);
127
+ /*
128
+ * 🛑 `mapDoc` is NOT overridden, and that absence IS the change.
129
+ *
130
+ * It used to decrypt on every read, so ciphertext never left the database
131
+ * and every caller handled plaintext without ever saying so. Following
132
+ * `SiteSettingsRepository`: reads return what Firestore holds, and plaintext
133
+ * requires one of the two named methods below.
134
+ *
135
+ * A convention would not hold this. `PasswordResetTokenDocument`'s PII fields are
136
+ * `Encrypted<string>`, assignable to nothing that wants a plain `string`, so
137
+ * a reader that skips both accessors is a compile error naming file and line.
138
+ */
139
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
140
+ revealResetToken(doc) {
141
+ return revealPii(doc, TOKEN_PII_FIELDS);
142
+ }
143
+ /** As `revealResetToken`, for a list read. */
144
+ revealResetTokens(docs) {
145
+ return docs.map((d) => this.revealResetToken(d));
146
+ }
147
+ /**
148
+ * Masked PII — **the default for any surface that only needs to identify a
149
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
150
+ * ciphertext by design, so passing a stored field straight in would return
151
+ * "Anonymous" for every row.
152
+ */
153
+ maskedResetToken(doc) {
154
+ return maskPii(doc, TOKEN_PII_FIELDS);
155
+ }
156
+ /** As `maskedResetToken`, for a list read. */
157
+ maskedResetTokens(docs) {
158
+ return docs.map((d) => this.maskedResetToken(d));
105
159
  }
106
160
  async findByToken(token) {
107
161
  return this.findOneBy(TOKEN_FIELDS.TOKEN, token);
@@ -1,11 +1,38 @@
1
- import type { DocumentSnapshot } from "../../../providers/db-firebase";
2
1
  import { BaseRepository, type FirebaseSieveFields, type FirebaseSieveResult, type SieveModel } from "../../../providers/db-firebase";
3
2
  import type { UserRole } from "../types";
4
- import { type UserDocument } from "../schemas";
3
+ import { type UserDocument, type UserPlain } from "../schemas";
5
4
  export declare class UserRepository extends BaseRepository<UserDocument> {
6
5
  static readonly SIEVE_FIELDS: FirebaseSieveFields;
7
6
  constructor();
8
- private decryptUser;
7
+ /**
8
+ * Plaintext PII. **Opt-in and named** — for the account's own settings page,
9
+ * the payout run, and any mail that has to reach the person.
10
+ */
11
+ revealUser(doc: UserDocument): UserPlain;
12
+ /** As `revealUser`, for a list read. */
13
+ revealUsers(docs: readonly UserDocument[]): UserPlain[];
14
+ /**
15
+ * Masked PII — **the default for every admin list and every public
16
+ * surface.** Decrypts first, then masks, because the mask helpers refuse
17
+ * ciphertext by design.
18
+ *
19
+ * `payoutDetails` and `shippingConfig` are decrypted and then masked
20
+ * member-by-member: a UPI handle or account number reaching an admin table
21
+ * unmasked is the most damaging value this document carries.
22
+ */
23
+ maskedUser(doc: UserDocument): UserPlain;
24
+ /** As `maskedUser`, for a list read. */
25
+ maskedUsers(docs: readonly UserDocument[]): UserPlain[];
26
+ /**
27
+ * Mask every string member of an already-decrypted nested object.
28
+ *
29
+ * The field list is derived from the object rather than hard-coded, because
30
+ * `USER_PII_FIELDS` does not name these members and a second list here would
31
+ * have to be kept in step with `decryptPayoutDetails`'s own (Root Cause #42).
32
+ * Every string in a payout or shipping block is sensitive, so "all of them"
33
+ * is the correct list, not an approximation.
34
+ */
35
+ private maskNested;
9
36
  /**
10
37
  * Declared, not hand-rolled.
11
38
  *
@@ -28,9 +55,8 @@ export declare class UserRepository extends BaseRepository<UserDocument> {
28
55
  * that have to agree — which is what the hand-rolled override was.
29
56
  */
30
57
  protected applyWriteHooks<D extends object>(data: D): D;
31
- protected mapDoc<D = UserDocument>(snap: DocumentSnapshot): D;
32
- createWithId(id: string, data: Partial<UserDocument>): Promise<UserDocument>;
33
- create(input: Omit<UserDocument, "id" | "createdAt" | "updatedAt">): Promise<UserDocument>;
58
+ createWithId(id: string, data: Partial<UserPlain>): Promise<UserDocument>;
59
+ create(input: Omit<UserPlain, "id" | "createdAt" | "updatedAt">): Promise<UserDocument>;
34
60
  findByUid(uid: string): Promise<UserDocument | null>;
35
61
  /**
36
62
  * Resolve a public profile slug.
@@ -51,7 +77,7 @@ export declare class UserRepository extends BaseRepository<UserDocument> {
51
77
  * Permanent bans (`hardBanExpiresAt` null/absent) never match this query.
52
78
  */
53
79
  getExpiredHardBans(): Promise<UserDocument[]>;
54
- update(uid: string, data: Partial<UserDocument>): Promise<UserDocument>;
80
+ update(uid: string, data: Partial<UserPlain>): Promise<UserDocument>;
55
81
  markEmailAsVerified(uid: string): Promise<UserDocument>;
56
82
  disable(uid: string): Promise<UserDocument>;
57
83
  enable(uid: string): Promise<UserDocument>;
@@ -1,7 +1,7 @@
1
1
  import { normalizeError } from "../../../errors/normalize.js";
2
2
  import { DatabaseError } from "../../../errors/index.js";
3
3
  import { BaseRepository, getFirestoreCount, prepareForFirestore, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
4
- import { USER_PII_FIELDS, USER_PII_INDEX_MAP, decryptPayoutDetails, decryptPiiFields, decryptShippingConfig, encryptPayoutDetails, encryptShippingConfig, piiBlindIndex, } from "../../../security/index.js";
4
+ import { USER_PII_FIELDS, USER_PII_INDEX_MAP, decryptPayoutDetails, maskPii, revealPii, decryptShippingConfig, encryptPayoutDetails, encryptShippingConfig, piiBlindIndex, } from "../../../security/index.js";
5
5
  import { USER_COLLECTION, USER_FIELDS, } from "../schemas/index.js";
6
6
  export class UserRepository extends BaseRepository {
7
7
  constructor() {
@@ -20,15 +20,74 @@ export class UserRepository extends BaseRepository {
20
20
  this.piiFields = USER_PII_FIELDS;
21
21
  this.piiIndexMap = USER_PII_INDEX_MAP;
22
22
  }
23
- decryptUser(doc) {
24
- const decrypted = decryptPiiFields(doc, [...USER_PII_FIELDS]);
25
- if (decrypted.payoutDetails) {
26
- decrypted.payoutDetails = decryptPayoutDetails(decrypted.payoutDetails);
23
+ /*
24
+ * 🛑 `mapDoc` no longer decrypts. This is the widest-reaching of the
25
+ * fourteen — 73 files touch this repository — and it is why ciphertext never
26
+ * leaving the database matters most here: `email` and `phoneNumber` belong
27
+ * to every account on the platform.
28
+ *
29
+ * `payoutDetails` and `shippingConfig` are handled inside the accessors
30
+ * rather than by `revealPii`, because each is encrypted by its OWN scheme
31
+ * and not by a `USER_PII_FIELDS` path. An accessor that silently skipped
32
+ * them would hand a caller a UPI id it could not read — worse than refusing,
33
+ * because the value looks present.
34
+ */
35
+ /**
36
+ * Plaintext PII. **Opt-in and named** — for the account's own settings page,
37
+ * the payout run, and any mail that has to reach the person.
38
+ */
39
+ revealUser(doc) {
40
+ const revealed = revealPii(doc, USER_PII_FIELDS);
41
+ if (revealed.payoutDetails) {
42
+ revealed.payoutDetails = decryptPayoutDetails(revealed.payoutDetails);
27
43
  }
28
- if (decrypted.shippingConfig) {
29
- decrypted.shippingConfig = decryptShippingConfig(decrypted.shippingConfig);
44
+ if (revealed.shippingConfig) {
45
+ revealed.shippingConfig = decryptShippingConfig(revealed.shippingConfig);
30
46
  }
31
- return decrypted;
47
+ return revealed;
48
+ }
49
+ /** As `revealUser`, for a list read. */
50
+ revealUsers(docs) {
51
+ return docs.map((d) => this.revealUser(d));
52
+ }
53
+ /**
54
+ * Masked PII — **the default for every admin list and every public
55
+ * surface.** Decrypts first, then masks, because the mask helpers refuse
56
+ * ciphertext by design.
57
+ *
58
+ * `payoutDetails` and `shippingConfig` are decrypted and then masked
59
+ * member-by-member: a UPI handle or account number reaching an admin table
60
+ * unmasked is the most damaging value this document carries.
61
+ */
62
+ maskedUser(doc) {
63
+ const masked = maskPii(doc, USER_PII_FIELDS);
64
+ if (masked.payoutDetails) {
65
+ masked.payoutDetails = this.maskNested(decryptPayoutDetails(masked.payoutDetails));
66
+ }
67
+ if (masked.shippingConfig) {
68
+ masked.shippingConfig = this.maskNested(decryptShippingConfig(masked.shippingConfig));
69
+ }
70
+ return masked;
71
+ }
72
+ /** As `maskedUser`, for a list read. */
73
+ maskedUsers(docs) {
74
+ return docs.map((d) => this.maskedUser(d));
75
+ }
76
+ /**
77
+ * Mask every string member of an already-decrypted nested object.
78
+ *
79
+ * The field list is derived from the object rather than hard-coded, because
80
+ * `USER_PII_FIELDS` does not name these members and a second list here would
81
+ * have to be kept in step with `decryptPayoutDetails`'s own (Root Cause #42).
82
+ * Every string in a payout or shipping block is sensitive, so "all of them"
83
+ * is the correct list, not an approximation.
84
+ */
85
+ maskNested(value) {
86
+ if (!value)
87
+ return undefined;
88
+ return maskPii(value, Object.entries(value)
89
+ .filter(([, v]) => typeof v === "string")
90
+ .map(([k]) => k));
32
91
  }
33
92
  /**
34
93
  * The base hook, plus the nested objects it cannot see.
@@ -47,10 +106,11 @@ export class UserRepository extends BaseRepository {
47
106
  access.shippingConfig = encryptShippingConfig(access.shippingConfig);
48
107
  return out;
49
108
  }
50
- mapDoc(snap) {
51
- const raw = super.mapDoc(snap);
52
- return this.decryptUser(raw);
53
- }
109
+ /*
110
+ * Takes PLAINTEXT, like the base it overrides — the three real signup paths
111
+ * hand over the email Firebase just gave them, and `applyWriteHooks` below
112
+ * is what encrypts it.
113
+ */
54
114
  async createWithId(id, data) {
55
115
  // `uid` is a required UserDocument field read directly off the mapped
56
116
  // object (SessionUser.uid, getServerPermissions(uid), etc.) — mapDoc()
@@ -76,6 +136,7 @@ export class UserRepository extends BaseRepository {
76
136
  // request an O(1) lookup). The readable public identifier is `slug`, minted
77
137
  // by `reserveUserSlug` from displayName only.
78
138
  const id = this.db.collection(this.collection).doc().id;
139
+ // Plain in, ciphertext out — `applyWriteHooks` encrypts below.
79
140
  const userData = {
80
141
  ...input,
81
142
  createdAt: new Date(),
@@ -86,7 +147,15 @@ export class UserRepository extends BaseRepository {
86
147
  .collection(this.collection)
87
148
  .doc(id)
88
149
  .set(prepareForFirestore(encrypted));
89
- return { id, ...userData };
150
+ /*
151
+ * Returns what was PERSISTED, not the plaintext input.
152
+ *
153
+ * `encrypted` is the exact object just written, so this is both honest and
154
+ * assignable to the base's `Promise<UserDocument>` — the declaration
155
+ * previously said `UserDocument` while returning `userData`, the plaintext.
156
+ * No re-read, so no extra Firestore read (Rule #6).
157
+ */
158
+ return { id, ...encrypted };
90
159
  }
91
160
  async findByUid(uid) {
92
161
  return this.findOneBy(USER_FIELDS.UID, uid);
@@ -157,6 +226,11 @@ export class UserRepository extends BaseRepository {
157
226
  throw new DatabaseError("Failed to fetch expired hard bans", error);
158
227
  }
159
228
  }
229
+ /*
230
+ * Takes PLAINTEXT, like the base it overrides — this method is the thing
231
+ * that encrypts (`applyWriteHooks`), so demanding ciphertext from callers
232
+ * inverted its own contract.
233
+ */
160
234
  async update(uid, data) {
161
235
  const encrypted = this.applyWriteHooks(data);
162
236
  return super.update(uid, encrypted);
@@ -181,11 +255,22 @@ export class UserRepository extends BaseRepository {
181
255
  if (!currentUser) {
182
256
  throw new DatabaseError(`User not found: ${uid}`);
183
257
  }
258
+ /*
259
+ * Plain in, ciphertext out — `this.update` encrypts via the write hook.
260
+ *
261
+ * 🛑 The comparison below (`data.email !== currentUser.email`) now
262
+ * compares PLAINTEXT to CIPHERTEXT, so it is always true and
263
+ * `emailVerified` is cleared on every profile save that includes an
264
+ * email — even an unchanged one. `currentUser` comes from `findById`,
265
+ * which no longer decrypts. Fixed by comparing against the revealed
266
+ * value, which is the one place in this method that needs plaintext.
267
+ */
184
268
  const updateData = { ...data };
185
- if (data.email && data.email !== currentUser.email) {
269
+ const current = this.revealUser(currentUser);
270
+ if (data.email && data.email !== current.email) {
186
271
  updateData.emailVerified = false;
187
272
  }
188
- if (data.phoneNumber && data.phoneNumber !== currentUser.phoneNumber) {
273
+ if (data.phoneNumber && data.phoneNumber !== current.phoneNumber) {
189
274
  updateData.phoneVerified = false;
190
275
  }
191
276
  return this.update(uid, updateData);
@@ -7,6 +7,7 @@
7
7
  import type { UserRole } from "../types";
8
8
  import type { BannedAction, EmployeeGroup, Permission } from "../permissions/constants";
9
9
  import type { BaseDocument } from "../../../_internal/shared/types/base-document";
10
+ import type { Encrypted, Plaintext } from "../../../security/encrypted";
10
11
  /**
11
12
  * Generic schema defaults for user-related data.
12
13
  * Consumer-specific values (admin email, currency) belong in SiteConfig, not here.
@@ -31,6 +32,16 @@ export interface AvatarMetadata {
31
32
  };
32
33
  zoom: number;
33
34
  }
35
+ /**
36
+ * `UserDocument` with its PII as plain `string` — what the named repository
37
+ * accessors return, and what a WRITE path accepts (the repository encrypts).
38
+ *
39
+ * `Plaintext<T>` is the one definition of this shape; see `security/encrypted.ts`.
40
+ * It is deliberately NOT distinguishable from a MASKED value — `maskPii`
41
+ * returns plain strings too, and no type can express "these characters are
42
+ * asterisks". The distinction is which named method you called.
43
+ */
44
+ export type UserPlain = Plaintext<UserDocument>;
34
45
  export interface UserDocument extends BaseDocument {
35
46
  uid: string;
36
47
  /**
@@ -52,8 +63,14 @@ export interface UserDocument extends BaseDocument {
52
63
  * profile resolution falls back to id and then uid.
53
64
  */
54
65
  slug?: string;
55
- email: string | null;
56
- phoneNumber: string | null;
66
+ /**
67
+ * PII — CIPHERTEXT at rest, kept true by `UserRepository` no longer
68
+ * decrypting in `mapDoc`. Readers call `userRepository.maskedUser(doc)` (the
69
+ * default) or `revealUser(doc)` (opt-in, named, greppable).
70
+ */
71
+ email: Encrypted<string> | null;
72
+ /** PII — ciphertext at rest; see `email`. */
73
+ phoneNumber: Encrypted<string> | null;
57
74
  phoneVerified?: boolean;
58
75
  displayName: string | null;
59
76
  photoURL: string | null;
@@ -133,7 +150,8 @@ export interface UserDocument extends BaseDocument {
133
150
  * exchange rather than the client SDK's linkWithCredential(). */
134
151
  googleLinked?: boolean;
135
152
  /** The Google account email this profile is linked to, once linked. */
136
- googleLinkedEmail?: string | null;
153
+ /** PII — ciphertext at rest; see `email`. */
154
+ googleLinkedEmail?: Encrypted<string> | null;
137
155
  uiPreferences?: {
138
156
  /** IDs of collapsible dashboard sections currently collapsed, flat across
139
157
  * every page (IDs are page-prefixed, e.g. "admin-dashboard:alerts", to
@@ -216,13 +234,13 @@ export interface SellerPayoutDetails {
216
234
  isConfigured: boolean;
217
235
  }
218
236
  export declare const USER_COLLECTION: "users";
219
- export declare const DEFAULT_USER_DATA: Partial<UserDocument>;
237
+ export declare const DEFAULT_USER_DATA: Partial<UserPlain>;
220
238
  export declare const USER_INDEXED_FIELDS: readonly ["email", "emailIndex", "phoneNumber", "phoneIndex", "role", "disabled", "emailVerified", "phoneVerified", "storeSlug", "storeStatus", "isTester", "slug"];
221
239
  export declare const USER_PUBLIC_FIELDS: readonly ["uid", "displayName", "photoURL", "avatarMetadata", "role", "createdAt", "storeSlug", "publicProfile", "stats"];
222
240
  export declare const USER_UPDATABLE_FIELDS: readonly ["displayName", "photoURL"];
223
241
  export type UserCreateInput = Omit<UserDocument, "uid" | "id" | "createdAt" | "updatedAt">;
224
242
  export type UserUpdateInput = Partial<Pick<UserDocument, "displayName" | "photoURL">>;
225
- export type UserAdminUpdateInput = Partial<Omit<UserDocument, "uid" | "id" | "createdAt">>;
243
+ export type UserAdminUpdateInput = Partial<Omit<UserPlain, "uid" | "id" | "createdAt">>;
226
244
  export interface UserQueryFilter {
227
245
  email?: string;
228
246
  phoneNumber?: string;
@@ -308,18 +326,38 @@ export declare const USER_FIELDS: {
308
326
  readonly LOGIN_COUNT: "metadata.loginCount";
309
327
  };
310
328
  };
329
+ /**
330
+ * `EmailVerificationTokenDocument` with its PII as plain `string` — what the named repository
331
+ * accessors return, and what a WRITE path accepts (the repository encrypts).
332
+ *
333
+ * `Plaintext<T>` is the one definition of this shape; see `security/encrypted.ts`.
334
+ * It is deliberately NOT distinguishable from a MASKED value — `maskPii`
335
+ * returns plain strings too, and no type can express "these characters are
336
+ * asterisks". The distinction is which named method you called.
337
+ */
338
+ export type EmailVerificationTokenPlain = Plaintext<EmailVerificationTokenDocument>;
311
339
  export type EmailVerificationTokenDocument = {
312
340
  id?: string;
313
341
  userId: string;
314
- email: string;
342
+ email: Encrypted<string>;
315
343
  token: string;
316
344
  expiresAt: Date;
317
345
  createdAt: Date;
318
346
  };
347
+ /**
348
+ * `PasswordResetTokenDocument` with its PII as plain `string` — what the named repository
349
+ * accessors return, and what a WRITE path accepts (the repository encrypts).
350
+ *
351
+ * `Plaintext<T>` is the one definition of this shape; see `security/encrypted.ts`.
352
+ * It is deliberately NOT distinguishable from a MASKED value — `maskPii`
353
+ * returns plain strings too, and no type can express "these characters are
354
+ * asterisks". The distinction is which named method you called.
355
+ */
356
+ export type PasswordResetTokenPlain = Plaintext<PasswordResetTokenDocument>;
319
357
  export type PasswordResetTokenDocument = {
320
358
  id?: string;
321
359
  userId: string;
322
- email: string;
360
+ email: Encrypted<string>;
323
361
  token: string;
324
362
  expiresAt: Date;
325
363
  createdAt: Date;
@@ -353,19 +391,32 @@ export declare const TOKEN_FIELDS: {
353
391
  readonly USED: "used";
354
392
  readonly USED_AT: "usedAt";
355
393
  };
394
+ /**
395
+ * The session shape with its PII as plain `string`.
396
+ *
397
+ * Was a hand-written twin, because `Plaintext<T>` un-branded top-level members
398
+ * only and all three of this document's PII fields are NESTED. Making the
399
+ * generic recurse removed the twin — which is the better outcome: a
400
+ * hand-written copy of a derived shape is the drift this whole file's
401
+ * `*Plain` convention exists to avoid.
402
+ */
403
+ export type SessionPlain = Plaintext<SessionDocument>;
356
404
  export type SessionDocument = {
357
405
  id: string;
358
406
  userId: string;
359
407
  deviceInfo?: {
360
- userAgent?: string;
408
+ /** PII — ciphertext at rest. See `SessionRepository.revealSession`. */
409
+ userAgent?: Encrypted<string>;
361
410
  browser?: string;
362
411
  os?: string;
363
412
  device?: string;
364
- ip?: string;
413
+ /** PII — ciphertext at rest. */
414
+ ip?: Encrypted<string>;
365
415
  };
366
416
  location?: {
367
417
  country?: string;
368
- city?: string;
418
+ /** PII — ciphertext at rest. */
419
+ city?: Encrypted<string>;
369
420
  };
370
421
  createdAt: Date;
371
422
  lastActivity: Date;
@@ -382,7 +433,7 @@ export declare const SESSION_PUBLIC_FIELDS: readonly ["id", "deviceInfo", "locat
382
433
  export declare const SESSION_EXPIRATION_MS: number;
383
434
  /** 30 days — auto-cleanup threshold */
384
435
  export declare const SESSION_CLEANUP_AFTER_MS: number;
385
- export type SessionCreateInput = Omit<SessionDocument, "id" | "createdAt" | "lastActivity">;
436
+ export type SessionCreateInput = Omit<SessionPlain, "id" | "createdAt" | "lastActivity">;
386
437
  export type SessionUpdateInput = {
387
438
  lastActivity: Date;
388
439
  location?: SessionDocument["location"];
@@ -400,7 +451,7 @@ export declare const sessionQueryHelpers: {
400
451
  readonly notExpired: () => readonly ["expiresAt", ">=", Date];
401
452
  readonly recentActivity: (since: Date) => readonly ["lastActivity", ">=", Date];
402
453
  };
403
- export declare function parseUserAgent(userAgent: string): SessionDocument["deviceInfo"];
454
+ export declare function parseUserAgent(userAgent: string): SessionPlain["deviceInfo"];
404
455
  export declare const SESSION_FIELDS: {
405
456
  readonly ID: "id";
406
457
  readonly USER_ID: "userId";
@@ -24,6 +24,12 @@ export const UserSchemaDefaults = {
24
24
  UNKNOWN_USER_AGENT: "Unknown",
25
25
  };
26
26
  export const USER_COLLECTION = "users";
27
+ /*
28
+ * The PLAIN shape: this is spread into a brand-new account's payload at
29
+ * signup, where every value is plaintext and `createWithId` encrypts. Typed
30
+ * as the document it would have demanded `Encrypted<string>` from all three
31
+ * signup routes.
32
+ */
27
33
  export const DEFAULT_USER_DATA = {
28
34
  role: "user",
29
35
  emailVerified: false,
@@ -215,6 +221,11 @@ export const sessionQueryHelpers = {
215
221
  notExpired: () => ["expiresAt", ">=", new Date()],
216
222
  recentActivity: (since) => ["lastActivity", ">=", since],
217
223
  };
224
+ /*
225
+ * Returns the PLAIN device shape: it parses a raw UA header, so everything it
226
+ * produces is plaintext and the repository's write hook encrypts it. Declaring
227
+ * `SessionDocument["deviceInfo"]` claimed the parser emitted ciphertext.
228
+ */
218
229
  export function parseUserAgent(userAgent) {
219
230
  const ua = userAgent.toLowerCase();
220
231
  const BROWSER_TOKENS = [
@@ -33,7 +33,7 @@ export async function GET(request) {
33
33
  filters,
34
34
  sort,
35
35
  page,
36
- perPage: pageSize,
36
+ pageSize: pageSize,
37
37
  });
38
38
  const totalPages = Math.max(1, Math.ceil(result.total / pageSize));
39
39
  return NextResponse.json({
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import Link from "next/link.js";
4
- import { Article, Button, Div, Grid, Heading, Pagination, Row, Span, Stack, Text } from "../../../ui/index.js";
4
+ import { Article, Div, Grid, Heading, OverflowRow, Pagination, Row, Span, Stack, Text } from "../../../ui/index.js";
5
5
  import { MediaImage } from "../../media/MediaImage.js";
6
6
  import { getDefaultLocale } from "../../../core/baseline-resolver.js";
7
7
  import { getMediaUrl } from "../../media/types/index.js";
@@ -11,7 +11,6 @@ const __P = {
11
11
  };
12
12
  const __O = {
13
13
  hidden: "overflow-hidden",
14
- xAuto: "overflow-x-auto",
15
14
  };
16
15
  const CLS_FEATURED_BADGE = "rounded-full bg-warning-surface px-[var(--appkit-space-2)] py-[var(--appkit-space-0-5)] text-warning dark:bg-warning-surface dark:text-warning";
17
16
  export function BlogCard({ post, href, onClick, className = "" }) {
@@ -33,7 +32,21 @@ export function BlogCard({ post, href, onClick, className = "" }) {
33
32
  return card;
34
33
  }
35
34
  export function BlogCategoryTabs({ categories, active, onSelect, labels = {}, }) {
36
- return (_jsxs(Div, { layout: "flex", gap: "2", className: `scrollbar-none ${__O.xAuto}`, padding: "b-2xs", children: [_jsx(Button, { onClick: () => onSelect(null), variant: !active ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-[var(--appkit-space-4)] py-[var(--appkit-space-1-5)] text-[length:var(--appkit-text-sm)] font-medium transition ${!active ? "bg-neutral-900 text-white" : "bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)] text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:bg-surface-hover"}`, children: labels.all ?? "All" }), categories.map((cat) => (_jsx(Button, { onClick: () => onSelect(cat), variant: active === cat ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-[var(--appkit-space-4)] py-[var(--appkit-space-1-5)] text-[length:var(--appkit-text-sm)] font-medium capitalize transition ${active === cat ? "bg-neutral-900 text-white" : "bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)] text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:bg-surface-hover"}`, children: labels[cat] ?? cat }, cat)))] }));
35
+ /*
36
+ * `ALL_ID` is a sentinel, not a category. It cannot be `""` because that is
37
+ * also `OverflowRow`'s "nothing selected" state, which would leave the
38
+ * collapsed trigger showing the placeholder instead of "All".
39
+ */
40
+ const ALL_ID = "__all__";
41
+ const items = [
42
+ { id: ALL_ID, label: labels.all ?? "All", onSelect: () => onSelect(null) },
43
+ ...categories.map((cat) => ({
44
+ id: cat,
45
+ label: labels[cat] ?? cat,
46
+ onSelect: () => onSelect(cat),
47
+ })),
48
+ ];
49
+ return (_jsx(OverflowRow, { items: items, ariaLabel: "Blog categories", activeId: active ?? ALL_ID, searchPlaceholder: "Search categories\u2026", noResultsText: "No matching category" }));
37
50
  }
38
51
  export function BlogListView({ posts, isLoading, totalPages = 1, currentPage = 1, total = 0, onPageChange, onPostClick, emptyLabel = "No posts found", slots, }) {
39
52
  if (isLoading) {
@@ -55,5 +55,5 @@ export function BlogPostView({ slug, initialData, labels = {}, renderImage, rend
55
55
  })
56
56
  : "";
57
57
  const coverImageUrl = getMediaUrl(post.coverImage);
58
- return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: `relative h-72 md:h-96 ${__O.hidden}`, children: [renderImage ? (renderImage(post)) : (_jsx(MediaImage, { src: coverImageUrl, alt: post.title, size: "hero" })), _jsx(Scrim, { direction: "bottom-up", intensity: "subtle", className: "absolute inset-0" })] })), _jsxs(Div, { className: "max-w-3xl mx-auto", paddingY: "y-3xl", paddingX: "x-md", children: [renderBlogPostHeader(post, date, labels), post.youtubeId && /^[A-Za-z0-9_-]{6,20}$/.test(post.youtubeId) && (_jsx(Div, { className: "mb-8", children: _jsx(Iframe, { src: `https://www.youtube-nocookie.com/embed/${post.youtubeId}`, title: `${post.title} — video`, aspect: "video", rounded: "lg" }) })), post.tags && post.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-8", children: post.tags.map((tag) => (_jsxs(Link, { href: `${String(ROUTES.PUBLIC.BLOG)}?tags=${encodeURIComponent(tag)}`, className: "inline-block px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] rounded-full bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)] hover:bg-primary/10 text-[var(--appkit-color-text-muted)] hover:text-primary text-[length:var(--appkit-text-xs)] font-medium transition-colors", children: ["#", tag] }, tag))) })), renderAuthorBio && _jsx(Div, { className: "mb-6", children: renderAuthorBio(post) }), _jsx(Div, { surface: "card", padding: "xl", className: "mb-12", children: renderContent ? renderContent(post) : (_jsx(RichText, { html: normalizeRichTextHtml(post.content ?? ""), proseClass: "prose max-w-none dark:prose-invert" })) }), _jsxs(Stack, { gap: "xl", children: [renderBlogPostRelated(related, labels?.relatedTitle ?? "Related Posts", renderRelatedCard), renderBlogPostRelated(relatedByTags, labels?.relatedByTagsTitle ?? "You might also like", renderRelatedCard), renderBlogPostRelated(relatedByAuthor, labels?.relatedByAuthorTitle ?? `More from ${post.authorName}`, renderRelatedCard)] }), renderBackButton && _jsx(Div, { border: "default", className: "mt-10 border-t", padding: "t-xl", children: renderBackButton() })] })] }));
58
+ return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: `relative h-72 md:h-96 ${__O.hidden}`, children: [renderImage ? (renderImage(post)) : (_jsx(MediaImage, { src: coverImageUrl, alt: post.title, size: "hero" })), _jsx(Scrim, { direction: "bottom-up", intensity: "subtle", className: "absolute inset-0" })] })), _jsxs(Div, { className: "max-w-3xl mx-auto", paddingY: "y-3xl", paddingX: "x-md", children: [renderBlogPostHeader(post, date, labels), post.youtubeId && /^[A-Za-z0-9_-]{6,20}$/.test(post.youtubeId) && (_jsx(Div, { className: "mb-8", children: _jsx(Iframe, { src: `https://www.youtube-nocookie.com/embed/${post.youtubeId}`, title: `${post.title} — video`, aspect: "video", rounded: "lg" }) })), post.tags && post.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-8", children: post.tags.map((tag) => (_jsxs(Link, { href: `${String(ROUTES.BLOG.LIST)}?tags=${encodeURIComponent(tag)}`, className: "inline-block px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] rounded-full bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)] hover:bg-primary/10 text-[var(--appkit-color-text-muted)] hover:text-primary text-[length:var(--appkit-text-xs)] font-medium transition-colors", children: ["#", tag] }, tag))) })), renderAuthorBio && _jsx(Div, { className: "mb-6", children: renderAuthorBio(post) }), _jsx(Div, { surface: "card", padding: "xl", className: "mb-12", children: renderContent ? renderContent(post) : (_jsx(RichText, { html: normalizeRichTextHtml(post.content ?? ""), proseClass: "prose max-w-none dark:prose-invert" })) }), _jsxs(Stack, { gap: "xl", children: [renderBlogPostRelated(related, labels?.relatedTitle ?? "Related Posts", renderRelatedCard), renderBlogPostRelated(relatedByTags, labels?.relatedByTagsTitle ?? "You might also like", renderRelatedCard), renderBlogPostRelated(relatedByAuthor, labels?.relatedByAuthorTitle ?? `More from ${post.authorName}`, renderRelatedCard)] }), renderBackButton && _jsx(Div, { border: "default", className: "mt-10 border-t", padding: "t-xl", children: renderBackButton() })] })] }));
59
59
  }
@@ -467,18 +467,18 @@ export declare const blogListParamsSchema: z.ZodObject<{
467
467
  sort?: string | undefined;
468
468
  page?: number | undefined;
469
469
  q?: string | undefined;
470
- perPage?: number | undefined;
471
470
  pageSize?: number | undefined;
472
471
  category?: "news" | "tips" | "guides" | "updates" | "community" | undefined;
473
472
  featured?: boolean | undefined;
474
473
  tags?: string | undefined;
474
+ perPage?: number | undefined;
475
475
  }, {
476
476
  sort?: string | undefined;
477
477
  page?: number | undefined;
478
478
  q?: string | undefined;
479
- perPage?: number | undefined;
480
479
  pageSize?: number | undefined;
481
480
  category?: "news" | "tips" | "guides" | "updates" | "community" | undefined;
482
481
  featured?: boolean | undefined;
483
482
  tags?: string | undefined;
483
+ perPage?: number | undefined;
484
484
  }>;
@@ -33,7 +33,7 @@ export async function GET(request) {
33
33
  filters,
34
34
  sort,
35
35
  page,
36
- perPage: pageSize,
36
+ pageSize: pageSize,
37
37
  });
38
38
  const totalPages = Math.max(1, Math.ceil(result.total / pageSize));
39
39
  return NextResponse.json({
@@ -1,4 +1,3 @@
1
- import type { DocumentSnapshot } from "firebase-admin/firestore";
2
1
  /**
3
2
  * Personal Catalogue Repository (Feature B).
4
3
  */
@@ -14,16 +13,17 @@ export interface CatalogueWriteContext {
14
13
  }
15
14
  export declare class CatalogueRepository extends BaseRepository<CatalogueItemDocument> {
16
15
  /**
17
- * `ownerEmail` only — NOT `ownerName`.
16
+ * 🛑 DEAD as written: `CatalogueItemDocument` has no `ownerEmail`.
18
17
  *
19
- * Per decision D1 names stay partial-match searchable, and catalogue items are
20
- * searchable by owner in the admin approvals queue. `CATALOGUE_HISTORY_PII_FIELDS`
21
- * lists both, but that constant scrubs status *history*, which has no search
22
- * requirement — the two lists are intentionally different.
18
+ * Kept rather than deleted because it is the declaration that would start
19
+ * working the moment an owner email is added to the document, and deleting
20
+ * it would hand that future field plaintext storage by default. The reasoning
21
+ * it used to carry — "`ownerEmail` only, NOT `ownerName`, because D1 keeps
22
+ * names searchable" — described a choice between two fields that neither
23
+ * exist nor can arrive through `CatalogueItemCreateInput`.
23
24
  */
24
25
  protected piiFields: readonly ["ownerEmail"];
25
26
  /** Decrypt on read so callers see the shape they wrote. */
26
- protected mapDoc<D = CatalogueItemDocument>(snap: DocumentSnapshot): D;
27
27
  constructor();
28
28
  create(input: CatalogueItemCreateInput): Promise<CatalogueItemDocument>;
29
29
  /**