@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
@@ -0,0 +1,150 @@
1
+ /**
2
+ * downscaleImageFile — bound an image's pixel dimensions and re-encode it
3
+ * before it ever leaves the browser.
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * Until 2026-10-19 the ONLY client-side resize in the whole upload path was
8
+ * inside `ImageEditor` (`modals/ImageEditor.tsx`), which runs only when the
9
+ * user opens the crop editor. Everything else stored the original bytes: a 9 MB
10
+ * phone photo was stored at 9 MB, watermarked at 9 MB, and served at 9 MB into
11
+ * a 64px thumbnail, because `/api/media/[...slug]` resizes nothing and
12
+ * `next/image` optimisation was off.
13
+ *
14
+ * That is the shape of the cost that suspended this project with HTTP 402 for
15
+ * Fast Origin Transfer at 5.25x its cap (Root Cause #104). Bounding the master
16
+ * at upload is the one fix that helps every downstream consumer at once.
17
+ *
18
+ * ## Why 2048
19
+ *
20
+ * Measured (docs/research/competitor-crawl-2026-10/images.md): worldhobbyshop
21
+ * serves a 2048x2048 master to photoswipe for zoom, and WordPress's own
22
+ * `-scaled` threshold is 2560. 2048 survives our lightbox's 300% zoom over a
23
+ * ~680px display box with detail to spare, and is 1/4 the pixels of a 4096px
24
+ * phone capture.
25
+ *
26
+ * ## Four cases where it deliberately returns the ORIGINAL file
27
+ *
28
+ * 1. **Not a raster image we own the pipeline for** — anything outside
29
+ * `CONVERTIBLE_MIMES`. SVG is never rasterised (it is also not in
30
+ * `ALLOWED_IMAGE_MIMES`), and GIF is never touched because re-encoding an
31
+ * animated GIF to a still WebP silently destroys the animation.
32
+ * 2. **Already small enough AND already a compact format** — re-encoding a
33
+ * 1200px WebP buys nothing and loses a generation of quality.
34
+ * 3. **The re-encode came out BIGGER.** A small, already-optimised JPEG can
35
+ * grow under WebP q0.9. Shipping the larger file would make this helper a
36
+ * pessimisation, so the original wins.
37
+ * 4. **Anything threw.** 🛑 Fail OPEN. A canvas decode failure, a tainted
38
+ * canvas, a browser without `createImageBitmap` — none of those are a reason
39
+ * to block a seller's upload. The server still enforces `MAX_BYTES[kind]`,
40
+ * so the worst case is the pre-2026-10-19 behaviour, not a hole.
41
+ */
42
+ import { normalizeError } from "../../../errors/normalize.js";
43
+ /** Longest edge, in CSS pixels, of the stored master. */
44
+ export const IMAGE_DOWNSCALE_MAX_EDGE = 2048;
45
+ /** Output MIME for a re-encoded master. */
46
+ export const IMAGE_DOWNSCALE_FORMAT = "image/webp";
47
+ /** Output quality for a re-encoded master. */
48
+ export const IMAGE_DOWNSCALE_QUALITY = 0.9;
49
+ /**
50
+ * MIMEs this helper is willing to decode and re-encode.
51
+ *
52
+ * 🛑 Deliberately NOT derived from `ALLOWED_IMAGE_MIMES` — that list is about
53
+ * what the server will STORE, this one is about what a canvas may safely
54
+ * round-trip. `image/gif` is in the first and must stay out of the second
55
+ * (animation loss), and the two lists answering different questions is exactly
56
+ * why one must not be spelled in terms of the other.
57
+ */
58
+ const CONVERTIBLE_MIMES = new Set(["image/jpeg", "image/jpg", "image/png", "image/webp"]);
59
+ /** Formats already compact enough that a same-size re-encode is pointless. */
60
+ const ALREADY_COMPACT = new Set(["image/webp", "image/avif"]);
61
+ function replaceExtension(name, mime) {
62
+ const ext = mime.split("/")[1] || "webp";
63
+ const dot = name.lastIndexOf(".");
64
+ const stem = dot > 0 ? name.slice(0, dot) : name;
65
+ return `${stem}.${ext}`;
66
+ }
67
+ async function decode(file) {
68
+ if (typeof createImageBitmap === "function") {
69
+ const bitmap = await createImageBitmap(file);
70
+ return { width: bitmap.width, height: bitmap.height, source: bitmap, release: () => bitmap.close() };
71
+ }
72
+ const url = URL.createObjectURL(file);
73
+ try {
74
+ const img = await new Promise((resolve, reject) => {
75
+ const el = new Image();
76
+ el.onload = () => resolve(el);
77
+ el.onerror = () => reject(new Error("image decode failed"));
78
+ el.src = url;
79
+ });
80
+ return {
81
+ width: img.naturalWidth,
82
+ height: img.naturalHeight,
83
+ source: img,
84
+ release: () => URL.revokeObjectURL(url),
85
+ };
86
+ }
87
+ catch (err) {
88
+ URL.revokeObjectURL(url);
89
+ throw err;
90
+ }
91
+ }
92
+ export async function downscaleImageFile(file, options = {}) {
93
+ const maxEdge = options.maxEdge ?? IMAGE_DOWNSCALE_MAX_EDGE;
94
+ const format = options.format ?? IMAGE_DOWNSCALE_FORMAT;
95
+ const quality = options.quality ?? IMAGE_DOWNSCALE_QUALITY;
96
+ // Case 1 — not something we are willing to round-trip through a canvas.
97
+ if (!CONVERTIBLE_MIMES.has(file.type))
98
+ return file;
99
+ let decoded = null;
100
+ try {
101
+ decoded = await decode(file);
102
+ const { width, height, source } = decoded;
103
+ if (!width || !height)
104
+ return file;
105
+ const longest = Math.max(width, height);
106
+ const scale = longest > maxEdge ? maxEdge / longest : 1;
107
+ // Case 2 — small enough already, and re-encoding would only lose a generation.
108
+ if (scale === 1 && ALREADY_COMPACT.has(file.type))
109
+ return file;
110
+ const targetW = Math.max(1, Math.round(width * scale));
111
+ const targetH = Math.max(1, Math.round(height * scale));
112
+ const canvas = document.createElement("canvas");
113
+ canvas.width = targetW;
114
+ canvas.height = targetH;
115
+ const ctx = canvas.getContext("2d");
116
+ if (!ctx)
117
+ return file;
118
+ ctx.imageSmoothingQuality = "high";
119
+ ctx.drawImage(source, 0, 0, targetW, targetH);
120
+ const blob = await new Promise((resolve) => canvas.toBlob(resolve, format, quality));
121
+ if (!blob || blob.size === 0)
122
+ return file;
123
+ // Case 3 — the re-encode is bigger than what we started with.
124
+ if (blob.size >= file.size && scale === 1)
125
+ return file;
126
+ return new File([blob], replaceExtension(file.name, format), {
127
+ type: format,
128
+ lastModified: file.lastModified,
129
+ });
130
+ }
131
+ catch (err) {
132
+ void normalizeError(err);
133
+ /*
134
+ * Case 4 — fail open. See the header.
135
+ *
136
+ * Reported rather than swallowed silently: `normalizeError` fires the
137
+ * observability hook, so a browser that cannot decode what it just accepted
138
+ * is visible instead of merely producing a suspiciously large upload. The
139
+ * upload itself still proceeds, with the original file.
140
+ *
141
+ * 🛑 The call sits on the line directly below the `catch` on purpose —
142
+ * `audit-catch-normalize` only looks a few lines ahead, so putting this
143
+ * comment first was enough to make it read as an unnormalised catch.
144
+ */
145
+ return file;
146
+ }
147
+ finally {
148
+ decoded?.release();
149
+ }
150
+ }
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useRef, useState } from "react";
4
+ import { useSearchParams } from "next/navigation.js";
4
5
  import { useAuth } from "../../../react/contexts/SessionContext.js";
5
6
  import { useConversationThread, useSendMessage, useMarkConversationRead, useBlockConversation, } from "../hooks/useMessages.js";
6
7
  import { Div } from "../../../ui/components/Div.js";
@@ -10,6 +11,10 @@ import { Button } from "../../../ui/components/Button.js";
10
11
  import { FieldTextarea } from "../../../ui/forms/FieldTextarea.js";
11
12
  import { EmptyState } from "../../../ui/components/EmptyState.js";
12
13
  import { MediaImage } from "../../media/MediaImage.js";
14
+ import { TextLink } from "../../../ui/components/TextLink.js";
15
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry.js";
16
+ import { isListingType } from "../../../_internal/shared/listing-types/feature-flags.js";
17
+ import { formatCurrency } from "../../../utils/number.formatter.js";
13
18
  function newClientMessageId() {
14
19
  // crypto.randomUUID is available in every browser this app targets; a
15
20
  // retry reuses the SAME id generated at compose time, not a fresh one per
@@ -22,7 +27,32 @@ function MessageBubble({ message, isSelf }) {
22
27
  if (message.deletedAt) {
23
28
  return (_jsx(Row, { justify: isSelf ? "end" : "start", children: _jsx(Text, { size: "sm", color: "muted", className: "italic", children: "Message deleted" }) }));
24
29
  }
25
- return (_jsx(Row, { justify: isSelf ? "end" : "start", children: _jsxs(Stack, { gap: "xs", surface: isSelf ? "interactive" : "muted", padding: "sm", rounded: "lg", className: "max-w-[75%]", children: [message.productRef && (_jsxs(Row, { gap: "sm", surface: "card", padding: "xs", rounded: "md", children: [message.productRef.image && (_jsx(Div, { className: "relative h-10 w-10 flex-shrink-0", rounded: "default", overflow: "hidden", children: _jsx(MediaImage, { src: message.productRef.image, alt: message.productRef.title, size: "thumbnail" }) })), _jsx(Text, { size: "xs", weight: "semibold", className: "truncate", children: message.productRef.title })] })), _jsx(Text, { size: "sm", className: "whitespace-pre-wrap break-words", children: message.body })] }) }));
30
+ return (_jsx(Row, { justify: isSelf ? "end" : "start", children: _jsxs(Stack, { gap: "xs", surface: isSelf ? "interactive" : "muted", padding: "sm", rounded: "lg", className: "max-w-[75%]", children: [message.productRef && (
31
+ /*
32
+ * A LINK, and it shows the price.
33
+ *
34
+ * `MessageProductRef` captures `price` and this block ignored it —
35
+ * a declared field with no reader (Root Cause #51's shape) — and the
36
+ * card was not clickable, so the one thing a buyer and seller both
37
+ * want from it (open the item) was missing. The snapshot is taken at
38
+ * send time on purpose, so it keeps reading correctly after the
39
+ * listing changes or is deleted.
40
+ *
41
+ * No `GatedPrice` here: chat requires auth, so there is no signed-out
42
+ * viewer to gate, and the price shown is the one the buyer was
43
+ * looking at when they asked.
44
+ */
45
+ _jsx(TextLink, { variant: "inherit", href: String(
46
+ /*
47
+ * Narrowed, not cast. The snapshot stores `listingType` as a
48
+ * plain `string` (a message written before the field existed has
49
+ * none), and anything unrecognised falls back to the `standard`
50
+ * route — the correct reading for those older rows and for a type
51
+ * that has since been removed.
52
+ */
53
+ pluginFor(isListingType(message.productRef.listingType)
54
+ ? message.productRef.listingType
55
+ : "standard").detailRoute(message.productRef.productId)), layout: "flex-col", rounded: "md", children: _jsxs(Row, { gap: "sm", surface: "card", padding: "xs", rounded: "md", align: "center", children: [message.productRef.image && (_jsx(Div, { className: "relative h-10 w-10 flex-shrink-0", rounded: "default", overflow: "hidden", children: _jsx(MediaImage, { src: message.productRef.image, alt: message.productRef.title, size: "thumbnail" }) })), _jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { size: "xs", weight: "semibold", className: "truncate", children: message.productRef.title }), typeof message.productRef.price === "number" && (_jsx(Text, { size: "xs", color: "muted", children: formatCurrency(message.productRef.price, "INR") }))] })] }) })), _jsx(Text, { size: "sm", className: "whitespace-pre-wrap break-words", children: message.body })] }) }));
26
56
  }
27
57
  export function ConversationThreadView({ conversationId }) {
28
58
  const { user, loading } = useAuth();
@@ -31,6 +61,17 @@ export function ConversationThreadView({ conversationId }) {
31
61
  const markRead = useMarkConversationRead();
32
62
  const block = useBlockConversation();
33
63
  const [draft, setDraft] = useState("");
64
+ /*
65
+ * The listing the buyer arrived from, attached to the NEXT message and then
66
+ * cleared — so the card appears once, on the message that asked about it,
67
+ * rather than on every subsequent reply in the thread.
68
+ *
69
+ * Read from `?product=` rather than held on the conversation because the
70
+ * schema is explicit that a product belongs to a message: one thread per
71
+ * pair of people, however many items they discuss.
72
+ */
73
+ const searchParams = useSearchParams();
74
+ const [attachedProductId, setAttachedProductId] = useState(() => searchParams.get("product") ?? undefined);
34
75
  const markedRef = useRef(false);
35
76
  const bottomRef = useRef(null);
36
77
  useEffect(() => {
@@ -57,8 +98,10 @@ export function ConversationThreadView({ conversationId }) {
57
98
  if (!trimmed)
58
99
  return;
59
100
  const clientMessageId = newClientMessageId();
60
- send({ body: trimmed, clientMessageId });
101
+ send({ body: trimmed, clientMessageId, productId: attachedProductId });
61
102
  setDraft("");
103
+ // Once attached, it is spent — the next message is a plain reply.
104
+ setAttachedProductId(undefined);
62
105
  };
63
106
  // Newest-first from the API, so reverse for display (oldest at top).
64
107
  const items = data ? [...data.items].reverse() : [];
@@ -1,5 +1,19 @@
1
1
  export interface MessageSellerButtonProps {
2
2
  storeId: string;
3
+ /**
4
+ * The listing this button was clicked from, carried into the thread so the
5
+ * buyer's first message renders as a PRODUCT CARD.
6
+ *
7
+ * 🛑 Without it the whole card pipeline is unreachable. `sendMessage` builds
8
+ * a `MessageProductRef` from a `productId`, `MessageBubble` renders it, and
9
+ * `POST /api/messages/[conversationId]` accepts it — but the ONLY caller of
10
+ * this button is the product detail page, which had the id right there and
11
+ * never passed it. So a buyer landed in a bare thread and had to TYPE which
12
+ * item they meant: a block of words where a card belongs. Root Cause #103's
13
+ * shape — a feature complete in every direction except the one that puts
14
+ * data in.
15
+ */
16
+ productId?: string;
3
17
  /** Render nothing when the viewer owns this store — comparing storeId
4
18
  * client-side is an optional convenience; the server refuses it either way. */
5
19
  isOwnStore?: boolean;
@@ -14,4 +28,4 @@ export interface MessageSellerButtonProps {
14
28
  * Absent entirely when chat is off or the viewer is the store's own owner —
15
29
  * never rendered-but-disabled, same discipline as the nav icon.
16
30
  */
17
- export declare function MessageSellerButton({ storeId, isOwnStore, className }: MessageSellerButtonProps): import("react").JSX.Element | null;
31
+ export declare function MessageSellerButton({ storeId, productId, isOwnStore, className }: MessageSellerButtonProps): import("react").JSX.Element | null;
@@ -16,7 +16,7 @@ import { ACTIONS } from "../../../_internal/shared/actions/action-registry.js";
16
16
  * Absent entirely when chat is off or the viewer is the store's own owner —
17
17
  * never rendered-but-disabled, same discipline as the nav icon.
18
18
  */
19
- export function MessageSellerButton({ storeId, isOwnStore, className }) {
19
+ export function MessageSellerButton({ storeId, productId, isOwnStore, className }) {
20
20
  const router = useRouter();
21
21
  const { user } = useAuth();
22
22
  const { data: settings } = useSiteSettings();
@@ -26,7 +26,15 @@ export function MessageSellerButton({ storeId, isOwnStore, className }) {
26
26
  return (_jsx(Button, { action: ACTIONS.PRODUCT["message-seller"], size: "sm", isLoading: isPending, className: className, onClick: () => {
27
27
  mutate({ storeId }, {
28
28
  onSuccess: (conversation) => {
29
- router.push(String(ROUTES.USER.MESSAGE_THREAD(conversation.id)));
29
+ /*
30
+ * `?product=` rather than a new conversation per listing. The
31
+ * schema is explicit that a product attaches to a MESSAGE, never
32
+ * to the thread — "a buyer with three questions about three items
33
+ * wants one thread, not three" — so the id rides in the URL and
34
+ * the composer attaches it to the next message sent.
35
+ */
36
+ const href = String(ROUTES.USER.MESSAGE_THREAD(conversation.id));
37
+ router.push(productId ? `${href}?product=${encodeURIComponent(productId)}` : href);
30
38
  },
31
39
  });
32
40
  } }));
@@ -44,6 +44,21 @@ export interface MessageProductRef {
44
44
  productId: string;
45
45
  title: string;
46
46
  image?: string;
47
+ /**
48
+ * 🛑 Required for the card to LINK anywhere correct.
49
+ *
50
+ * Nine listing types have five different detail routes
51
+ * (`/auctions/…`, `/pre-orders/…`, `/prize-draws/…`, `/classified/…`, …) and
52
+ * `pluginFor(type).detailRoute()` is the only thing that knows which. A card
53
+ * that hardcodes `/products/{slug}` sends an auction to the standard product
54
+ * page — which is Root Cause #48 exactly: a doc→card mapper dropping
55
+ * `listingType` and the link going wrong because of the one field it lost.
56
+ *
57
+ * Optional only because a message sent before this field existed has none;
58
+ * `normalizeListingType` resolves an absent value to `"standard"`, which is
59
+ * the correct reading for those rows.
60
+ */
61
+ listingType?: string;
47
62
  /** Omitted for a guest-gated listing snapshot taken while signed out is not
48
63
  * possible here — chat requires auth — but still optional: a product can be
49
64
  * archived/deleted between send and render. */
@@ -18,8 +18,10 @@ export function useOrders(params = {}, opts) {
18
18
  sp.set("sort", params.sort);
19
19
  if (params.page)
20
20
  sp.set("page", String(params.page));
21
- if (params.perPage)
22
- sp.set("perPage", String(params.perPage));
21
+ // `pageSize` is what the route prefers; it keeps reading `perPage` only for
22
+ // links built before the rename, so there is no reason to emit the old name.
23
+ if (params.pageSize)
24
+ sp.set("pageSize", String(params.pageSize));
23
25
  const qs = sp.toString();
24
26
  // ORDER_ENDPOINTS.LIST ("/api/orders") has no GET route handler — every
25
27
  // real caller of this hook wants the current user's own orders, served by
@@ -2,7 +2,7 @@ import type { JsonValue } from "../../../schemas/types";
2
2
  import type { DocumentReference, WriteBatch } from "firebase-admin/firestore";
3
3
  import type { FirebaseSieveResult, SieveModel } from "../../../providers/db-firebase";
4
4
  import { BaseRepository, parseSieveDateValue } from "../../../providers/db-firebase";
5
- import { type OrderCreateInput, type OrderDocument, type OrderRefundEvent } from "../schemas";
5
+ import { type OrderCreateInput, type OrderDocument, type OrderPlain, type OrderRefundEvent } from "../schemas";
6
6
  import { type HistoryActor, type FieldChange } from "../../../_internal/shared/history/index";
7
7
  import type { OrderStatus, PaymentStatus } from "../types";
8
8
  import { type PaymentReviewQueueMode } from "../constants/payment-window";
@@ -26,7 +26,6 @@ export interface OrderWriteContext {
26
26
  }
27
27
  declare class OrderRepository extends BaseRepository<OrderDocument> {
28
28
  constructor();
29
- private decryptOrder;
30
29
  /**
31
30
  * Declared, not hand-rolled.
32
31
  *
@@ -39,8 +38,20 @@ declare class OrderRepository extends BaseRepository<OrderDocument> {
39
38
  * call.
40
39
  */
41
40
  protected piiFields: readonly ["userName", "userEmail", "sellerEmail"];
42
- protected mapDoc<D = OrderDocument>(snap: import("../../../providers/db-firebase").DocumentSnapshot): D;
43
- create(input: OrderCreateInput): Promise<OrderDocument>;
41
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
42
+ revealOrder(doc: OrderDocument): OrderPlain;
43
+ /** As `revealOrder`, for a list read. */
44
+ revealOrders(docs: readonly OrderDocument[]): OrderPlain[];
45
+ /**
46
+ * Masked PII — **the default for any surface that only needs to identify a
47
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
48
+ * ciphertext by design, so passing a stored field straight in would return
49
+ * "Anonymous" for every row.
50
+ */
51
+ maskedOrder(doc: OrderDocument): OrderPlain;
52
+ /** As `maskedOrder`, for a list read. */
53
+ maskedOrders(docs: readonly OrderDocument[]): OrderPlain[];
54
+ createOrder(input: OrderCreateInput): Promise<OrderPlain>;
44
55
  findByUser(userId: string): Promise<OrderDocument[]>;
45
56
  findByProduct(productId: string): Promise<OrderDocument[]>;
46
57
  findByStatus(status: OrderStatus): Promise<OrderDocument[]>;
@@ -3,7 +3,7 @@ import { planSearchTxt, beginSearchWindow, emptySearchResult, } from "../../../u
3
3
  import { normalizeError } from "../../../errors/normalize.js";
4
4
  import { DatabaseError, NotFoundError } from "../../../errors/index.js";
5
5
  import { BaseRepository, prepareForFirestore, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
6
- import { decryptPiiFields, ORDER_PII_FIELDS, } from "../../../security/index.js";
6
+ import { maskPii, revealPii, ORDER_PII_FIELDS, } from "../../../security/index.js";
7
7
  import { serverTimestamp, arrayUnion } from "../../../contracts/field-ops.js";
8
8
  import { createOrderId, ORDER_COLLECTION, ORDER_TRACKED_FIELDS, OrderStatusValues, } from "../schemas/index.js";
9
9
  import { withHistory } from "../../../_internal/shared/history/index.js";
@@ -37,18 +37,49 @@ class OrderRepository extends BaseRepository {
37
37
  */
38
38
  this.piiFields = ORDER_PII_FIELDS;
39
39
  }
40
- decryptOrder(doc) {
41
- return decryptPiiFields(doc, [
42
- ...ORDER_PII_FIELDS,
43
- ]);
40
+ /*
41
+ * 🛑 `mapDoc` is NOT overridden, and that absence IS the change.
42
+ *
43
+ * It used to decrypt on every read, so ciphertext never left the database
44
+ * and every caller handled plaintext without ever saying so. Following
45
+ * `SiteSettingsRepository`: reads return what Firestore holds, and plaintext
46
+ * requires one of the two named methods below.
47
+ *
48
+ * A convention would not hold this. `OrderDocument`'s PII fields are
49
+ * `Encrypted<string>`, assignable to nothing that wants a plain `string`, so
50
+ * a reader that skips both accessors is a compile error naming file and line.
51
+ */
52
+ /** Plaintext PII. **Opt-in and named** — shows up in review and in a grep. */
53
+ revealOrder(doc) {
54
+ return revealPii(doc, ORDER_PII_FIELDS);
44
55
  }
45
- mapDoc(snap) {
46
- const raw = super.mapDoc(snap);
47
- return this.decryptOrder(raw);
56
+ /** As `revealOrder`, for a list read. */
57
+ revealOrders(docs) {
58
+ return docs.map((d) => this.revealOrder(d));
48
59
  }
49
- async create(input) {
60
+ /**
61
+ * Masked PII — **the default for any surface that only needs to identify a
62
+ * row to a human.** Decrypts first, then masks: the mask helpers refuse
63
+ * ciphertext by design, so passing a stored field straight in would return
64
+ * "Anonymous" for every row.
65
+ */
66
+ maskedOrder(doc) {
67
+ return maskPii(doc, ORDER_PII_FIELDS);
68
+ }
69
+ /** As `maskedOrder`, for a list read. */
70
+ maskedOrders(docs) {
71
+ return docs.map((d) => this.maskedOrder(d));
72
+ }
73
+ /*
74
+ * 🛑 NOT an `override`. It returns the plaintext it was handed rather than
75
+ * re-reading (a read-after-write costs a Firestore read per order), so the
76
+ * return is `OrderPlain` — not assignable to the base's `Promise<T>`, and
77
+ * correctly so, because the two differ.
78
+ */
79
+ async createOrder(input) {
50
80
  const orderDate = new Date();
51
81
  const id = createOrderId(input.quantity, orderDate);
82
+ // Plain in, ciphertext out — `applyWriteHooks` encrypts below.
52
83
  const orderData = {
53
84
  ...input,
54
85
  orderDate,
@@ -116,6 +147,7 @@ class OrderRepository extends BaseRepository {
116
147
  });
117
148
  // `null` means no tracked field actually changed — write the patch as-is
118
149
  // so an untracked update never grows the array.
150
+ // Plain: this is a write payload and `update` encrypts.
119
151
  return this.update(orderId, (withEntry ?? patch));
120
152
  }
121
153
  async updateStatus(orderId, status, additionalData, ctx) {
@@ -172,7 +204,7 @@ class OrderRepository extends BaseRepository {
172
204
  .orderBy(ORDER_FIELDS.CREATED_AT, "asc")
173
205
  .limit(200)
174
206
  .get();
175
- return snap.docs.map((doc) => this.decryptOrder({ id: doc.id, ...doc.data() }));
207
+ return snap.docs.map((doc) => ({ id: doc.id, ...doc.data() }));
176
208
  }
177
209
  async updatePaymentStatus(orderId, paymentStatus, paymentId, ctx) {
178
210
  return this.updateWithHistory(orderId, {
@@ -202,7 +234,7 @@ class OrderRepository extends BaseRepository {
202
234
  .where(ORDER_FIELDS.ORDER_DATE, ">=", new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000))
203
235
  .orderBy(ORDER_FIELDS.ORDER_DATE, "desc")
204
236
  .get();
205
- return snapshot.docs.map((doc) => this.decryptOrder({
237
+ return snapshot.docs.map((doc) => ({
206
238
  id: doc.id,
207
239
  ...doc.data(),
208
240
  }));
@@ -412,7 +444,7 @@ class OrderRepository extends BaseRepository {
412
444
  .where("paymentBatchId", "==", batchId)
413
445
  .limit(20)
414
446
  .get();
415
- return snap.docs.map((d) => this.decryptOrder({ id: d.id, ...d.data() }));
447
+ return snap.docs.map((d) => ({ id: d.id, ...d.data() }));
416
448
  }
417
449
  /**
418
450
  * Fetch every order recorded against a single gateway payment id (e.g. a
@@ -428,7 +460,7 @@ class OrderRepository extends BaseRepository {
428
460
  .where(ORDER_FIELDS.PAYMENT_ID, "==", paymentId)
429
461
  .limit(20)
430
462
  .get();
431
- return snap.docs.map((d) => this.decryptOrder({ id: d.id, ...d.data() }));
463
+ return snap.docs.map((d) => ({ id: d.id, ...d.data() }));
432
464
  }
433
465
  /**
434
466
  * Cloud Functions: find pending orders created before a timeout threshold.
@@ -447,7 +479,7 @@ class OrderRepository extends BaseRepository {
447
479
  return snap.docs.map((d) => ({
448
480
  id: d.id,
449
481
  ref: d.ref,
450
- data: this.decryptOrder({ id: d.id, ...d.data() }),
482
+ data: { id: d.id, ...d.data() },
451
483
  }));
452
484
  }
453
485
  /**
@@ -470,7 +502,7 @@ class OrderRepository extends BaseRepository {
470
502
  .map((d) => ({
471
503
  id: d.id,
472
504
  ref: d.ref,
473
- data: this.decryptOrder({ id: d.id, ...d.data() }),
505
+ data: { id: d.id, ...d.data() },
474
506
  }))
475
507
  .filter((entry) => !entry.data.paymentProofUrl);
476
508
  }
@@ -495,7 +527,7 @@ class OrderRepository extends BaseRepository {
495
527
  .map((d) => ({
496
528
  id: d.id,
497
529
  ref: d.ref,
498
- data: this.decryptOrder({ id: d.id, ...d.data() }),
530
+ data: { id: d.id, ...d.data() },
499
531
  }))
500
532
  .filter((entry) => !!entry.data.paymentProofUrl && !entry.data.paymentReviewOutcome);
501
533
  }
@@ -537,7 +569,7 @@ class OrderRepository extends BaseRepository {
537
569
  .limit(PAYMENT_REVIEW_QUEUE_SCAN_LIMIT)
538
570
  .get();
539
571
  const matches = snap.docs
540
- .map((d) => this.decryptOrder({ id: d.id, ...d.data() }))
572
+ .map((d) => ({ id: d.id, ...d.data() }))
541
573
  .filter((order) => MANUAL_PAYMENT_METHODS.includes(order.paymentMethod ?? ""))
542
574
  .filter((order) => mode === "awaiting_proof"
543
575
  ? !order.paymentProofUrl
@@ -573,7 +605,7 @@ class OrderRepository extends BaseRepository {
573
605
  .map((d) => ({
574
606
  id: d.id,
575
607
  ref: d.ref,
576
- data: this.decryptOrder({ id: d.id, ...d.data() }),
608
+ data: { id: d.id, ...d.data() },
577
609
  }))
578
610
  .filter((o) => !o.data.emiEnabled || o.data.emiComplete);
579
611
  }
@@ -596,7 +628,7 @@ class OrderRepository extends BaseRepository {
596
628
  .map((d) => ({
597
629
  id: d.id,
598
630
  ref: d.ref,
599
- data: this.decryptOrder({ id: d.id, ...d.data() }),
631
+ data: { id: d.id, ...d.data() },
600
632
  }))
601
633
  .filter((o) => !o.data.emiEnabled || o.data.emiComplete);
602
634
  }
@@ -616,7 +648,7 @@ class OrderRepository extends BaseRepository {
616
648
  return snap.docs.map((d) => ({
617
649
  id: d.id,
618
650
  ref: d.ref,
619
- data: this.decryptOrder({ id: d.id, ...d.data() }),
651
+ data: { id: d.id, ...d.data() },
620
652
  }));
621
653
  }
622
654
  /**
@@ -8,6 +8,7 @@ import type { ListingType } from "../../products/types";
8
8
  import type { StatusChangeEntry } from "../../../_internal/shared/history/index";
9
9
  import type { ReturnReason } from "../../../_internal/shared/features/orders/return-reasons";
10
10
  import type { ReturnCustodyState } from "../../../_internal/shared/features/returns/custody";
11
+ import type { Encrypted, Plaintext } from "../../../security/encrypted";
11
12
  export interface OrderSourceStandard {
12
13
  path: "standard";
13
14
  listPrice: number;
@@ -320,14 +321,24 @@ export interface AppliedOrderDiscount {
320
321
  scope?: "admin" | "seller";
321
322
  storeId?: string;
322
323
  }
324
+ /**
325
+ * `OrderDocument` with its PII as plain `string` — what the named repository
326
+ * accessors return, and what a WRITE path accepts (the repository encrypts).
327
+ *
328
+ * `Plaintext<T>` is the one definition of this shape; see `security/encrypted.ts`.
329
+ * It is deliberately NOT distinguishable from a MASKED value — `maskPii`
330
+ * returns plain strings too, and no type can express "these characters are
331
+ * asterisks". The distinction is which named method you called.
332
+ */
333
+ export type OrderPlain = Plaintext<OrderDocument>;
323
334
  export interface OrderDocument extends BaseDocument {
324
335
  /** Word-prefix search tokens. Derived on write; never fed by a PII field. */
325
336
  searchTxt?: string[];
326
337
  productId: string;
327
338
  productTitle: string;
328
339
  userId: string;
329
- userName: string;
330
- userEmail: string;
340
+ userName: Encrypted<string>;
341
+ userEmail: Encrypted<string>;
331
342
  storeId?: string;
332
343
  storeName?: string;
333
344
  items?: OrderDocumentItem[];
@@ -778,9 +789,9 @@ export declare const ORDER_UPDATABLE_FIELDS: readonly ["notes", "shippingAddress
778
789
  * which is every single write — and exhaust the FIFO cap within days.
779
790
  */
780
791
  export declare const ORDER_TRACKED_FIELDS: readonly ["status", "paymentStatus", "paymentReviewOutcome", "trackingNumber", "cancellationReason"];
781
- export type OrderCreateInput = Omit<OrderDocument, "id" | "createdAt" | "updatedAt" | "orderDate">;
792
+ export type OrderCreateInput = Omit<OrderPlain, "id" | "createdAt" | "updatedAt" | "orderDate">;
782
793
  export type OrderUpdateInput = Partial<Pick<OrderDocument, (typeof ORDER_UPDATABLE_FIELDS)[number]>>;
783
- export type OrderAdminUpdateInput = Partial<Omit<OrderDocument, "id" | "createdAt">>;
794
+ export type OrderAdminUpdateInput = Partial<Omit<OrderPlain, "id" | "createdAt">>;
784
795
  export declare const orderQueryHelpers: {
785
796
  readonly byUser: (userId: string) => readonly ["userId", "==", string];
786
797
  readonly byStore: (storeId: string) => readonly ["storeId", "==", string];