@mohasinac/appkit 4.61.0 → 4.62.1

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 (281) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +19 -3
  3. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +1 -1
  4. package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +1 -1
  5. package/dist/_internal/server/features/checkout/actions.d.ts +80 -0
  6. package/dist/_internal/server/features/checkout/actions.js +542 -26
  7. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  8. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  9. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  10. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  11. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  12. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  13. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  14. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  15. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  16. package/dist/_internal/server/features/orders/actions.js +81 -8
  17. package/dist/_internal/server/features/orders/adapters.js +33 -0
  18. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  19. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  20. package/dist/_internal/server/features/points/award.js +46 -4
  21. package/dist/_internal/server/features/refunds/actions.js +26 -0
  22. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  23. package/dist/_internal/server/features/shipping/courier-block.js +239 -0
  24. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  25. package/dist/_internal/server/features/site-settings/adapters.js +15 -0
  26. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  27. package/dist/_internal/server/features/stores/adapters.js +51 -0
  28. package/dist/_internal/server/functions/scheduled.js +38 -1
  29. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +9 -2
  30. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  31. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  32. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  33. package/dist/_internal/server/jobs/core/index.js +2 -1
  34. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  35. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  36. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  37. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +62 -0
  38. package/dist/_internal/server/jobs/core/paymentReconcile.js +87 -97
  39. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  40. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  41. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  42. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +10 -2
  43. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  44. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  45. package/dist/_internal/shared/actions/action-registry.js +177 -9
  46. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  47. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  48. package/dist/_internal/shared/checkout/order-math.d.ts +145 -0
  49. package/dist/_internal/shared/checkout/order-math.js +173 -0
  50. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  51. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  52. package/dist/_internal/shared/checkout/split.d.ts +87 -0
  53. package/dist/_internal/shared/checkout/split.js +100 -0
  54. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  55. package/dist/_internal/shared/content/disclaimers.js +217 -0
  56. package/dist/_internal/shared/content/published-values.d.ts +88 -0
  57. package/dist/_internal/shared/content/published-values.js +198 -0
  58. package/dist/_internal/shared/features/admin/integrations.d.ts +109 -0
  59. package/dist/_internal/shared/features/admin/integrations.js +253 -0
  60. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  61. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  62. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  63. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  64. package/dist/_internal/shared/features/points/accepts.d.ts +36 -0
  65. package/dist/_internal/shared/features/points/accepts.js +43 -0
  66. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  67. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  68. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  69. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  70. package/dist/_internal/shared/fees/calculator.js +32 -2
  71. package/dist/_internal/shared/media/limits.d.ts +10 -0
  72. package/dist/_internal/shared/media/limits.js +10 -0
  73. package/dist/_internal/shared/types/action-result.js +15 -1
  74. package/dist/client/api/surface-error.js +16 -2
  75. package/dist/client/api/useApiMutation.js +17 -1
  76. package/dist/client.d.ts +12 -1
  77. package/dist/client.js +31 -1
  78. package/dist/constants/api-endpoints.d.ts +45 -0
  79. package/dist/constants/api-endpoints.js +15 -0
  80. package/dist/constants/field-names.d.ts +18 -0
  81. package/dist/constants/field-names.js +28 -0
  82. package/dist/contracts/index.d.ts +1 -1
  83. package/dist/contracts/shipping.d.ts +45 -0
  84. package/dist/contracts/shipping.js +15 -0
  85. package/dist/core/server-action.js +19 -3
  86. package/dist/errors/error-mapping.js +26 -1
  87. package/dist/features/about/components/AboutView.js +1 -1
  88. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  89. package/dist/features/account/components/UserOffersPanel.js +5 -3
  90. package/dist/features/account/components/UserOrdersView.js +19 -33
  91. package/dist/features/admin/components/AdminActionIndexView.js +100 -5
  92. package/dist/features/admin/components/AdminAddressClustersView.js +21 -2
  93. package/dist/features/admin/components/AdminBlogEditorView.js +8 -8
  94. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  95. package/dist/features/admin/components/AdminCarouselView.js +96 -4
  96. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  97. package/dist/features/admin/components/AdminFulfillmentView.js +3 -2
  98. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  99. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  100. package/dist/features/admin/components/AdminMediaView.js +36 -3
  101. package/dist/features/admin/components/AdminNavigationView.js +4 -1
  102. package/dist/features/admin/components/AdminOffersView.js +2 -1
  103. package/dist/features/admin/components/AdminOrderEditorView.d.ts +18 -1
  104. package/dist/features/admin/components/AdminOrderEditorView.js +11 -2
  105. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  106. package/dist/features/admin/components/AdminOrdersView.js +67 -5
  107. package/dist/features/admin/components/AdminPaymentClustersView.js +19 -2
  108. package/dist/features/admin/components/AdminProductEditorView.js +2 -2
  109. package/dist/features/admin/components/AdminSectionsView.d.ts +10 -0
  110. package/dist/features/admin/components/AdminSectionsView.js +486 -224
  111. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  112. package/dist/features/admin/components/ReferenceRecordEditor.js +1 -1
  113. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  114. package/dist/features/admin/constants/filter-tabs.js +6 -0
  115. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  116. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  117. package/dist/features/admin/hooks/useOptimisticRowFlag.d.ts +33 -0
  118. package/dist/features/admin/hooks/useOptimisticRowFlag.js +87 -0
  119. package/dist/features/admin/repository/notification.repository.d.ts +15 -0
  120. package/dist/features/admin/repository/notification.repository.js +32 -0
  121. package/dist/features/admin/schemas/action-index-form.d.ts +34 -0
  122. package/dist/features/admin/schemas/action-index-form.js +115 -0
  123. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  124. package/dist/features/admin/schemas/firestore.d.ts +30 -0
  125. package/dist/features/admin/schemas/firestore.js +5 -0
  126. package/dist/features/audit-log/schemas/firestore.d.ts +30 -0
  127. package/dist/features/audit-log/schemas/firestore.js +15 -0
  128. package/dist/features/auth/components/RegisterForm.js +2 -1
  129. package/dist/features/auth/permissions/constants.js +13 -0
  130. package/dist/features/cart/components/CartPriceBreakdown.d.ts +13 -0
  131. package/dist/features/cart/components/CartPriceBreakdown.js +6 -2
  132. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  133. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  134. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  135. package/dist/features/cart/components/index.d.ts +2 -0
  136. package/dist/features/cart/components/index.js +1 -0
  137. package/dist/features/cart/repository/cart.repository.d.ts +19 -0
  138. package/dist/features/cart/repository/cart.repository.js +27 -0
  139. package/dist/features/cart/schemas/firestore.d.ts +92 -0
  140. package/dist/features/catalogue/components/CatalogueItemEditorView.js +3 -3
  141. package/dist/features/contact/email.d.ts +27 -10
  142. package/dist/features/contact/email.js +20 -3
  143. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +38 -0
  144. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +80 -0
  145. package/dist/features/dispute-reasons/schemas/firestore.d.ts +64 -0
  146. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  147. package/dist/features/events/components/AdminEventEditorView.js +8 -6
  148. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  149. package/dist/features/faq/components/FAQAccordion.js +29 -4
  150. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  151. package/dist/features/invoicing/schemas/firestore.js +45 -0
  152. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  153. package/dist/features/invoicing/utils/financial-year.js +53 -0
  154. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  155. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  156. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  157. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  158. package/dist/features/jobs/schemas/firestore.js +37 -0
  159. package/dist/features/layout/hooks/useFormBottomActions.js +20 -1
  160. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  161. package/dist/features/media/MediaImage.js +22 -1
  162. package/dist/features/media/upload/ImageUpload.js +1 -1
  163. package/dist/features/obligations/constants/policies.js +24 -1
  164. package/dist/features/orders/components/EmiInstallmentsPanel.js +25 -7
  165. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  166. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  167. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  168. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  169. package/dist/features/orders/components/RaiseDisputeForm.js +111 -0
  170. package/dist/features/orders/components/RefundRequestView.js +22 -4
  171. package/dist/features/orders/components/index.d.ts +4 -0
  172. package/dist/features/orders/components/index.js +2 -0
  173. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  174. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  175. package/dist/features/orders/repository/orders.repository.d.ts +57 -0
  176. package/dist/features/orders/repository/orders.repository.js +145 -0
  177. package/dist/features/orders/schemas/firestore.d.ts +196 -1
  178. package/dist/features/orders/schemas/index.d.ts +60 -12
  179. package/dist/features/orders/schemas/index.js +12 -0
  180. package/dist/features/orders/types/index.d.ts +26 -0
  181. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  182. package/dist/features/orders/utils/courier-block.js +23 -0
  183. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  184. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  185. package/dist/features/products/components/GroupMemberPicker.js +4 -1
  186. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  187. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  188. package/dist/features/products/components/ProductDetailActions.js +2 -1
  189. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  190. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  191. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  192. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  193. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  194. package/dist/features/promotions/components/CouponCard.js +13 -0
  195. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  196. package/dist/features/promotions/constants/coupon-help.js +9 -1
  197. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  198. package/dist/features/promotions/schemas/firestore.js +4 -0
  199. package/dist/features/promotions/types/index.d.ts +19 -1
  200. package/dist/features/scams/components/ScamProfileView.js +2 -2
  201. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  202. package/dist/features/search/action-index/tab-entries.js +1 -1
  203. package/dist/features/seller/actions/seller-actions.js +33 -3
  204. package/dist/features/seller/components/FulfillmentView.js +3 -2
  205. package/dist/features/seller/components/SellerAddressesView.js +32 -4
  206. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +62 -3
  207. package/dist/features/seller/components/SellerBundlesView.js +53 -14
  208. package/dist/features/seller/components/SellerGroupedListingsView.js +23 -3
  209. package/dist/features/seller/components/SellerListingTypeView.js +56 -10
  210. package/dist/features/seller/components/SellerOrdersView.js +129 -27
  211. package/dist/features/seller/components/SellerPayoutMethodsView.js +33 -1
  212. package/dist/features/seller/components/SellerPayoutSettingsView.js +48 -9
  213. package/dist/features/seller/components/SellerProductsView.js +5 -1
  214. package/dist/features/seller/components/SellerShippingConfigsView.js +33 -1
  215. package/dist/features/seller/components/SellerShippingView.js +2 -1
  216. package/dist/features/seller/components/SellerStoreCategoriesView.js +33 -1
  217. package/dist/features/seller/components/SellerSupportView.js +69 -2
  218. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  219. package/dist/features/shell/SectionForm.js +20 -16
  220. package/dist/features/shell/build-sections.js +14 -1
  221. package/dist/features/shipments/components/AdminShipmentLotItemsView.js +54 -1
  222. package/dist/features/shipments/components/AdminShipmentProjectionsView.js +3 -2
  223. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  224. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +43 -0
  225. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +90 -0
  226. package/dist/features/shipping-boxes/schemas/firestore.d.ts +82 -0
  227. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  228. package/dist/features/sticker-trace/components/StickerCommitPanel.js +2 -1
  229. package/dist/features/sticker-trace/components/StickerPrintPanel.js +2 -1
  230. package/dist/features/sticker-trace/components/StickerRetryPanel.js +24 -4
  231. package/dist/features/sticker-trace/components/StickerTraceStudio.js +2 -1
  232. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  233. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  234. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  235. package/dist/features/stores/schemas/firestore.d.ts +71 -0
  236. package/dist/features/stores/types/index.d.ts +19 -0
  237. package/dist/features/support/schemas/index.d.ts +6 -6
  238. package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +3 -2
  239. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  240. package/dist/index.d.ts +11 -2
  241. package/dist/index.js +17 -2
  242. package/dist/next/routing/route-map.d.ts +24 -0
  243. package/dist/next/routing/route-map.js +19 -0
  244. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  245. package/dist/providers/shipping-shiprocket/index.js +84 -1
  246. package/dist/schemas/registry.d.ts +51 -22
  247. package/dist/schemas/sieve.d.ts +5 -5
  248. package/dist/server-entry.d.ts +2 -2
  249. package/dist/server-entry.js +8 -1
  250. package/dist/server.d.ts +11 -2
  251. package/dist/server.js +40 -2
  252. package/dist/styles.css +64 -80
  253. package/dist/tailwind-utilities.css +1 -1
  254. package/dist/tokens/themes/default-dark.js +1 -0
  255. package/dist/tokens/themes/default-light.js +1 -0
  256. package/dist/tokens/themes/required.d.ts +1 -1
  257. package/dist/tokens/themes/required.js +1 -0
  258. package/dist/tokens/tokens.css +15 -0
  259. package/dist/ui/components/Checkbox.js +10 -2
  260. package/dist/ui/components/DateInput.js +8 -1
  261. package/dist/ui/components/Disclaimer.d.ts +19 -0
  262. package/dist/ui/components/Disclaimer.js +74 -0
  263. package/dist/ui/components/Input.js +22 -2
  264. package/dist/ui/components/PaginatedSelect.d.ts +8 -19
  265. package/dist/ui/components/PaginatedSelect.js +43 -9
  266. package/dist/ui/components/Radio.js +8 -1
  267. package/dist/ui/components/Select.js +10 -2
  268. package/dist/ui/components/TagInput.d.ts +8 -1
  269. package/dist/ui/components/TagInput.js +4 -3
  270. package/dist/ui/components/Textarea.js +10 -2
  271. package/dist/ui/components/tabs-overflow.js +64 -11
  272. package/dist/ui/forms/FieldCheckbox.js +1 -1
  273. package/dist/ui/forms/FormErrorList.d.ts +0 -16
  274. package/dist/ui/forms/FormErrorList.js +34 -1
  275. package/dist/ui/forms/apply-zod-issues.d.ts +19 -1
  276. package/dist/ui/forms/apply-zod-issues.js +23 -1
  277. package/dist/ui/index.d.ts +2 -0
  278. package/dist/ui/index.js +6 -0
  279. package/dist/ui/rich-text/RichText.style.css +48 -79
  280. package/package.json +1 -1
  281. package/scripts/seed-cli.mjs +1831 -1822
@@ -38,7 +38,24 @@ export const REFUND_COPY = {
38
38
  acknowledgments: [
39
39
  "I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.",
40
40
  "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).",
41
- "I understand the refund amount may take 5–7 business days to reflect and that platform fees may be non-recoverable.",
41
+ /*
42
+ * 🛑 Phase 9 — TOKENS, resolved by `resolvePublishedCopy` at render.
43
+ *
44
+ * This literal was one of the three contradicting owners of the refund
45
+ * timeline: "5–7 business days" here, "5–7 business days via Razorpay"
46
+ * on the policy page (naming a gateway that was not even the one in
47
+ * use), and "3–5 business days" in the FAQ. Three statements of one
48
+ * fact, no reconciliation, and the FAQ one admin-editable so it could
49
+ * drift further after deployment.
50
+ *
51
+ * The caller renders this through `resolvePublishedCopy`, so the number
52
+ * now has exactly one definition. Note this string is an
53
+ * ACKNOWLEDGEMENT the buyer ticks — a token left unresolved here would
54
+ * appear in something they are agreeing to, which is the strongest
55
+ * possible argument for the unknown-token rule leaving `{{…}}` visible
56
+ * rather than blanking it.
57
+ */
58
+ "I understand the refund amount may take {{refundBusinessDaysMin}}–{{refundBusinessDaysMax}} business days to reflect and that platform fees may be non-recoverable.",
42
59
  ],
43
60
  },
44
61
  siblingPayments: {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Does this store accept buyer points as part-payment?
3
+ *
4
+ * ## Why this is a function and not a bare field read
5
+ *
6
+ * Decision 3 has two halves: *"the main store always accepts, others opt in"*.
7
+ * The opt-in half is `StoreDocument.acceptsPoints`; the always half is the
8
+ * platform's own storefront, which cannot decline to fund its own programme.
9
+ *
10
+ * 🛑 The platform store is resolved in CODE rather than seeded `true`, because a
11
+ * seeded flag can be switched off by an edit, a reseed, or an admin clicking the
12
+ * wrong toggle — and the one store that must never stop accepting is the one the
13
+ * whole programme is advertised on. `UserPointsView` tells buyers points are
14
+ * spendable; if the only store could opt out, that promise would be a lie that
15
+ * nothing detected.
16
+ *
17
+ * ## 🛑 Absent means NOT accepted
18
+ *
19
+ * Matching `supportsSaleProtection`'s rule on the same document, and for the
20
+ * same reason: the accepting store ABSORBS the redemption against its payout,
21
+ * so defaulting absent to `true` would enrol every existing seller in funding
22
+ * discounts they never agreed to. A tri-state would be worse still — a buyer
23
+ * cannot tell a seller who declined from one who has not been asked.
24
+ */
25
+ /**
26
+ * The platform's own storefront.
27
+ *
28
+ * Hard-coded deliberately: this is an identity, not a setting. It is the same
29
+ * id `realListingsOnly` and the seed's `REAL_STORE_IDS` already treat as the
30
+ * platform's own.
31
+ */
32
+ export declare const PLATFORM_STORE_ID = "store-letitrip-official";
33
+ export declare function storeAcceptsPoints(store: {
34
+ id?: string;
35
+ acceptsPoints?: boolean;
36
+ } | null | undefined, storeId?: string): boolean;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Does this store accept buyer points as part-payment?
3
+ *
4
+ * ## Why this is a function and not a bare field read
5
+ *
6
+ * Decision 3 has two halves: *"the main store always accepts, others opt in"*.
7
+ * The opt-in half is `StoreDocument.acceptsPoints`; the always half is the
8
+ * platform's own storefront, which cannot decline to fund its own programme.
9
+ *
10
+ * 🛑 The platform store is resolved in CODE rather than seeded `true`, because a
11
+ * seeded flag can be switched off by an edit, a reseed, or an admin clicking the
12
+ * wrong toggle — and the one store that must never stop accepting is the one the
13
+ * whole programme is advertised on. `UserPointsView` tells buyers points are
14
+ * spendable; if the only store could opt out, that promise would be a lie that
15
+ * nothing detected.
16
+ *
17
+ * ## 🛑 Absent means NOT accepted
18
+ *
19
+ * Matching `supportsSaleProtection`'s rule on the same document, and for the
20
+ * same reason: the accepting store ABSORBS the redemption against its payout,
21
+ * so defaulting absent to `true` would enrol every existing seller in funding
22
+ * discounts they never agreed to. A tri-state would be worse still — a buyer
23
+ * cannot tell a seller who declined from one who has not been asked.
24
+ */
25
+ /**
26
+ * The platform's own storefront.
27
+ *
28
+ * Hard-coded deliberately: this is an identity, not a setting. It is the same
29
+ * id `realListingsOnly` and the seed's `REAL_STORE_IDS` already treat as the
30
+ * platform's own.
31
+ */
32
+ export const PLATFORM_STORE_ID = "store-letitrip-official";
33
+ export function storeAcceptsPoints(store, storeId) {
34
+ /*
35
+ * The id is taken from either source so a caller holding only an id (the
36
+ * order-group loop) and one holding the document (an admin surface) get the
37
+ * same answer. Mismatched sources would be two rules again.
38
+ */
39
+ const id = store?.id ?? storeId;
40
+ if (id === PLATFORM_STORE_ID)
41
+ return true;
42
+ return store?.acceptsPoints === true;
43
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared purchase, S5a — one payer, N destinations.
3
+ *
4
+ * ## What this is, and what it deliberately is not
5
+ *
6
+ * The coordinator buys everything and assigns a destination per item, so one
7
+ * paid order becomes N parcels. That is **~20% of the shared-purchase work for
8
+ * most of its value** (the plan's own assessment), because it needs none of
9
+ * the hard parts: no multi-party payment, no coordinator deposit, no approval
10
+ * cascade, no per-buyer invoicing, no per-buyer GST, and no stock-reservation
11
+ * primitive.
12
+ *
13
+ * 🛑 It is NOT S5b. There is exactly ONE payer and ONE place of supply, which
14
+ * is what keeps the tax, the invoice and the refund path unchanged. The moment
15
+ * a second person pays, every one of those becomes per-buyer and the design is
16
+ * a different design.
17
+ *
18
+ * ## 🛑 Why the fees are SNAPSHOTTED, and the precedent that proves it
19
+ *
20
+ * A coordinator commits to a quoted total. If the handling fee or the
21
+ * per-destination shipping is re-read at settle, a seller can raise it after
22
+ * the quote and the coordinator absorbs the difference.
23
+ *
24
+ * The codebase already has this exact hole and this exact fix: the refund path
25
+ * reads `finalSale` from the ORDER snapshot rather than the live product,
26
+ * because — in its own words — "re-reading the live product would let a seller
27
+ * flip the switch afterwards". D61 generalises it: *any agreement with a gap
28
+ * between "terms agreed" and "money taken" must snapshot its terms at
29
+ * agreement.*
30
+ *
31
+ * So `quoteSharedPurchase` takes the rates as ARGUMENTS and the caller
32
+ * snapshots the result onto the order. There is no settings read in here.
33
+ */
34
+ /** The two rates, read from the store document at quote time. */
35
+ export interface SharedPurchaseRates {
36
+ allowSharedPurchase?: boolean;
37
+ sharedPurchaseHandlingFee?: number;
38
+ sharedPurchaseExtraShippingPerDestination?: number;
39
+ }
40
+ export interface SharedPurchaseQuoteInput {
41
+ /**
42
+ * Distinct destinations in this order group, INCLUDING the first.
43
+ *
44
+ * 🛑 A count of DISTINCT addresses, not of items. Three items to one address
45
+ * is one parcel and no extra leg; two items to two addresses is two. Passing
46
+ * an item count would charge a coordinator for splitting an order they did
47
+ * not split.
48
+ */
49
+ destinationCount: number;
50
+ /** The store's snapshotted rates. */
51
+ rates: SharedPurchaseRates;
52
+ }
53
+ export interface SharedPurchaseQuote {
54
+ /** True when this is actually a multi-destination order. */
55
+ isShared: boolean;
56
+ /** Flat handling fee, or 0. */
57
+ handlingFee: number;
58
+ /** Extra shipping for destinations beyond the first, or 0. */
59
+ extraShippingFee: number;
60
+ /** `handlingFee + extraShippingFee`, the figure added to the order total. */
61
+ total: number;
62
+ /**
63
+ * Set when the arrangement cannot be priced — the seller allows it but has
64
+ * not configured a rate.
65
+ *
66
+ * 🛑 The caller MUST act on this rather than treating the fee as ₹0. That is
67
+ * D44 exactly: `shippingUnavailable` existed with its own docstring saying
68
+ * "the caller MUST act on this rather than trusting `shippingFee: 0`", had
69
+ * ZERO consumers, and an `estimate`-mode store shipped free on every path as
70
+ * a result. An unpriced arrangement must be refused, not given away.
71
+ */
72
+ unpriced?: "handling" | "extra-shipping";
73
+ }
74
+ /**
75
+ * Price a shared-purchase arrangement for ONE order group.
76
+ *
77
+ * Pure: no settings read, no Firestore, no clock. The rates come in, the
78
+ * figure comes out, and the caller snapshots it.
79
+ */
80
+ export declare function quoteSharedPurchase(input: SharedPurchaseQuoteInput): SharedPurchaseQuote;
81
+ /**
82
+ * Distinct destinations across a set of lines.
83
+ *
84
+ * 🛑 Lines with NO `destinationAddressId` collapse into one bucket — the
85
+ * order's own address — rather than counting as a destination each. Otherwise
86
+ * an ordinary three-item order would look like three destinations and be
87
+ * charged two extra legs.
88
+ */
89
+ export declare function countDestinations(lines: readonly {
90
+ destinationAddressId?: string;
91
+ }[]): number;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Shared purchase, S5a — one payer, N destinations.
3
+ *
4
+ * ## What this is, and what it deliberately is not
5
+ *
6
+ * The coordinator buys everything and assigns a destination per item, so one
7
+ * paid order becomes N parcels. That is **~20% of the shared-purchase work for
8
+ * most of its value** (the plan's own assessment), because it needs none of
9
+ * the hard parts: no multi-party payment, no coordinator deposit, no approval
10
+ * cascade, no per-buyer invoicing, no per-buyer GST, and no stock-reservation
11
+ * primitive.
12
+ *
13
+ * 🛑 It is NOT S5b. There is exactly ONE payer and ONE place of supply, which
14
+ * is what keeps the tax, the invoice and the refund path unchanged. The moment
15
+ * a second person pays, every one of those becomes per-buyer and the design is
16
+ * a different design.
17
+ *
18
+ * ## 🛑 Why the fees are SNAPSHOTTED, and the precedent that proves it
19
+ *
20
+ * A coordinator commits to a quoted total. If the handling fee or the
21
+ * per-destination shipping is re-read at settle, a seller can raise it after
22
+ * the quote and the coordinator absorbs the difference.
23
+ *
24
+ * The codebase already has this exact hole and this exact fix: the refund path
25
+ * reads `finalSale` from the ORDER snapshot rather than the live product,
26
+ * because — in its own words — "re-reading the live product would let a seller
27
+ * flip the switch afterwards". D61 generalises it: *any agreement with a gap
28
+ * between "terms agreed" and "money taken" must snapshot its terms at
29
+ * agreement.*
30
+ *
31
+ * So `quoteSharedPurchase` takes the rates as ARGUMENTS and the caller
32
+ * snapshots the result onto the order. There is no settings read in here.
33
+ */
34
+ import { roundRupees } from "../../../../utils/number.formatter.js";
35
+ /**
36
+ * Price a shared-purchase arrangement for ONE order group.
37
+ *
38
+ * Pure: no settings read, no Firestore, no clock. The rates come in, the
39
+ * figure comes out, and the caller snapshots it.
40
+ */
41
+ export function quoteSharedPurchase(input) {
42
+ const none = {
43
+ isShared: false,
44
+ handlingFee: 0,
45
+ extraShippingFee: 0,
46
+ total: 0,
47
+ };
48
+ /*
49
+ * One destination is an ordinary order. Checked BEFORE the allow flag, so a
50
+ * seller who has not opted in is unaffected by this code path entirely —
51
+ * rather than being refused an order they were always able to take.
52
+ */
53
+ const destinations = Math.max(1, Math.floor(input.destinationCount));
54
+ if (destinations <= 1)
55
+ return none;
56
+ if (input.rates.allowSharedPurchase !== true) {
57
+ /*
58
+ * 🛑 Returns `isShared: false` rather than throwing, and the CALLER
59
+ * refuses. This function prices; it does not authorise. A thrown error
60
+ * here would be caught by a preview path and rendered as a broken page,
61
+ * where the correct behaviour is to tell the buyer this seller does not
62
+ * split orders.
63
+ */
64
+ return none;
65
+ }
66
+ const handling = input.rates.sharedPurchaseHandlingFee;
67
+ const perExtra = input.rates.sharedPurchaseExtraShippingPerDestination;
68
+ /*
69
+ * 🛑 `undefined` is UNPRICED, not zero — see the `unpriced` field. A seller
70
+ * who opted in without setting a rate has not agreed to do it for free, and
71
+ * charging ₹0 would hand them the extra labour at their own cost silently.
72
+ */
73
+ if (typeof handling !== "number" || !Number.isFinite(handling)) {
74
+ return { ...none, isShared: true, unpriced: "handling" };
75
+ }
76
+ if (typeof perExtra !== "number" || !Number.isFinite(perExtra)) {
77
+ return { ...none, isShared: true, unpriced: "extra-shipping" };
78
+ }
79
+ const handlingFee = roundRupees(Math.max(0, handling));
80
+ // BEYOND THE FIRST: the first destination's shipping is what the order would
81
+ // have paid anyway, so only the marginal legs are charged here.
82
+ const extraShippingFee = roundRupees(Math.max(0, perExtra) * (destinations - 1));
83
+ return {
84
+ isShared: true,
85
+ handlingFee,
86
+ extraShippingFee,
87
+ total: roundRupees(handlingFee + extraShippingFee),
88
+ };
89
+ }
90
+ /**
91
+ * Distinct destinations across a set of lines.
92
+ *
93
+ * 🛑 Lines with NO `destinationAddressId` collapse into one bucket — the
94
+ * order's own address — rather than counting as a destination each. Otherwise
95
+ * an ordinary three-item order would look like three destinations and be
96
+ * charged two extra legs.
97
+ */
98
+ export function countDestinations(lines) {
99
+ const ids = new Set();
100
+ let usesOrderAddress = false;
101
+ for (const line of lines) {
102
+ if (line.destinationAddressId)
103
+ ids.add(line.destinationAddressId);
104
+ else
105
+ usesOrderAddress = true;
106
+ }
107
+ return ids.size + (usesOrderAddress ? 1 : 0);
108
+ }
@@ -42,6 +42,17 @@ export interface PublicSiteSettings {
42
42
  chat?: {
43
43
  enabled: boolean;
44
44
  };
45
+ /**
46
+ * Is the support desk reachable — read by `UserLayoutClient`, a client
47
+ * component. Narrowed to the one boolean rather than passed by reference,
48
+ * so a field added to the document's `support` group later is not published
49
+ * by accident; `PUBLIC_SITE_SETTINGS_FIELDS` carries the same caveat beside
50
+ * its entry. Optional here because the group is absent on a settings
51
+ * document written before it existed.
52
+ */
53
+ support?: {
54
+ enabled: boolean;
55
+ };
45
56
  /**
46
57
  * The browser-side search index kill switch. **ON by default** — the
47
58
  * projection emits `indexEnabled: doc.search?.indexEnabled !== false`, so
@@ -79,6 +79,17 @@ export interface PayoutDeduction {
79
79
  * plus ₹80 postage" is a sentence; one net figure is not.
80
80
  */
81
81
  shippingReimbursement: number;
82
+ /**
83
+ * Rupee value of buyer points this order was settled with, deducted from
84
+ * `netAmount` (D46/D47, decisions 3 and 17 — the accepting store funds the
85
+ * redemption).
86
+ *
87
+ * Returned as its own figure rather than folded into `totalDeduction` for the
88
+ * same reason `shippingReimbursement` is: *"'₹900 less ₹30 commission plus
89
+ * ₹80 postage' is a sentence; one net figure is not."* A seller looking at a
90
+ * short payout needs to see which of the four terms shortened it.
91
+ */
92
+ pointsFunded: number;
82
93
  }
83
94
  /**
84
95
  * What a seller is actually paid.
@@ -101,8 +112,29 @@ export interface PayoutDeduction {
101
112
  *
102
113
  * Defaulted to 0, so the three call sites that do not yet pass it keep their
103
114
  * current behaviour exactly rather than silently gaining a term.
115
+ *
116
+ * ## 🛑 `pointsFunded` is the mirror of that, and it is a DEDUCTION
117
+ *
118
+ * Decisions 3 and 17: the programme is seller-funded at both ends — the
119
+ * accepting store absorbs the redemption, the originating store bears the
120
+ * earn — and the platform funds neither. So points spent on an order reduce
121
+ * that order's payout by the rupee value spent.
122
+ *
123
+ * It sits in the SAME position as postage and for the inverse reason: outside
124
+ * the commission and gateway bases. The seller agreed to fund a discount, not
125
+ * to pay us a commission on the discount they funded, and a gateway percentage
126
+ * on money no gateway touched is not a card fee at all.
127
+ *
128
+ * 🛑 So `grossAmount` is untouched and the fee figures are IDENTICAL whether
129
+ * points were used or not. That is what keeps the commission the seller is
130
+ * charged a function of the sale rather than of how the buyer chose to settle
131
+ * it — and it is why this cannot be implemented by passing a smaller
132
+ * `grossAmount`, which is the obvious shortcut and silently reduces our own
133
+ * commission by 2% of every redemption.
134
+ *
135
+ * Also defaulted to 0, for the same reason.
104
136
  */
105
- export declare function computePayoutDeduction(grossAmount: number, commissions: FeeCommissionRates, shippingReimbursement?: number): PayoutDeduction;
137
+ export declare function computePayoutDeduction(grossAmount: number, commissions: FeeCommissionRates, shippingReimbursement?: number, pointsFunded?: number): PayoutDeduction;
106
138
  export interface CodHandlingFeeRates {
107
139
  /**
108
140
  * Rupee CEILING on the COD handling fee. Optional so a `siteSettings`
@@ -114,8 +114,29 @@ export function allocateCheckoutFees(groupSubtotals, fees) {
114
114
  *
115
115
  * Defaulted to 0, so the three call sites that do not yet pass it keep their
116
116
  * current behaviour exactly rather than silently gaining a term.
117
+ *
118
+ * ## 🛑 `pointsFunded` is the mirror of that, and it is a DEDUCTION
119
+ *
120
+ * Decisions 3 and 17: the programme is seller-funded at both ends — the
121
+ * accepting store absorbs the redemption, the originating store bears the
122
+ * earn — and the platform funds neither. So points spent on an order reduce
123
+ * that order's payout by the rupee value spent.
124
+ *
125
+ * It sits in the SAME position as postage and for the inverse reason: outside
126
+ * the commission and gateway bases. The seller agreed to fund a discount, not
127
+ * to pay us a commission on the discount they funded, and a gateway percentage
128
+ * on money no gateway touched is not a card fee at all.
129
+ *
130
+ * 🛑 So `grossAmount` is untouched and the fee figures are IDENTICAL whether
131
+ * points were used or not. That is what keeps the commission the seller is
132
+ * charged a function of the sale rather than of how the buyer chose to settle
133
+ * it — and it is why this cannot be implemented by passing a smaller
134
+ * `grossAmount`, which is the obvious shortcut and silently reduces our own
135
+ * commission by 2% of every redemption.
136
+ *
137
+ * Also defaulted to 0, for the same reason.
117
138
  */
118
- export function computePayoutDeduction(grossAmount, commissions, shippingReimbursement = 0) {
139
+ export function computePayoutDeduction(grossAmount, commissions, shippingReimbursement = 0, pointsFunded = 0) {
119
140
  const platformFee = roundRupees(grossAmount * (commissions.platformFeePercent / 100));
120
141
  const gatewayFee = roundRupees(grossAmount * ((commissions.gatewayFeePercent ?? 0) / 100));
121
142
  const gstOnFee = roundRupees(platformFee * (commissions.gstPercent / 100));
@@ -123,7 +144,15 @@ export function computePayoutDeduction(grossAmount, commissions, shippingReimbur
123
144
  const postage = Number.isFinite(shippingReimbursement)
124
145
  ? Math.max(0, shippingReimbursement)
125
146
  : 0;
126
- const netAmount = Math.max(0, roundRupees(grossAmount - totalDeduction + postage));
147
+ const points = Number.isFinite(pointsFunded) ? Math.max(0, pointsFunded) : 0;
148
+ /*
149
+ * Clamped at zero, as it already was. A redemption cannot exceed 50% of the
150
+ * order total, so it cannot plausibly exceed the net — but a floor here means
151
+ * no caller can ever hand a seller a negative payout, which would be written
152
+ * to a `PayoutDocument.amount` that every downstream sum then treats as a
153
+ * credit against the platform.
154
+ */
155
+ const netAmount = Math.max(0, roundRupees(grossAmount - totalDeduction + postage - points));
127
156
  return {
128
157
  platformFee,
129
158
  gatewayFee,
@@ -131,6 +160,7 @@ export function computePayoutDeduction(grossAmount, commissions, shippingReimbur
131
160
  totalDeduction,
132
161
  netAmount,
133
162
  shippingReimbursement: roundRupees(postage),
163
+ pointsFunded: roundRupees(points),
134
164
  };
135
165
  }
136
166
  /** Buyer-facing COD handling ceiling, in decimal rupees. */
@@ -27,6 +27,16 @@ export type MediaKind = "image" | "video" | "pdf";
27
27
  export declare const PRODUCT_MAX_IMAGES = 24;
28
28
  /** Videos per listing. Bounded by `ProductDocument.video` being singular. */
29
29
  export declare const PRODUCT_MAX_VIDEOS = 1;
30
+ /**
31
+ * Photos a buyer may attach to one review.
32
+ *
33
+ * 🛑 Deliberately NOT `PRODUCT_MAX_IMAGES`, which is 24 and is a SELLER's
34
+ * ceiling for a whole listing. `audit-media-limit-literals` suggests that
35
+ * constant for any `images: z.array(…).max(n)`, and taking the suggestion
36
+ * here would have quadrupled what a review accepts — the right shape, the
37
+ * wrong number. A review is a few photos of one thing.
38
+ */
39
+ export declare const REVIEW_MAX_IMAGES = 6;
30
40
  /**
31
41
  * Highest legal `index` in a product media filename.
32
42
  *
@@ -41,6 +41,16 @@ export const MAX_VIDEO_BYTES = 50 * MEGABYTE;
41
41
  export const PRODUCT_MAX_IMAGES = 24;
42
42
  /** Videos per listing. Bounded by `ProductDocument.video` being singular. */
43
43
  export const PRODUCT_MAX_VIDEOS = 1;
44
+ /**
45
+ * Photos a buyer may attach to one review.
46
+ *
47
+ * 🛑 Deliberately NOT `PRODUCT_MAX_IMAGES`, which is 24 and is a SELLER's
48
+ * ceiling for a whole listing. `audit-media-limit-literals` suggests that
49
+ * constant for any `images: z.array(…).max(n)`, and taking the suggestion
50
+ * here would have quadrupled what a review accepts — the right shape, the
51
+ * wrong number. A review is a few photos of one thing.
52
+ */
53
+ export const REVIEW_MAX_IMAGES = 6;
44
54
  /**
45
55
  * Highest legal `index` in a product media filename.
46
56
  *
@@ -1,5 +1,6 @@
1
1
  import { normalizeError } from "../../../errors/normalize.js";
2
2
  import { mapToHttpError } from "../../../errors/error-mapping.js";
3
+ import { toApiIssues } from "../../../errors/error-envelope.js";
3
4
  import { describeCauseChain } from "../../../errors/describe-cause.js";
4
5
  import { reportActionError } from "./action-error-reporter.js";
5
6
  /**
@@ -57,7 +58,20 @@ export async function wrapAction(fn) {
57
58
  ok: false,
58
59
  code: mapped.code,
59
60
  error: mapped.message,
60
- ...(mapped.issues ? { issues: mapped.issues } : {}),
61
+ /*
62
+ * 🛑 `toApiIssues`, not the raw issues — this was the ONE producer in
63
+ * the codebase that skipped the scrubber, and it is the one with 221
64
+ * call sites.
65
+ *
66
+ * A raw `ZodIssue` carries `received`: the value the user actually
67
+ * submitted. On a failed signup, address save or payout-details save
68
+ * that is an email, a phone number or a bank account, echoed straight
69
+ * back into the client payload. `toApiIssues` narrows each issue to
70
+ * `{ message, path?, code? }`, which is exactly why it exists — every
71
+ * other producer (`routeHandler`, `createApiHandler`, the offer
72
+ * actions) already routes through it.
73
+ */
74
+ ...(mapped.issues ? { issues: toApiIssues(mapped.issues) } : {}),
61
75
  };
62
76
  }
63
77
  }
@@ -1,6 +1,6 @@
1
1
  import { isApiError } from "./ApiError.js";
2
2
  import { ApiClientError } from "../../http/ApiClient.js";
3
- import { applyZodIssues, hasAttachableIssue } from "../../ui/forms/apply-zod-issues.js";
3
+ import { applyZodIssues, hasAttachableIssue, rootLevelMessages } from "../../ui/forms/apply-zod-issues.js";
4
4
  import { normalizeError } from "../../errors/normalize.js";
5
5
  import { getErrorDisplay, toUserMessage } from "../../errors/error-display-map.js";
6
6
  import { HTTP_ERROR_CODES } from "../../errors/error-mapping.js";
@@ -36,7 +36,21 @@ export function surfaceError(err, opts) {
36
36
  const issues = issuesOf(err);
37
37
  if (setFieldError && hasAttachableIssue(issues)) {
38
38
  applyZodIssues(issues, (name, message) => setFieldError(name, message ?? ""));
39
- return; // inline errors only — no toast
39
+ /*
40
+ * 🛑 Root-level issues are NOT covered by the line above and must still be
41
+ * surfaced, or a cross-field rule fails silently.
42
+ *
43
+ * `applyZodIssues` skips any issue with an empty `path` — there is no
44
+ * field to put it on. For a mixed response (one field error plus one
45
+ * cross-field `.refine()`, the shape of "passwords must match" or "end
46
+ * date must be after start date") `hasAttachableIssue` is true, so we used
47
+ * to take this branch and `return` with the refine message discarded: the
48
+ * save was refused and nothing on screen said why.
49
+ */
50
+ for (const message of rootLevelMessages(issues)) {
51
+ showToast(message, "error");
52
+ }
53
+ return; // field errors inline; only the unattachable ones toast
40
54
  }
41
55
  if (hasStableErrorCode(err)) {
42
56
  const display = getErrorDisplay(err.code);
@@ -3,6 +3,7 @@ import * as React from "react";
3
3
  import { useMutation, } from "@tanstack/react-query";
4
4
  import { useToast } from "../../ui/components/Toast.js";
5
5
  import { surfaceError } from "./surface-error.js";
6
+ import { toUserMessage } from "../../errors/error-display-map.js";
6
7
  export function useApiMutation(options) {
7
8
  const { showToast, updateToast } = useToast();
8
9
  const loadingIdRef = React.useRef(null);
@@ -40,7 +41,22 @@ export function useApiMutation(options) {
40
41
  onSettled: (data, err, variables, context, ctx) => {
41
42
  if (loadingIdRef.current) {
42
43
  if (err) {
43
- updateToast(loadingIdRef.current, "error", err instanceof Error ? err.message : "Action failed");
44
+ /*
45
+ * 🛑 This was `err instanceof Error ? err.message : "Action failed"`
46
+ * — verbatim the inverted ternary `audit-raw-error-text`'s own
47
+ * header calls "the dominant shape", sitting two lines below the
48
+ * correct `surfaceError` call in the same hook. The authored
49
+ * sentence showed only when the value was NOT an Error, i.e. almost
50
+ * never, so the normal case published the raw message.
51
+ *
52
+ * It was dormant only because `loadingMessage` currently has no
53
+ * call sites; the first consumer to set one would have got two
54
+ * toasts, one of them raw. `updateToast` is also absent from that
55
+ * audit's SINKS list, so nothing would have caught it.
56
+ */
57
+ updateToast(loadingIdRef.current, "error", toUserMessage(err?.code, undefined, {
58
+ fallback: "Action failed",
59
+ }));
44
60
  }
45
61
  else if (!successMessage) {
46
62
  updateToast(loadingIdRef.current, "success", "Done");
package/dist/client.d.ts CHANGED
@@ -283,6 +283,8 @@ export { useLogout, useLogin, useGoogleLogin, useLinkGoogleAccount, useRegister,
283
283
  export type { LoginCredentials, RegisterData, ForgotPasswordData, ResetPasswordData, VerifyEmailData, ChangeEmailData } from "./features/auth/index";
284
284
  export { CartView, CartItemRow, CartGroupLineRow, CartSummary, CartPriceBreakdown, CartDrawer, CheckoutView, CheckoutSuccessView, CheckoutAddressStep, useGuestCart, useCartCount, useAddToCart, useCart, useGuestCartMerge, useCartQuery } from "./features/cart/index";
285
285
  export { StoreAddonsPicker, hasAnyStoreAddon } from "./features/cart/index";
286
+ export { PointsTenderPicker } from "./features/cart/index";
287
+ export type { PointsTenderPickerProps } from "./features/cart/index";
286
288
  export { clientLineTotal } from "./features/cart/utils/line-total";
287
289
  export type { PricedCartLine } from "./features/cart/utils/line-total";
288
290
  export type { CartPriceBreakdownData, CartPriceBreakdownStore, StoreAddonsValue, StoreAddonsRates } from "./features/cart/index";
@@ -389,6 +391,11 @@ export type { UserAccountHubViewProps, UserAccountHubViewLabels, UserOrdersViewP
389
391
  export { useOrders, useOrder, OrdersList } from "./features/orders/index";
390
392
  export { OrderStatusTimeline } from "./features/orders/components/OrderStatusTimeline";
391
393
  export type { OrderStatusTimelineProps } from "./features/orders/components/OrderStatusTimeline";
394
+ export { OrderProvenanceCard } from "./features/orders/components/OrderProvenanceCard";
395
+ export type { OrderProvenanceCardProps } from "./features/orders/components/OrderProvenanceCard";
396
+ export { RaiseDisputeForm } from "./features/orders/components/RaiseDisputeForm";
397
+ export type { RaiseDisputeFormProps } from "./features/orders/components/RaiseDisputeForm";
398
+ export type { OrderSourceContext } from "./features/orders/schemas/firestore";
392
399
  export { PROTECTION_CLAIM_REASON_LABEL } from "./features/protection-claims/schemas/firestore";
393
400
  export type { ProtectionClaimReason } from "./features/protection-claims/schemas/firestore";
394
401
  export { OrderCompletionPanel } from "./features/orders/components/OrderCompletionPanel";
@@ -455,7 +462,7 @@ export type { OwnerQuickActionsProps, OwnerQuickActionsResource } from "./featur
455
462
  export type { StoreListingEntitlements } from "./features/seller/hooks/useStoreListingEntitlements";
456
463
  export type { ListingTypePlugin } from "./_internal/shared/listing-types/_registry";
457
464
  export type { ListingType } from "./features/products/types/index";
458
- export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, IMAGE_ACCEPT_ATTR, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, PRODUCT_MAX_IMAGES, PRODUCT_MAX_VIDEOS, PRODUCT_IMAGE_INDEX_MAX, } from "./_internal/shared/media/limits";
465
+ export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, IMAGE_ACCEPT_ATTR, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, PRODUCT_MAX_IMAGES, REVIEW_MAX_IMAGES, PRODUCT_MAX_VIDEOS, PRODUCT_IMAGE_INDEX_MAX, } from "./_internal/shared/media/limits";
459
466
  export type { MediaKind, AllowedImageMime, AllowedVideoMime, AllowedDocMime, AllowedMime, } from "./_internal/shared/media/limits";
460
467
  export { ScamAwarenessModal } from "./features/scams/components/ScamAwarenessModal";
461
468
  export type { ScamAwarenessModalProps } from "./features/scams/components/ScamAwarenessModal";
@@ -586,6 +593,10 @@ export type { SellerSupportViewProps } from "./features/seller/components/Seller
586
593
  export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy";
587
594
  export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons";
588
595
  export type { ReturnReason } from "./_internal/shared/features/orders/return-reasons";
596
+ export { DISPUTE_KIND, DISPUTE_KIND_LABEL, DISPUTE_GATE, DISPUTE_TRANSIT_WINDOW_DAYS, DISPUTE_NOT_REACHED_GRACE_DAYS, isDisputeKind, checkDisputeGate, resolveDisputeEtd, disputeNotReachedFilableFrom, } from "./_internal/shared/features/orders/dispute-reasons";
597
+ export type { DisputeKind, DisputeGateOrder, DisputeGateResult, } from "./_internal/shared/features/orders/dispute-reasons";
598
+ export { INTEGRATIONS, INTEGRATION_ORDER, readIntegrationStates, integrationPatch, allIntegrationsPatch, } from "./_internal/shared/features/admin/integrations";
599
+ export type { IntegrationId, IntegrationDescriptor, IntegrationState, } from "./_internal/shared/features/admin/integrations";
589
600
  export { RefundRequestView } from "./features/orders/components/RefundRequestView";
590
601
  export type { RefundRequestViewProps, RefundRequestSubmission, } from "./features/orders/components/RefundRequestView";
591
602
  export { ORDER_RETURN_WINDOW_DAYS, ORDER_RETURN_WINDOW_MS, ORDER_CANCELLABLE_STATUSES, } from "./_internal/shared/features/orders/config";